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

Merge sources from multiple compiler executions #393

Open
Marcono1234 opened this issue Nov 8, 2021 · 0 comments
Open

Merge sources from multiple compiler executions #393

Marcono1234 opened this issue Nov 8, 2021 · 0 comments
Labels

Comments

@Marcono1234
Copy link

Marcono1234 commented Nov 8, 2021

Context

Maven projects which want to compile against Java < 9, but also want to prodive a JPMS module descriptor might choose to realize this using separate Maven Compiler Plugin executions, one compiling the main source code and another one only compiling the module-info.java file.

A setup for this is described in the documentation for the Apache Maven Compiler Plugin, but that implementation is in my opinion flawed (will submit a Maven issue for this once their bug tracker is available again). It compiles all the code, including module-info.java, against Java 9 and then compiles everything except module-info.java against a lower Java version, hoping that this replaces all class files except module-info.class. The issues here are:

  • It relies on Java 9 creating the same class files as the lower version; however if Java 9 created additional synthetic classes or chose different synthetic class names (e.g. for anonymous classes), then those would remain in the created JAR.
  • The created JAR contains directly in the root directory the module-info.class. This causes issues for some build tools (mostly for Android?) which cannot handle the file (see related issue in Gson).

For these reasons the compilation for module-info.java should run with:

<release>9</release>
<includes>
  <include>module-info.java</include>
</includes>
<multiReleaseOutput>true</multiReleaseOutput>

(Additionally the JAR plugin needs to be configured to set Mutli-Release: true in the manifest.)
This only compiles the module-info.java and places it under META-INF/versions/9, where most build tools don't process classes (for Android, plugins have been updated to ignore these directories).

Issue

The issue with m2e and the recently integrated #253 is that the improved setup described above would cause m2e to detect Java 9 as highest release, and then only consider its sources; that means the whole project would only have the module-info.java file as source, and all the other source files compiled with an older version would be missing.

Potential solution

Would it make sense to remove the version requirement introduced by #253, and instead of overwriting the list of previously detected source files here, merge them instead?

Normally compiling with a newer Java version should not be a problem, and it only affects the IDE anyways. When you build with Maven from the command line it will choose the correct Java versions.
In my opinion having all files as source files available in the IDE weighs higher than compiling in the IDE with the exact Java version specified in the POM.

What do you think?

Open questions:

  • When users have specified multiple executions to compile version specific classes to Multi Release folders (e.g. one verison of MyClass for Java 8 and one for Java 9), then the question is how Eclipse handles this case when both classes exist on the source path, with the same package name.

Workaround

For this specific use case of adding a module descriptor to a Java < 9 project, ModiTect seems to be well suited. It can compile an existing module-info.java file, place it in the version specific META-INF/versions folder of the JAR and set the Mutli-Release: true attribute in the manifest.
This way you don't need two separate maven-compiler-plugin executions anymore and therefore no issues for m2e arise.

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

No branches or pull requests

2 participants