Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Maven Compilation Error without any errors from the compiler

Tags:

java

maven

I have a Java application built with Maven. Our CI system (Bamboo) is configured to use Maven 3.1.1, and I use Maven 3.5 locally. We're using Java 8u152 everywhere; I can also reproduce the problem using 8u144.

Today, after I committed a trivial change to the Java code, we started getting this error (paths and project names obfuscated):

[INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ project-name ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 35 source files to /bamboo/bamboo-home/xml-data/build-dir/ASP-CAS-CJT/project/service/target/test-classes
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 9.036s
[INFO] Finished at: Tue Feb 13 15:15:51 EST 2018
[INFO] Final Memory: 26M/715M
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.1:testCompile (default-testCompile) on project project-name: Compilation failure -> [Help 1]
[ERROR] 
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR] 
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoFailureException

Other similarly-built services build fine. This build passes when I run it locally. It also builds fine on the Bamboo host using Maven 3.5.0 manually from the command line. Invoking Maven with -e or -X gives no additional useful information; the stacktrace just indicates that there was a compilation failure.

Furthermore, the target/test-classes directory exists and contains all 35 expected .class files; it appears that compilation was every bit as successful as I expected it to be.

I've scoured the POM and parent POMs looking for hooks related to the test compile phase. I found nothing, and the output above indicates that there are none.

I'm at a loss as to what could be causing Maven to think there's a compiler error when there is none. Has anyone seen this before?

like image 649
JakeRobb Avatar asked Feb 13 '18 20:02

JakeRobb


2 Answers

Short version: javac was encountering a StackOverflowError (irony noted! 😄 ), caused by a 693-deep chained method call on a Builder.

To diagnose: we used Maven's -X output to extract the actual command to javac, then executed that separately. This gave us javac's full output, which does not appear to be available using Maven. The output told us which class it was working on and then spat out the stacktrace for the SOE. I then looked at the history of commits to that file and found that, coincident with the trivial change I committed, someone else had added a few calls to the builder chain.

To verify the diagnosis, we added -J-Xss256M to javac's args and ran it again; compilation succeeded. Rather than run the compiler with nonstandard args (and spending the time figuring out how to get Maven to invoke it that way), I then split the builder chain into two smaller chains. With that change committed, the build is now passing in Bamboo.

Note: in the question, I said that the compiler output contained all 35 expected class files; this was a coincidence. It contained 35 files, which matched up with the number of source files, but thanks to some inner classes, the 35 .java files should have generated 42 .class files.

We're using an old version of maven-compiler-plugin (v3.1, from 2013). I'm going to experiment with whether a newer version does a better job of exposing the failure.

like image 118
JakeRobb Avatar answered Oct 18 '22 23:10

JakeRobb


It seems the error of the creator had a different error cause. But since my issue let me here and I had a different cause: Check if you fork the compiler plugin somewhere:

E.g. like this:

<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.0</version> <configuration> <fork>true</fork> <meminitial>512m</meminitial> <maxmem>2048m</maxmem> <compilerArgs> <arg>-XX:MaxPermSize=256m</arg> </compilerArgs> <source>${java.version}</source> <target>${java.version}</target> </configuration> </plugin>

In this case the outcome can be ugly. It works on some machines where JAVA_HOME is set generally correct and will not where you just set it in a local window. And the error is not helpful at all as the forked compiler will not return helpful info.

like image 35
Martin Avatar answered Oct 19 '22 01:10

Martin