使用 Eclipse 2018-12 从 Oracle JDK 8 迁移到 Open JDK 11.0.1 时,我显然发现了另一个与JPMS相关的错误很难在模块化Java项目中使用外部未模块化的 .jar's 。我将问题追溯到下面的完整示例。
该示例来自真实项目的迁移过程(使用仍未模块化的 javax.servlet.api ),这引起了一些麻烦。它由四个分别构成一个Java模块的Maven项目 M,N,Y和X 和另一个构成一个非模块化Java项目 W 的maven项目组成。我使用了maven和 maven-compiler-plugin 3.8.0 。我的观察是:
很明显,在顶级项目中重新声明了诸如模块 w 之类的自动化模块似乎会导致内置Eclipse编译器出现问题,并且不允许我们工作在Eclipse上正确运行(而运行项目效果很好)。我认为,这种不匹配是Eclipse 2018-12中的另一个错误(以及我在Automatic modules not found in Eclipse 2018-12 when project is opened和Java module not found at runtime even with requires transitive中描述的问题)。
我的问题是:有人可以确认这是一个错误,还是已经知道?对我们来说,这是一个完整的展示机会,因为我们的项目依赖于既不是模块化也不是 Automatic-Module-Name 属性的不同库。只要存在本文中描述的Eclipse错误,我们就无法进一步迁移到JDK 11。
Sidemark :我们不希望在从SCM签出以使其在Eclipse中运行之后配置项目。对我们来说,直到现在都没有必要(,实际上,与Maven和Eclipse一起使用时,这真的很棒,这要归功于到目前为止所有使这一切成为可能的人!),而且我几乎不尝试避免手动配置eclipse项目或运行配置的模块路径。
因此,这是完整且可复制的示例:
项目M (模块化)
// 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>
项目N (模块化)
// 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>
项目Y (模块化)
// 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>
项目X (模块化)
// 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 (非模块化)
// 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>
请执行 Maven>更新项目…> ,以在定义项目或更改模块依存关系后使所有内容保持同步。另外,在执行 mvn全新安装之后,也请关闭非模块化项目 M ,因为否则您将得到此处描述的错误:Automatic modules not found in Eclipse 2018-12 when project is opened。
答案 0 :(得分:2)
确实,Eclipse有一个bug,仅当以非常特定的顺序执行编译时才会出现。
背景:在JPMS时代,程序包具有不同的内容 取决于询问哪个模块。在示例中,不同的模块 查看软件包
com.example
的不同配置: p.o.v.从其他角度来看,它包含一个子程序包n
没有。为了提高性能,此类查询的每个结果都会被缓存, 哪个导致了订单依赖性:首先查找哪个模块 软件包com.example
决定了对软件包的贡献奇怪的是,将拆分程序包定为非法的同一JPMS,要求编译器将具有多个贡献模块的每个父程序包都视为拆分程序包,从而大大增加了实现复杂性。
(已编辑:)该错误已解决为Eclipse bug 543765,此修复程序自2019-03版本以来可用。