Search code examples
javamaven

Maven Compilation Error without any errors from the compiler


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?


Solution

  • 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.