Skip to content

JavacCompiler forked compilation fails with no messages and no other output #66

Open
@jakerobb

Description

@jakerobb

I had a Java class using a builder pattern to put together a lookup table. There was another class which chained together 600+ method calls on a single line on this builder, assembling the table. Understandably, as the number of entries in the lookup table grew, we eventually ran into a StackOverflowError from javac while compiling the class. javac does not handle this gracefully; the SOE stacktrace is written to stderr with no surrounding context clues, and then the compiler exits.

The project is built using Maven, which of course uses plexus-compiler-javac. We run the build in forked mode.

Unfortunately, the Plexus compiler recognizes the forked build as failed, but does not capture the cause. There are no messages on the CompilerResult, and nothing is printed to stdout/stderr. It was therefore quite difficult for me to diagnose the cause of the compilation failure. By enabling verbose mode, I was able to see the compiler's progress, and through process of elimination I identified the problematic class. One look at the class led me to suspect an SOE, which I was able to verify by compiling the class manually at the command line. From there, it was a simple matter of splitting up the line of code into multiple lines.

I have created an MVCE here: https://github.com/jakerobb/plexus-javac-compiler-bug. It's a small Maven project. Just clone it and run mvn test to reproduce the issue.

I think that #39 would have been helpful here, but I also think that some other improvements are called for:

  1. If compilation fails and there are no messages, add a custom message indicating that there is a likely compiler issue, and then proxy the entire output through, regardless of whether any "debug flag" is set.
  2. Capture and recognize exception stacktraces on javac's stderr. Treat them similarly to number 1 above, but with a different message.
  3. If possible, include the name of the problematic file in the output. I know javac isn't returning this, but it seems like it might be possible to determine; I don't want to assume.

Of course, ideally, javac should be fixed to not throw an SOE in this scenario, probably by replacing recursion with iteration, and also to write out the file it was working on when compilation fails. I'm now off to figure out how to report an improvement request in javac....

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions