-
Notifications
You must be signed in to change notification settings - Fork 61
Make Eclipse and AspectJ compilers run on JDK 11 again #358
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
Conversation
AspectJ can compile many projects on JDK 11, because it is not always using Java 17 classes from JDT Core. If it does not work, there will be a runtime error, and the user can figure out what is wrong. For ECJ, the case is more complicated, because it directly imports Java 17 classes from JDT Core. There were isolated in new class EclipseJavaCompilerDelegate, which is accessed using Class::forName and method handles from EclipseJavaCompiler. I.e., Sisu Inject can scan the annotations on EclipseJavaCompiler on JDK 11, and there is no more confusing "No such compiler 'eclipse'" error, but rather: Error injecting constructor, ... EcjFailureException: Failed to run the ecj compiler: ECJ only works on Java 17+ at org.codehaus.plexus.compiler.eclipse.EclipseJavaCompiler.<init> This explicitly tells the user what is wrong. A multi-release JAR solution was tested and worked well in Maven, but was dismissed due to the terrible developer experience in IDEs. Fixes codehaus-plexus#347.
Actually, it would be nice to run most of the unit and integration tests on JDK 11 again, too, but we would need toolchains for that, which is out of scope for this PR. The advantage would be, that we could add tests for the new error message on JDK 11 when trying to use ECJ. For a unit test, we might be able to mock the JVM's java version, but I do not want to introduce Mockito or so just for this PR. That should be something the commiters ought to decide. But I manually tested with some ECJ and AsectJ Maven projects and also manually ran some of the ITs directly from |
I don't think this is something to consider here as there is literally not much to "develop" her and this Method Handle stuff is terrible as well ( sorry :-D ) I even wonder why we need MH at all and can't use reflection? Thinking even more, I wonder if not maven could even be made to check the minimal maven version like it does for plugins already? |
@laeubi, method handles are more efficient and type-safe than reflection. If you think, that is terrible, you should try my other local branch with the multi-release JAR not from Maven, but from your IDE, not finding the right source directory per JDK. That is even more horrible. And it definitely is to consider, because it does not compile the right thing and hence not yield the right test results in the IDE. |
Please note my second commit:
Now, the corresponding Maven build error is much shorter:
|
This shifts the focus from a supposed Maven component wiring error to the root cause, expressed in the error message: Fatal error compiling: ECJ needs JRE 17+ We need to add safeguards throwing the exception in both methods accessing class EclipseJavaCompilerDelegate, because we cannot predict who calls which one first. Omitting one safeguard might lead to the return of the infamous "No such compiler 'eclipse'" error. The new static boolean field EclipseJavaCompiler.isJdkSupported also enables us to write a simple unit test, asserting on the error message, if the field value is false. Relates to codehaus-plexus#347.
Please see #359 as well |
Superseded by #361. |
AspectJ can compile many projects on JDK 11, because it is not always using Java 17 classes from JDT Core. If it does not work, there will be a runtime error, and the user can figure out what is wrong.
For ECJ, the case is more complicated, because it directly imports Java 17 classes from JDT Core. There were isolated in new class
EclipseJavaCompilerDelegate
, which is accessed usingClass::forName
and method handles fromEclipseJavaCompiler
.I.e., Sisu Inject can scan the annotations on
EclipseJavaCompiler
on JDK 11, and there is no more confusing "No such compiler 'eclipse'" error, but rather:This explicitly tells the user what is wrong.
A multi-release JAR solution was tested and worked well in Maven, but was dismissed due to the terrible developer experience in IDEs.
Fixes #347.
Update: The error message for ECJ on JDK 11 in more detail:
An alternative to the injection exception would be to actually add guards to the method handle calls and throw exceptions there, i.e. not during wiring the plugin dependencies but when actually executing it. If the code reviewers would prefer that, I could certainly change it upon request.