Reputation: 21
I have an Aggregator POM whose Parent POM is also one of its child Modules. When I run a multi-thread Maven build with normal goals (e.g mvn clean install -T 2
) it works as expected: The Parent module builds first followed by the Aggregator.
However when running mvn sonar:sonar -T 2
the build hangs indefinitely (from org.sonarsource.scanner.maven:sonar-maven-plugin:3.4.0.905
).
Layout:
sample/
- parent/
- pom.xml
- pom.xml
Aggregator POM (sample/pom.xml):
<?xml version="1.0"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.sample</groupId>
<artifactId>parent</artifactId>
<version>1.0.0-SNAPSHOT</version>
<relativePath>parent/pom.xml</relativePath>
</parent>
<artifactId>aggregator</artifactId>
<packaging>pom</packaging>
<modules>
<module>parent</module>
</modules>
</project>
Parent POM (sample/parent/pom.xml):
<?xml version="1.0"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.sample</groupId>
<artifactId>parent</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>pom</packaging>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.sonarsource.scanner.maven</groupId>
<artifactId>sonar-maven-plugin</artifactId>
<version>3.4.0.905</version>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
A normal multi-threaded build works as expected: mvn clean install -T 2
DANIJOH2-M-C5DB:deadlock-sample danijoh2$ mvn clean install -T 2
[INFO] Scanning for projects...
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Build Order:
[INFO]
[INFO] parent [pom]
[INFO] aggregator [pom]
[INFO]
[INFO] Using the MultiThreadedBuilder implementation with a thread count of 2
[INFO]
[INFO] -------------------------< com.sample:parent >--------------------------
[INFO] Building parent 1.0.0-SNAPSHOT [1/2]
[INFO] --------------------------------[ pom ]---------------------------------
[INFO]
[INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ parent ---
[INFO] Deleting /Users/danijoh2/Desktop/deadlock-sample/parent/target
[INFO]
[INFO] --- maven-install-plugin:2.4:install (default-install) @ parent ---
[INFO] Installing /Users/danijoh2/Desktop/deadlock-sample/parent/pom.xml to /Users/danijoh2/.m2/repository/com/sample/parent/1.0.0-SNAPSHOT/parent-1.0.0-SNAPSHOT.pom
[INFO]
[INFO] -----------------------< com.sample:aggregator >------------------------
[INFO] Building aggregator 1.0.0-SNAPSHOT [2/2]
[INFO] --------------------------------[ pom ]---------------------------------
[INFO]
[INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ aggregator ---
[INFO]
[INFO] --- maven-install-plugin:2.4:install (default-install) @ aggregator ---
[INFO] Installing /Users/danijoh2/Desktop/deadlock-sample/pom.xml to /Users/danijoh2/.m2/repository/com/sample/aggregator/1.0.0-SNAPSHOT/aggregator-1.0.0-SNAPSHOT.pom
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary:
[INFO]
[INFO] parent ............................................. SUCCESS [ 0.805 s]
[INFO] aggregator 1.0.0-SNAPSHOT .......................... SUCCESS [ 0.024 s]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1.984 s (Wall Clock)
[INFO] Finished at: 2018-04-17T08:15:31-07:00
[INFO] ------------------------------------------------------------------------
But when running sonar goal, it hangs indefinitely: mvn sonar:sonar -T 2
(This can also be reproduced with mvn clean install sonar:sonar -T 2
, in which case it hangs immediately after building and installing both projects)
DANIJOH2-M-C5DB:deadlock-sample danijoh2$ mvn sonar:sonar -T 2
[INFO] Scanning for projects...
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Build Order:
[INFO]
[INFO] parent [pom]
[INFO] aggregator [pom]
[INFO]
[INFO] Using the MultiThreadedBuilder implementation with a thread count of 2
<process is now hung>
Running the same build with a single thread works fine: mvn sonar:sonar
DANIJOH2-M-C5DB:deadlock-sample danijoh2$ mvn sonar:sonar
[INFO] Scanning for projects...
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Build Order:
[INFO]
[INFO] parent [pom]
[INFO] aggregator [pom]
[INFO]
[INFO] -----------------------< com.sample:aggregator >------------------------
[INFO] Building aggregator 1.0.0-SNAPSHOT [1/2]
[INFO] --------------------------------[ pom ]---------------------------------
[INFO]
[INFO] --- sonar-maven-plugin:3.4.0.905:sonar (default-cli) @ aggregator ---
...
[INFO] ANALYSIS SUCCESSFUL, you can browse http://localhost:9000/dashboard/index/com.sample:aggregator
[INFO] Note that you will be able to access the updated dashboard once the server has processed the submitted analysis report
[INFO] More about the report processing at http://localhost:9000/api/ce/task?id=AWLUPrWVbruNGPzM1Q9P
[INFO] Task total time: 11.792 s
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary:
[INFO]
[INFO] parent ............................................. SKIPPED
[INFO] aggregator 1.0.0-SNAPSHOT .......................... SUCCESS [ 16.700 s]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 18.462 s
[INFO] Finished at: 2018-04-17T08:35:01-07:00
[INFO] ------------------------------------------------------------------------
2018-04-17 08:25:33
Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.152-b16 mixed mode):
"Attach Listener" #11 daemon prio=9 os_prio=31 tid=0x00007fcf4d22e800 nid=0x2807 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"Service Thread" #8 daemon prio=9 os_prio=31 tid=0x00007fcf4982c000 nid=0x3703 runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"C1 CompilerThread2" #7 daemon prio=9 os_prio=31 tid=0x00007fcf4b03a800 nid=0x4503 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"C2 CompilerThread1" #6 daemon prio=9 os_prio=31 tid=0x00007fcf4b039800 nid=0x3403 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"C2 CompilerThread0" #5 daemon prio=9 os_prio=31 tid=0x00007fcf49832000 nid=0x4703 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"Signal Dispatcher" #4 daemon prio=9 os_prio=31 tid=0x00007fcf49817000 nid=0x3207 runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"Finalizer" #3 daemon prio=8 os_prio=31 tid=0x00007fcf4a809800 nid=0x5003 in Object.wait() [0x0000700004411000] java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x0000000782098a08> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:143)
- locked <0x0000000782098a08> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:164)
at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:209)
"Reference Handler" #2 daemon prio=10 os_prio=31 tid=0x00007fcf4a807000 nid=0x2d03 in Object.wait() [0x000070000430e000] java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x0000000782098bc0> (a java.lang.ref.Reference$Lock)
at java.lang.Object.wait(Object.java:502)
at java.lang.ref.Reference.tryHandlePending(Reference.java:191)
- locked <0x0000000782098bc0> (a java.lang.ref.Reference$Lock)
at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:153)
"main" #1 prio=5 os_prio=31 tid=0x00007fcf4a006000 nid=0x1a03 waiting on condition [0x0000700003cfb000] java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x0000000781595778> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
at java.util.concurrent.ExecutorCompletionService.take(ExecutorCompletionService.java:193)
at org.apache.maven.lifecycle.internal.builder.multithreaded.MultiThreadedBuilder.multiThreadedProjectTaskSegmentBuild(MultiThreadedBuilder.java:140)
at org.apache.maven.lifecycle.internal.builder.multithreaded.MultiThreadedBuilder.build(MultiThreadedBuilder.java:101)
at org.apache.maven.lifecycle.internal.LifecycleStarter.execute(LifecycleStarter.java:128)
at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:305)
at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:192)
at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:105)
at org.apache.maven.cli.MavenCli.execute(MavenCli.java:956)
at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:290)
at org.apache.maven.cli.MavenCli.main(MavenCli.java:194)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:289)
at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:229)
at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:415)
at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:356)
"VM Thread" os_prio=31 tid=0x00007fcf4b01c000 nid=0x5203 runnable
"GC task thread#0 (ParallelGC)" os_prio=31 tid=0x00007fcf4a00f000 nid=0x2007 runnable
"GC task thread#1 (ParallelGC)" os_prio=31 tid=0x00007fcf49800800 nid=0x1f03 runnable
"GC task thread#2 (ParallelGC)" os_prio=31 tid=0x00007fcf4a010000 nid=0x2a03 runnable
"GC task thread#3 (ParallelGC)" os_prio=31 tid=0x00007fcf4a010800 nid=0x5303 runnable
"VM Periodic Task Thread" os_prio=31 tid=0x00007fcf49810800 nid=0x4303 waiting on condition
JNI global references: 229
DANIJOH2-M-C5DB:deadlock-sample danijoh2$ mvn --version
Apache Maven 3.5.3 (3383c37e1f9e9b3bc3df5050c29c8aff9f295297; 2018-02-24T11:49:05-08:00)
Maven home: /Users/danijoh2/Work/maven-3.5.3
Java version: 1.8.0_152, vendor: Oracle Corporation
Java home: /Library/Java/JavaVirtualMachines/jdk1.8.0_152.jdk/Contents/Home/jre
Default locale: en_US, platform encoding: UTF-8
OS name: "mac os x", version: "10.13.4", arch: "x86_64", family: "mac"
I saw the same behavior with Maven 3.0.5, 3.2.3, 3.3.9 as well. I also tried with sonar-maven-plugin 3.0 and 3.3.0.603 with the same results.
In our project, with ~100 modules, running multithreaded cuts our build time from ~30 minutes to <10 minutes. If I make the aggregator itself the parent (and get rid of the parent module entirely) then it works fine. The problem with that approach is that we are also creating aggregated site reports for our project, when then will not work as expected since the aggregator POM will build before its modules. I see two other alternatives:
sonar:sonar
as a dedicated step after running clean install -T 2
on the project. I will go with the first approach for now, but would like to see the sonar:sonar
goal to be able to handle this scenario in the future.
Upvotes: 1
Views: 1260
Reputation: 2936
I don't see any evidence of the sonar plugin hanging. From the stack trace it looks like maven hangs. Am I missing something?
The multi-thread support in maven is broken when multiple tasks are given. See this P/R and the related ticket, and other bug tickets regarding multithreading: https://github.com/apache/maven/pull/125
To be honest, I don't expect it to be fixed anytime soon, if ever. Consider moving to Gradle.
Upvotes: 1