问题描述
我尝试将Java8项目迁移到Java9.自动生成的模块info.java包含一个条目
requires log4j;
显示错误:
log4j cannot be resolved to a module
=>如何正确将log4j作为Java9的模块依赖关系?
(我也有同样的问题以下依赖项: 需要Hibernate.Core; 需要Hibernate.jpa.2.1.api; 需要jcommander; 需要Junit; 需要思考; )
我到目前为止所做的:
- 安装Java 9.0.1
- 将日食升级为oxygen.1a版本(4.7.1a)
- 将我的Java项目的合规级别更改为9
-
生成的模块info.java带有右键单击project => configure =>生成模块info.java
-
在我的pom.xml文件中更新了插件(另请参见 https://cwiki.apache.org/confluence/display/maven/maven/java +9+ - +jigsaw ),将java版本设置为9:
<!-- plugin for compile phase (and test-compile phase) --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.7.0</version> <configuration> <!-- specify current java version here: --> <source>9</source> <target>9</target> </configuration> </plugin>
-
在pom.xml文件中更新了log4j版本,因为log4j 1.2似乎与java9不起作用(请参阅 https://blogs.apache.org/logging/entry/moving_on_to_log4j_2 )
<dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-api</artifactId> <version>2.9.1</version> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> <version>2.9.1</version> </dependency>
推荐答案
Module-info.java中的错误
即使已将项目的合规性级别设置为Java9,也可能会在Eclipse中显示误导错误.
我希望仅在更改pom.xml文件时需要更新Maven项目.现在,我了解到更改模块info.java还需要对Maven项目进行手动更新.
=> 更新Maven项目(ALT+F5)
之后,更新我的错误消失了.
我还了解到,最好先更新pom.xml文件中的版本,然后生成模块info.java.否则,模块info.java将包括"启用log4j"等不存在的模块,而不是"需要log4j.api"
模块info.java中的另一个误导性错误可能是由于POM包装而发生的,请参见下文.
未解决的进口
对于无法解决导入的情况下,问题可能是"我需要哪个相应的(新)模块(旧)导入?".在这里可能会有所帮助:
-
在以下页面搜索所需页面: MR/Jigsaw/EA/Module-Summary.html (列出JDK模型的所有导出软件包)
-
使用(旧) *.jar文件上的JDEP获取所需JAR文件的列表,例如
jdeps - 级别路径" lib" - recursive my old.jar> output.txt
-
使用jar查找jar文件的模块
jar-deScribe-module-文件quired-jar-file.jar
也请参见:
重新出口依赖项
为了使祖父母项目可见自动可见
grandparent => parent => log4j
您可能要使用
requires transitive log4j.api
在父母中而不是
中requires log4j.api
祖父母.另请参阅:
POM包装
我的主要问题似乎是我的java8 pom.xml文件使用了pom包装:
<packaging>pom</packaging>
如果我删除了该行,则在模块info.java中没有显示错误
还请参见以下其他问题:如何与maven一起使用maven java9.0.1和Eclipse氧气中的POM包装1a释放(4.7.1a)?
新的log4j版本
a.除了更改"需要log4j" =>"需要log4j.api",我还必须针对与Java9兼容的新log4j版本的调用代码:
私有静态记录器syslog = logger.getLogger(main.class);
to
私有静态记录器syslog = logmanager.getlogger(main.class);
b. log4j 2没有属性configurator.另请参阅此相关问题:
c. log4j 2不支持log4j.properties文件.以前我用过
src/main/resources/meta-inf/log4j.properties
用于配置.现在我使用
src/main/resources/log4j2.xml
也请参见
工作示例作为参考
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>Log4JWithJava9</groupId> <artifactId>Log4JWithJava9</artifactId> <version>0.0.1-SNAPSHOT</version> <build> <sourceDirectory>src</sourceDirectory> <plugins> <plugin> <artifactId>maven-compiler-plugin</artifactId> <version>3.7.0</version> <configuration> <release>9</release> </configuration> </plugin> </plugins> </build> <dependencies> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-api</artifactId> <version>2.9.1</version> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> <version>2.9.1</version> </dependency> </dependencies> </project>
Module-info.java:
module Log4JWithJava9 { requires javafx.base; requires log4j.api; }
main.java:
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; public class Main { private static Logger sysLog = LogManager.getLogger(Main.class); public static void main(String[] args) { } }
Eclipse插件
为了将log4j添加到eclipse插件中,我在文件夹" lib"中复制了文件log4j-api-2.10.0.jar,并将jar文件添加到java build path => libraries => modulepath
而不是requires log4j.api我必须使用requires org.apache.logging.log4j
其他推荐答案
我能够以某种方式完成这项工作.
- 我下载了最新的Eclipse Photon版本(4.8.0),我不知道此修复程序是否适用于较旧版本.
- 我更改了module-info.java具有以下几行: requires log4j.api; requires log4j.core;
- 我必须切换到log4j的早期版本,2.8.2.
- 我更改了所有的导入,说import org.apache.logging.log4j.*;不使用通配符.因此他们更改为:import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger;
就是这样,它可以与Maven和Eclipse一起使用.
问题描述
I try to migrate a Java8 project to Java9. The auto generated module-info.java contains an entry
requires log4j;
and an error is shown:
log4j cannot be resolved to a module
=> How do I correctly include log4j as a module dependency with Java9?
(I have the same issue for following dependencies: requires hibernate.core; requires hibernate.jpa.2.1.api; requires jcommander; requires junit; requires reflections; )
What I did so far:
- Installed Java 9.0.1
- Upgraded Eclipse to Oxygen.1a Release (4.7.1a)
- Changed Compliance level of my Java project to 9
Generated module-info.java with Right click on project=>Configure=>Generate module-info.java
Updated the plugins in my pom.xml file (also see https://cwiki.apache.org/confluence/display/MAVEN/Java+9+-+Jigsaw) and set java version to 9:
<!-- plugin for compile phase (and test-compile phase) --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.7.0</version> <configuration> <!-- specify current java version here: --> <source>9</source> <target>9</target> </configuration> </plugin>
Updated log4j version in pom.xml file since log4j 1.2 does not seem to work with Java9 (see https://blogs.apache.org/logging/entry/moving_on_to_log4j_2)
<dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-api</artifactId> <version>2.9.1</version> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> <version>2.9.1</version> </dependency>
推荐答案
Errors in module-info.java
Even if the compliance level of the project has been set to Java9, there might be shown misleading errors for module-info.java in Eclipse.
I expected that an update of the maven project would only be required if I change the pom.xml file. Now I learned that changing the module-info.java also requires a manual update of the maven project.
=> update the maven project (Alt+F5)
After that update my errors vanished.
I also learned that it is better to first update the versions in the pom.xml file and then generate the module-info.java. Otherwise the module-info.java will include non-existing modules like "requires log4j" instead of "requires log4j.api"
Another misleading error in module-info.java might occur due to pom packaging, see below.
Unresolved imports
For the case that an import can not be resolved the question might be "Which corresponding (new) module do I need for that (old) import?". What might help here:
Search at following page for the required page: http://cr.openjdk.java.net/~mr/jigsaw/ea/module-summary.html (lists all exported packages of the JDK-modules)
Use JDeps on the (old) *.jar file to get a list of required jar files, e.g.
jdeps --class-path "lib" -recursive MY-OLD.jar >output.txt
Use jar to find the module for a jar file
jar --describe-module --file REQUIRED-JAR-FILE.jar
Also see:
Re-Export dependencies
In order to automatically make log4j visible for a grandparent project
grandparent => parent => log4j
you might want to use
requires transitive log4j.api
in parent instead of
requires log4j.api
in grandparent. Also see:
POM packaging
My main issue seems to be that my Java8 pom.xml file used pom packaging:
<packaging>pom</packaging>
If I remove that line, no errors are shown in module-info.java
Also see this extra question: How to use maven with Java9.0.1 and pom packaging in Eclipse Oxygen 1a Release (4.7.1a)?
New log4j version
A. In addition to the change "requires log4j" => "requires log4j.api" I had to adapt the calling code for the new log4j version that is compatible to Java9:
private static Logger sysLog = Logger.getLogger(Main.class);
to
private static Logger sysLog = LogManager.getLogger(Main.class);
B. log4j 2 does not have PropertyConfigurator. Also see this related question:
PropertyConfigurator in log4j2
C. log4j 2 does not support log4j.properties files. Previously I used
src/main/resources/META-INF/log4j.properties
for configuration. Now I use
src/main/resources/log4j2.xml
Also see
Working example as a reference
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>Log4JWithJava9</groupId> <artifactId>Log4JWithJava9</artifactId> <version>0.0.1-SNAPSHOT</version> <build> <sourceDirectory>src</sourceDirectory> <plugins> <plugin> <artifactId>maven-compiler-plugin</artifactId> <version>3.7.0</version> <configuration> <release>9</release> </configuration> </plugin> </plugins> </build> <dependencies> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-api</artifactId> <version>2.9.1</version> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> <version>2.9.1</version> </dependency> </dependencies> </project>
module-info.java:
module Log4JWithJava9 { requires javafx.base; requires log4j.api; }
Main.java:
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; public class Main { private static Logger sysLog = LogManager.getLogger(Main.class); public static void main(String[] args) { } }
Eclipse plugins
In order to add log4j to an eclipse plugin, I copied the file log4j-api-2.10.0.jar in a folder "lib" and added the jar file to Java Build Path=>Libraries=>ModulePath
Instead of requires log4j.api I had to use requires org.apache.logging.log4j
其他推荐答案
I was able to make this work somehow.
- I downloaded the latest Eclipse Photon Release (4.8.0), I don't know if this fix will work with older versions.
- I changed the module-info.java to have the following lines: requires log4j.api; requires log4j.core;
- I had to switch to an earlier version of log4j, 2.8.2.
- I changed all my imports that say import org.apache.logging.log4j.*; to not use the wildcard. So they changed to: import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger;
That's it, it works with both Maven and Eclipse.