How to use log4j with maven and java9 in Eclipse Oxygen?

∥☆過路亽.° 提交于 2019-12-12 08:16:07

问题


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>
    

回答1:


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:

  • 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

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:

What's the difference between requires and requires transitive statements in Java 9 module declaration

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

  • Log4j 2 doesn't support log4j.properties file anymore?

  • Converting log4j.properties to log4j.xml

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




回答2:


I was able to make this work somehow.

  1. I downloaded the latest Eclipse Photon Release (4.8.0), I don't know if this fix will work with older versions.
  2. I changed the module-info.java to have the following lines: requires log4j.api; requires log4j.core;
  3. I had to switch to an earlier version of log4j, 2.8.2.
  4. 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.



来源:https://stackoverflow.com/questions/47223440/how-to-use-log4j-with-maven-and-java9-in-eclipse-oxygen

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!