Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
jakerobb opened this issue Oct 8, 2019 · 2 comments

Comments

@jakerobb
Copy link

jakerobb commented Oct 8, 2019

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

@urld
Copy link

urld commented Dec 15, 2021

I encountered a similar problem where valuable information from stderr is ignored:

  bad class file: <censored>
    class file has wrong version 55.0, should be 52.0
    Please remove or make sure it appears in the correct subdirectory of the classpath.

So its not just about potential stackoverflow bugs in javac. There are also error cases where erroneous input data can cause javac to detect actual errors that should be recognized be the plexus-compiler.

@Marcono1234
Copy link

Marcono1234 commented Mar 5, 2023

  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.

Would also be great if in addition to that there was a opt-in setting (which would then also be propagated to the Maven Compiler Plugin) which always prints the complete process output on error, regardless of whether some diagnostics were found in the output or not. That would help in case plexus-compiler only detected some but not all diagnostics in the output.
I would be much happier about overly verbose output on error than compiler output being omitted because it was erroneously deemed unimportant.

For example for the following warnings about missing annotation classes (JDK-6365854), plexus-compiler did not detect any warnings or errors:

C:\Users\#redacted#\Downloads\gson\gson\target\gson-2.10.2-SNAPSHOT.jar(/com/google/gson/JsonParser.class): warning: Cannot find annotation method 'replacement()' in type 'InlineMe': class file for com.google.errorprone.annotations.InlineMe not found
C:\Users\#redacted#\Downloads\gson\gson\target\gson-2.10.2-SNAPSHOT.jar(/com/google/gson/JsonParser.class): warning: Cannot find annotation method 'imports()' in type 'InlineMe'
C:\Users\#redacted#\Downloads\gson\gson\target\gson-2.10.2-SNAPSHOT.jar(/com/google/gson/JsonParser.class): warning: Cannot find annotation method 'replacement()' in type 'InlineMe'
C:\Users\#redacted#\Downloads\gson\gson\target\gson-2.10.2-SNAPSHOT.jar(/com/google/gson/JsonParser.class): warning: Cannot find annotation method 'imports()' in type 'InlineMe'
C:\Users\#redacted#\Downloads\gson\gson\target\gson-2.10.2-SNAPSHOT.jar(/com/google/gson/JsonParser.class): warning: Cannot find annotation method 'replacement()' in type 'InlineMe'
C:\Users\#redacted#\Downloads\gson\gson\target\gson-2.10.2-SNAPSHOT.jar(/com/google/gson/JsonParser.class): warning: Cannot find annotation method 'imports()' in type 'InlineMe'
error: warnings found and -Werror specified
1 error
6 warnings

Or maybe org.codehaus.plexus.compiler.javac.JavacCompiler#parseModernStream should be changed to not silently ignore unrecognized lines and instead report them as diagnostic of Kind.OTHER? Would affect the following

Or is there output which should be ignored from the compiler?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants