While migrating from Oracle JDK 8 to Open JDK 11.0.1 using Eclipse 2018-12 I obviously found another JPMS-related bug making it hard to work with external non-modularized .jar's within a modular java project. I tracked my problem down to the full example below.
The example was derived from the migration process of a real project (using the still non-modularized javax.servlet.api ) which caused some headaches. It consists of four maven projects M, N, Y and X making up one java module each, and another maven project that makes up a non-modular java project W . I use maven and the maven-compiler-plugin 3.8.0 . My observations are:
Obviously, re-declaring automated modules like module w in top-level projects seems to cause problems with the built-in Eclipse compiler and does not allow us to work properly with Eclipse (whereas running the project works well). In my opinion, this mismatch is another bug in Eclipse 2018-12 (along with the problems I described in Automatic modules not found in Eclipse 2018-12 when project is opened and Java module not found at runtime even with requires transitive ).
My question is: Can someone confirm this as a bug, or is it already known? For us it is a complete show stopper since our project depends on different libraries that are neither modular nor have they the Automatic-Module-Name attribute. And as long the Eclipse bug described in this post exist we are not be able to migrate further to JDK 11.
Sidemark : We don't want to configure our projects after checking out from SCM to get it running in Eclipse. For us, it was not necessary until now ( and that's actually really great when working with Maven and Eclipse, thanks to everyone who made that possible so far! ), and I hardly try to avoid to manually configure module paths of our eclipse projects or run configurations.
So, here is the complete and reproducable example:
Project M (modular)
// M.java
package m;
import com.example.n.N;
public class M {
public static void main(String[] args) {
System.out.println("M");
N.main(null);
}
}
// module-info.java
open module m {
requires n;
requires w;
}
// pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.mavenexample2</groupId>
<artifactId>m</artifactId>
<version>0.0.1-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>com.mavenexample2</groupId>
<artifactId>n</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.mavenexample2</groupId>
<artifactId>y</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
Project N (modular)
// N.java
package com.example.n;
public class N {
public static void main(String[] args) {
System.out.println("N");
}
}
// module-info.java
open module n {
exports com.example.n;
}
// pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.mavenexample2</groupId>
<artifactId>n</artifactId>
<version>0.0.1-SNAPSHOT</version>
</project>
Project Y (modular)
// Y.java
package com.example.y;
public class Y {
public static void main(String[] args) {
System.out.println("Y");
}
}
// module-info.java
open module com.example.y {
exports com.example.y;
requires com.example.x;
}
// pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.mavenexample2</groupId>
<artifactId>y</artifactId>
<version>0.0.1-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>com.mavenexample2</groupId>
<artifactId>x</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
Project X (modular)
// X.java
package com.example.x;
public class X {
public static void main(String[] args) {
System.out.println("X");
}
}
// module-info.java
open module com.example.x {
exports com.example.x;
requires w;
}
// pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.mavenexample2</groupId>
<artifactId>x</artifactId>
<version>0.0.1-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>com.mavenexample2</groupId>
<artifactId>w</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
Project W (non-modular)
// W.java
package external;
public class W {
public static void main(String[] args) {
System.out.println("W");
}
}
// pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.mavenexample2</groupId>
<artifactId>w</artifactId>
<version>0.0.1-SNAPSHOT</version>
</project>
Please do a Maven > Update Projects … > all to get everything in sync after defining the projects or changing your module dependencies. Also, please close also the non-modular project M after doing a mvn clean install since otherwise you would get the error described here: Automatic modules not found in Eclipse 2018-12 when project is opened .
Indeed Eclipse had a bug, which surfaced only when compilation was performed in a very specific order.
Background: In the era of JPMS a package has different content depending on which module is asking. In the example different modules see different configurations for package
com.example
: from some pov it contains a child packagen
in other perspectives it doesn't. For performance sake, each result of such lookup is cached, which caused the order dependence: which module first looked up packagecom.example
decided what contributions to the package were known.Curiously, the same JPMS that makes split packages illegal, requires a compiler to treat each parent package with multiple contributing modules as a split package, causing a significant increase in implementation complexity.
(Edited:) The bug has been addressed as Eclipse bug 543765 , the fix is available since release 2019-03.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.