eclipse-m2e / m2e-core

Eclipse Public License 2.0
110 stars 109 forks source link

Dependency calculation issue when Eclipse runtime different from build environment #388

Open m4ttschw4rz opened 2 years ago

m4ttschw4rz commented 2 years ago

I have a project that needs Java8 and Apache CXF. With the latest Eclipse running with at least Java11 I get some issues with the dependencies calculated by m2e.

The cxf-parent.pom defines a set of additional dependencies for jdk9 and up by using a profile the gets activated when jdk9+ is being used. When I open up my project with the latest eclipse, maven/m2e seems to use the eclipse runtime vm to calculate the dependencies. In result I end up with a lot more dependencies than necessary, or, even worse, with multiple implementations for the same package (eg. jaxb) during runtime with jdk8.

Is there a way to force m2e to use the project's build environment (here JDK8) to calculate the dependencies? I already tried to configure compiler and toolchain parameters but to no avail. This only seems to affect compilation but not dependency calculation.

Thanks in advance, Michael

mickaelistria commented 2 years ago

Do you think you can provide a very minimal project to reproduce this issue? And maybe even write a test case for it?

generatorr commented 2 years ago

I ran into the very same problem this week, and want to share a very minimal project to reproduce the issue. There are actually two bugs:

This happens when there is a dependency to the Java version within the pom.xmls of libraries which are included in the project. I am using the dependency to jaxws-rt 2.10.0 as an example.

Part 1 - the maven bug

To reproduce the issue please extract the attached m2e_bug388_demo.zip m2e_bug388_demo.zip It consists only of a pom.xml, with packaging ear and one dependency to jaxws-rt 2.2.0. No sources, just the pom.

Build it with JDK 1.8:

$ JAVA_HOME_1_8=/Library/Java/JavaVirtualMachines/jdk1.8.0_202.jdk/Contents/Home
$ JAVA_HOME=$JAVA_HOME_1_8;mvn clean package
[...]
[INFO] BUILD SUCCESS
$ find target
target
target/application.xml
target/maven-archiver
target/maven-archiver/pom.properties
target/m2e_bug388-0.0.1-SNAPSHOT
target/m2e_bug388-0.0.1-SNAPSHOT/jaxws-api-2.2.11.jar
target/m2e_bug388-0.0.1-SNAPSHOT/FastInfoset-1.2.13.jar
target/m2e_bug388-0.0.1-SNAPSHOT/jaxb-api-2.2.12-b140109.1041.jar
target/m2e_bug388-0.0.1-SNAPSHOT/jaxb-core-2.2.10-b140802.1033.jar
target/m2e_bug388-0.0.1-SNAPSHOT/policy-2.4.jar
target/m2e_bug388-0.0.1-SNAPSHOT/javax.annotation-api-1.2.jar
target/m2e_bug388-0.0.1-SNAPSHOT/META-INF
target/m2e_bug388-0.0.1-SNAPSHOT/META-INF/application.xml
target/m2e_bug388-0.0.1-SNAPSHOT/jaxb-impl-2.2.10-b140802.1033.jar
target/m2e_bug388-0.0.1-SNAPSHOT/resolver-20050927.jar
target/m2e_bug388-0.0.1-SNAPSHOT/mimepull-1.9.4.jar
target/m2e_bug388-0.0.1-SNAPSHOT/management-api-3.0.0-b012.jar
target/m2e_bug388-0.0.1-SNAPSHOT/stax2-api-3.1.1.jar
target/m2e_bug388-0.0.1-SNAPSHOT/ha-api-3.1.9.jar
target/m2e_bug388-0.0.1-SNAPSHOT/jsr181-api-1.0-MR1.jar
target/m2e_bug388-0.0.1-SNAPSHOT/streambuffer-1.5.3.jar
target/m2e_bug388-0.0.1-SNAPSHOT/javax.xml.soap-api-1.3.7.jar
target/m2e_bug388-0.0.1-SNAPSHOT/woodstox-core-asl-4.2.0.jar
target/m2e_bug388-0.0.1-SNAPSHOT/saaj-impl-1.3.25.jar
target/m2e_bug388-0.0.1-SNAPSHOT/stax-ex-1.7.7.jar
target/m2e_bug388-0.0.1-SNAPSHOT/gmbal-api-only-3.1.0-b001.jar
target/m2e_bug388-0.0.1-SNAPSHOT.ear

now, that looks good. All dependencies are there

Build it with JDK 15:

$ JAVA_HOME_15=/Library/Java/JavaVirtualMachines/jdk-15.0.1.jdk/Contents/Home
$ JAVA_HOME=$JAVA_HOME_15;mvn clean package
[...]
[WARNING] The POM for com.sun.xml.ws:jaxws-rt:pom:2.2.10 is invalid, transitive dependencies (if any) will not be available, enable debug logging for more details
[...]
[INFO] BUILD SUCCESS
$ find target
target
target/application.xml
target/maven-archiver
target/maven-archiver/pom.properties
target/m2e_bug388-0.0.1-SNAPSHOT
target/m2e_bug388-0.0.1-SNAPSHOT/META-INF
target/m2e_bug388-0.0.1-SNAPSHOT/META-INF/application.xml
target/m2e_bug388-0.0.1-SNAPSHOT.ear

That result is a bit short; there is a warning message but the target directory is incomplete, the transitive dependencies are missing. The Maven bug is: Although the build result is incomplete and wrong, Maven does not recognize and report this situation as an error.

Let's find out the root cause of the warning message: Step 1: Do what maven tells us and enable debug log:

JAVA_HOME=$JAVA_HOME_15;mvn clean package -X
[...]
[WARNING] The POM for com.sun.xml.ws:jaxws-rt:pom:2.2.10 is invalid, transitive dependencies (if any) will not be available: 1 problem was encountered while building the effective model for com.sun.xml.ws:jaxws-rt:2.2.10
[ERROR] 'dependencyManagement.dependencies.dependency.systemPath' for com.sun:tools:jar must specify an absolute path but is ${tools.jar} @ 
[...]
[INFO] BUILD SUCCESS

When switching on the DEBUG log, maven reports an ERROR pointing to some problem with "tools.jar". But still the result is "BUILD SUCCESS".

Step 2: finding the issue in the pom.xml Let's look in the pom of jaxws-rt. A "tools.jar" is not mentioned there. It is actually in the parent pom of the parent pom of the parent pom: there in line 888 (com.sun.xml.ws:project:2.2.10) we find: <systemPath>${tools.jar}</systemPath> The file tools.jar vanished from JDK distributions starting with JDK 1.9. Therefore there is a hard dependency in jaxws-rt.pom so that it cannot be built with JDK versions newer than 1.8.

Using a newer JDK to build that project results in a broken release without Maven reporting an error.

At least the following poms have that dependency to the jdk version: jaxws-rt 2.10.0 and Apache CXF (see the error report of the original poster)

Part 2 - the m2e bug

Now it is proven we must define the JDK version for computing the dependencies of a maven project. m2e does not support choosing the JDK version to compute the dependencies; instead, in the "settings/installations" dialog of m2e:

In addition, starting with eclipse release 2020-09, eclipse requires at least JDK 11 to run, therefore it is not possible to use a JDK 8 to compute the dependencies within eclipse.

How it should be:

And, to mitigate the maven bug described above

Part 3 - workaround for the jaxws-rt build bug By adding the following line into eclipse.ini -Dtools.jar=/Library/Java/JavaVirtualMachines/jdk1.8.0_202.jdk/Contents/Home/lib/tools.jar This makes my build work, as the "tools.jar" variable can be resolved. It is definitely an ugly hack but resolves that particular problem with jaxws-rt for now.

generatorr commented 2 years ago

improved the demo project - now includes a Junit test case m2e_bug388_demo2.zip

runs with JDK 1.8 on the command line:

$ JAVA_HOME=$JAVA_HOME_1_8;mvn clean package
[...]
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
[...]
[INFO] BUILD SUCCESS

fails with JDK 15 on the command line:

$ JAVA_HOME=$JAVA_HOME_15;mvn clean package
[...]
Failed tests:   testLoadClassFromDepenceny(M2eBug388Test): class could not be loaded: com.sun.xml.stream.buffer.MutableXMLStreamBuffer
Tests run: 1, Failures: 1, Errors: 0, Skipped: 0
[...]
[INFO] BUILD FAILURE
[...]

fails within eclipse (where jdk 1.8 is configured for the project) Bildschirmfoto 2021-11-07 um 17 36 46

mickaelistria commented 2 years ago

The issue is that the project is incompatible with newer Java versions, because it relies on tools.jar being present. That is not really a Maven nor an m2e issue. Contributions to improve that would be welcome but beware that "the m2e settings/installations dialog should allow the user to choose the maven installation to be used, also for dependency resolution" is almost impossible to implement because the Maven runtime must be part of the same VM as the IDE for many of m2e features to work. However "m2e should consider the maven warning message 'The POM for ...is invalid, transitive dependencies (if any) will not be available' as a severe build problem and report it as such" seems very interesting and relatively easy to implement, if the warning is properly reported by ProjectBuilder.

generatorr commented 2 years ago

The issue is that the project is incompatible with newer Java versions, because it relies on tools.jar being present. That is not really a Maven nor an m2e issue.

Yes, true; it is a problem within the pom.xmls and needs to be addressed there (and probably is in newer versions of the pom). But it is definitely a maven bug recognizing an issue that results in an incomplete build result, and nevertheless saying "BUILD SUCCESS".

Contributions to improve that would be welcome but beware that "the m2e settings/installations dialog should allow the user to choose the maven installation to be used, also for dependency resolution" is almost impossible to implement because the Maven runtime must be part of the same VM as the IDE for many of m2e features to work.

Ok, so you are saying: I cannot use a current version of Eclipse/m2e to build my project? We are bound to jdk1.8, and we are using that version of jaxws-rt. It builds without issues on the command line or in jenkins, but not locally within eclipse.

However "m2e should consider the maven warning message 'The POM for ...is invalid, transitive dependencies (if any) will not be available' as a severe build problem and report it as such" seems very interesting and relatively easy to implement, if the warning is properly reported by ProjectBuilder.

That would be a good step forward