关于 Java 模块和 Maven 的 Eclipse 2019-03
Eclipse 2019-03 regarding Java modules and maven
我有一个基于 java11 的 Maven (3.6.0) 项目,具有以下结构(在命令行上工作正常!):
src/main/java/
module-info.java
/de/test/tp/TP.java
src/test/java/
/de/test/tp/test/TPTests.java
模块-info.java 如下所示:
module de.test.tp
{
exports de.test.tp;
requires org.apache.logging.log4j;
}
TP.java:
package de.test.tp;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class TP
{
private static final Logger LOGGER = LogManager.getLogger(TP.class);
public TP()
{
super();
LOGGER.info("test");
}
}
TPTests.java:
package de.test.tp.test;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.junit.jupiter.api.Test;
import de.test.tp.TP;
public class TPTests
{
private static final Logger LOGGER = LogManager.getLogger(TP.class);
public TPTests()
{
super();
}
@Test
public void defaultConstructor()
{
final TP tp = new TP();
assertNotNull(tp, "Default constructor failed!");
}
}
最后但并非最不重要的部分 pom.xml
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<fork>true</fork>
<showDeprecation>true</showDeprecation>
<showWarnings>true</showWarnings>
<optimize>false</optimize>
<debug>true</debug>
<release>11</release>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.1</version>
<dependencies>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.4.1</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.4.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.11.2</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.11.2</version>
</dependency>
</dependencies>
当我现在说(从 Eclipse 中)"maven/update project" 时,eclipse 将所有 Maven 依赖项放入 类路径 。重新编译后 eclipse 告诉我:
The package org.apache.logging.log4j is accessible from more than one module: <unnamed>, org.apache.logging.log4j
两个 org.apache.logging.log4j
导入。
所以问题是,如何解决这个问题?
更新 1
我真正想要的是 java 模块项目的清晰项目结构,该项目基于 maven,在 eclipse 中工作并支持白盒和黑盒测试。有人可以给我这样的项目框架吗?
更新 2
或者我的问题是我在一些文章中看到的eclipse不支持多模块? - 这也会让我回到更新 1 的问题。
更新 3
缩短了整个问题并添加了完整(缩短)的文件内容。
注1
在我所有的测试中,例如在 test/java/
下有一个秒模块-info.java,我发现 eclipse 2019-03 非常不稳定并且有错误!例如 - 有时在尝试删除 module-info.java 测试时 - Eclipse 无法删除它。另一个影响是,当使用测试路径编辑 module-info.java 时,eclipse 也会编辑主路径下的 module-info.java。这意味着在主模块中 - info.java 我发现 exort 已更改为 de.test.tp.test - 当我修复它时(在 Eclipse 编辑器中)我无法保存文件。当我在外部编辑器和 refresh/clean 中修复它时,项目 eclipse 仍然告诉我 de.test.tp.test 不存在 - 所以我必须从标记选项卡中手动删除错误。
所以从我的角度来看,eclipse 2019-03 在 java 模块的处理方面存在一些错误。
注2
正如您从下面的评论中看到的那样,@howIger 将其报告为 bug in Eclipse。
注3
在我看来它现在已在 eclipse 2019-06 中修复:)
错误表明有多个模块(可能是一个 JAR)包含包 org.apache.logging.log4j
(或者更准确地说,可以从中访问包)。 Java 平台模块系统 (JPMS) 不允许这样做。但在本例中,只有一个包含该包的 JAR,因此在 Eclipse 2019-03 (4.11) 中错误显示了此 错误。参见:
作为此错误的解决方法,请执行以下操作之一:
- 在
module-info.java
中添加行 requires org.apache.logging.log4j.core;
将所有相关的 JAR 拉到模块路径
- 忽略错误(因为它不会阻止代码被编译)
- 降级到 Eclipse 2018-12 (4.10) 或等到 Eclipse 2019-06 (4.12)
默认情况下,所有 Maven 依赖项都在类路径中。在 module-info.java
中,行 requires org.apache.logging.log4j;
将带有 org.apache.logging.log4j
模块的 JAR 拉到模块路径上。该错误错误地指出类路径上还有另一个 JAR(因此在 unnamed 模块中)也包含包 org.apache.logging.log4j
。请注意,modules-info.test
(文件扩展名为 .test
)既不是 Java 也不是 Maven 的东西,因此对于 Eclipse 来说只是一个文本文件。
多模块支持:在您的情况下,您只有一个 module-info.java
,这意味着您只有一个 Java 模块。在 Eclipse 中,每个 Java 模块需要一个 Java 项目(因为每个模块都有自己的依赖项)。
我有一个基于 java11 的 Maven (3.6.0) 项目,具有以下结构(在命令行上工作正常!):
src/main/java/
module-info.java
/de/test/tp/TP.java
src/test/java/
/de/test/tp/test/TPTests.java
模块-info.java 如下所示:
module de.test.tp
{
exports de.test.tp;
requires org.apache.logging.log4j;
}
TP.java:
package de.test.tp;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class TP
{
private static final Logger LOGGER = LogManager.getLogger(TP.class);
public TP()
{
super();
LOGGER.info("test");
}
}
TPTests.java:
package de.test.tp.test;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.junit.jupiter.api.Test;
import de.test.tp.TP;
public class TPTests
{
private static final Logger LOGGER = LogManager.getLogger(TP.class);
public TPTests()
{
super();
}
@Test
public void defaultConstructor()
{
final TP tp = new TP();
assertNotNull(tp, "Default constructor failed!");
}
}
最后但并非最不重要的部分 pom.xml
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<fork>true</fork>
<showDeprecation>true</showDeprecation>
<showWarnings>true</showWarnings>
<optimize>false</optimize>
<debug>true</debug>
<release>11</release>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.1</version>
<dependencies>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.4.1</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.4.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.11.2</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.11.2</version>
</dependency>
</dependencies>
当我现在说(从 Eclipse 中)"maven/update project" 时,eclipse 将所有 Maven 依赖项放入 类路径 。重新编译后 eclipse 告诉我:
The package org.apache.logging.log4j is accessible from more than one module: <unnamed>, org.apache.logging.log4j
两个 org.apache.logging.log4j
导入。
所以问题是,如何解决这个问题?
更新 1
我真正想要的是 java 模块项目的清晰项目结构,该项目基于 maven,在 eclipse 中工作并支持白盒和黑盒测试。有人可以给我这样的项目框架吗?
更新 2
或者我的问题是我在一些文章中看到的eclipse不支持多模块? - 这也会让我回到更新 1 的问题。
更新 3
缩短了整个问题并添加了完整(缩短)的文件内容。
注1
在我所有的测试中,例如在 test/java/
下有一个秒模块-info.java,我发现 eclipse 2019-03 非常不稳定并且有错误!例如 - 有时在尝试删除 module-info.java 测试时 - Eclipse 无法删除它。另一个影响是,当使用测试路径编辑 module-info.java 时,eclipse 也会编辑主路径下的 module-info.java。这意味着在主模块中 - info.java 我发现 exort 已更改为 de.test.tp.test - 当我修复它时(在 Eclipse 编辑器中)我无法保存文件。当我在外部编辑器和 refresh/clean 中修复它时,项目 eclipse 仍然告诉我 de.test.tp.test 不存在 - 所以我必须从标记选项卡中手动删除错误。
所以从我的角度来看,eclipse 2019-03 在 java 模块的处理方面存在一些错误。
注2
正如您从下面的评论中看到的那样,@howIger 将其报告为 bug in Eclipse。
注3
在我看来它现在已在 eclipse 2019-06 中修复:)
错误表明有多个模块(可能是一个 JAR)包含包 org.apache.logging.log4j
(或者更准确地说,可以从中访问包)。 Java 平台模块系统 (JPMS) 不允许这样做。但在本例中,只有一个包含该包的 JAR,因此在 Eclipse 2019-03 (4.11) 中错误显示了此 错误。参见:
作为此错误的解决方法,请执行以下操作之一:
- 在
module-info.java
中添加行requires org.apache.logging.log4j.core;
将所有相关的 JAR 拉到模块路径 - 忽略错误(因为它不会阻止代码被编译)
- 降级到 Eclipse 2018-12 (4.10) 或等到 Eclipse 2019-06 (4.12)
默认情况下,所有 Maven 依赖项都在类路径中。在 module-info.java
中,行 requires org.apache.logging.log4j;
将带有 org.apache.logging.log4j
模块的 JAR 拉到模块路径上。该错误错误地指出类路径上还有另一个 JAR(因此在 unnamed 模块中)也包含包 org.apache.logging.log4j
。请注意,modules-info.test
(文件扩展名为 .test
)既不是 Java 也不是 Maven 的东西,因此对于 Eclipse 来说只是一个文本文件。
多模块支持:在您的情况下,您只有一个 module-info.java
,这意味着您只有一个 Java 模块。在 Eclipse 中,每个 Java 模块需要一个 Java 项目(因为每个模块都有自己的依赖项)。