如何在 Eclipse Oxygen 中将 log4j 与 maven 和 java9 一起使用?
Posted
技术标签:
【中文标题】如何在 Eclipse Oxygen 中将 log4j 与 maven 和 java9 一起使用?【英文标题】:How to use log4j with maven and java9 in Eclipse Oxygen? 【发布时间】:2018-04-23 17:19:12 【问题描述】:我尝试将 Java8 项目迁移到 Java9。自动生成的 module-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 将 Eclipse 升级到 Oxygen.1a 版本 (4.7.1a) 将我的 Java 项目的合规级别更改为 9通过右键单击项目=>配置=>生成 module-info.java 生成 module-info.java
更新了我的 pom.xml 文件中的插件(另见 https://cwiki.apache.org/confluence/display/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>
【问题讨论】:
您不应再次将编译器插件绑定到生命周期。仅在 pluginManagement 版本 3.7.0 中定义 maven-compiler-plugin 并定义源/目标...无绑定.. log4j-api 不包含 modules-info.class 文件,因此仅使用自动模块名称,即 log4j- api?而不是 log4j... 如果没有一个requires
被识别,我会坚持你分享完整的项目结构和你的 pom.xml 的 <build>
配置。此外,为上述依赖项派生的自动模块名称分别为 log4j.api
和 log4j.core
。
您可以使用jar
命令(来自Java 9)来找出模块的名称:jar --describe-module --file $JAR-FILE
告诉您必须使用哪个名称来要求它。此外,您可以use JDeps to identify which JARs you directly depend on。
@nullpointer 我要使用的 pom 包装(我的问题中没有提到它,因为我首先认为它不相关)不包括编译阶段。因此我必须明确包含编译器插件。
【参考方案1】:
module-info.java 中的错误
即使项目的合规级别已设置为 Java9,Eclipse 中的 module-info.java 也可能会显示误导性错误。
我预计只有在我更改 pom.xml 文件时才需要更新 maven 项目。现在了解到更改module-info.java也需要手动更新maven项目。
=> 更新maven项目(Alt+F5)
在那次更新之后,我的错误消失了。
我还了解到,最好先更新 pom.xml 文件中的版本,然后生成 module-info.java。否则,module-info.java 将包含不存在的模块,例如“requires log4j”而不是“requires log4j.api”
由于 pom 打包,可能会在 module-info.java 中出现另一个误导性错误,请参见下文。
未解决的导入
对于无法解析导入的情况,问题可能是“对于该(旧)导入,我需要哪个相应的(新)模块?”。这里有什么帮助:
在以下页面搜索所需页面: http://cr.openjdk.java.net/~mr/jigsaw/ea/module-summary.html (列出 JDK 模块的所有导出包)
在(旧)*.jar 文件上使用 JDeps 以获取所需 jar 文件的列表,例如
jdeps --class-path "lib" -recursive MY-OLD.jar >output.txt
使用 jar 查找 jar 文件的模块
jar --describe-module --file REQUIRED-JAR-FILE.jar
另见:
What are the predefined modules in JDK9 or Which module do I need to fix dependency problems?
https://blog.codefx.org/tools/jdeps-tutorial-analyze-java-project-dependencies/#Getting-To-Know-JDeps
重新导出依赖项
为了自动使 log4j 对祖父项目可见
grandparent => parent => log4j
你可能想使用
requires transitive log4j.api
在父级而不是
requires log4j.api
在祖父母。另见:
What's the difference between requires and requires transitive statements in Java 9 module declaration
POM 包装
我的主要问题似乎是我的 Java8 pom.xml 文件使用了 pom 包装:
<packaging>pom</packaging>
如果我删除该行,module-info.java 中不会显示任何错误
另请参阅这个额外的问题:How to use maven with Java9.0.1 and pom packaging in Eclipse Oxygen 1a Release (4.7.1a)?
新的 log4j 版本
A.除了更改“需要 log4j”=>“需要 log4j.api”之外,我还必须调整与 Java9 兼容的新 log4j 版本的调用代码:
私有静态 Logger sysLog = Logger.getLogger(Main.class);
到
私有静态Logger sysLog = LogManager.getLogger(Main.class);
B. log4j 2 没有 PropertyConfigurator。另请参阅此相关问题:
PropertyConfigurator in log4j2
C. log4j 2 不支持 log4j.properties 文件。以前我用过
src/main/resources/META-INF/log4j.properties
用于配置。现在我用
src/main/resources/log4j2.xml
另见
Log4j 2 doesn't support log4j.properties file anymore?
Converting log4j.properties to log4j.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>
模块信息.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 插件,我将文件 log4j-api-2.10.0.jar 复制到文件夹“lib”中,并将 jar 文件添加到 Java Build Path=>Libraries=>ModulePath
我不得不使用requires org.apache.logging.log4j
而不是requires log4j.api
【讨论】:
【参考方案2】:我能够以某种方式完成这项工作。
-
我下载了最新的 Eclipse Photon Release (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。
【讨论】:
这对我不起作用,使用与您描述的相同的 Eclipse 和相同的设置,我得到:“log4j.api 无法解析为模块”在模块信息类或“The当我不创建模块信息文件时,可以从多个模块访问包 org.apache.logging.log4j:org.apache.logging.log4j、org.apache.logging.log4j.core”。 查看:bugs.eclipse.org/bugs/show_bug.cgi?id=534624 看来我们必须等待 Eclipse 4.8.1 甚至 4.9.0 版本才能修复此问题。 我更改了说明。更改了第 2 步并添加了第 3 步。我可以正常工作以上是关于如何在 Eclipse Oxygen 中将 log4j 与 maven 和 java9 一起使用?的主要内容,如果未能解决你的问题,请参考以下文章
JavaEclipse Oxygen 如何正确配置Java 9 SDK
Ubuntu16.04 install eclipse-jee-oxygen-R-linux-gtk-x86_64