由于(Maven)依赖关系管理,我知道在类路径上丢失或重复slf4j实现的原因,并且知道如何通过排除来避免这种情况。
但是,如果我有一个包含EJB接口和实体的JAR的多模块Java项目,EJB实现和打包为EAR的WAR Web前端,我找不到放置slf4j API org.slf4j:slf4j-api:1.7.25
的方法,实现ch.qos.logback:logback-classic:1.2.3
和配置logback.xml
,以便我在JAR,EJB和WEB模块中工作,并且可以避免这两者
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
和
SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/home/richter/zpool-tmp/jee-slf4j-logging/jee-slf4j-logging-ear/target/gfdeploy/jee-slf4j-logging-ear/jee-slf4j-logging-web-1.0-SNAPSHOT_war/WEB-INF/lib/logback-classic-1.2.3.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/home/richter/zpool-tmp/jee-slf4j-logging/jee-slf4j-logging-ear/target/gfdeploy/jee-slf4j-logging-ear/lib/logback-classic-1.2.3.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.
SLF4J: Actual binding is of type [ch.qos.logback.classic.util.ContextSelectorStaticBinder]
和
Caused by: java.lang.LinkageError: loader constraint violation: when resolving method "org.slf4j.impl.StaticLoggerBinder.getLoggerFactory()Lorg/slf4j/ILoggerFactory;" the class loader (instance of org/glassfish/web/loader/WebappClassLoader) of the current class, org/slf4j/LoggerFactory, and the class loader (instance of org/glassfish/javaee/full/deployment/EarLibClassLoader) for the method's defining class, org/slf4j/impl/StaticLoggerBinder, have different Class objects for the type org/slf4j/ILoggerFactory used in the signature
at org.slf4j.LoggerFactory.getILoggerFactory(LoggerFactory.java:418)
at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:357)
at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:383)
我在https://gitlab.com/krichter/jee-slf4j-logging提供MCVE。
GlassFish 4, no logging framework dependencies is working in pom.xml不涉及Java EE方面。
我最后做了以下事情:
Class-Path: conf
如果您使用maven在您的moules(例如web,ejb和ejb接口)中构建项目,请将依赖性添加到具有提供范围的slf4j-api:
WEB, EJB, API modules
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
<scope>provided</scope>
</dependency>
并在您的EAR模块中添加依赖项到slf4j-api和logback-classic和logback-core:
EAR modeule
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>${logback.version}</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>${logback.version}</version>
</dependency>
要在模块中将conf定义为Class-Path,请在maven-war-plugin,maven-jar-plugin和maven-ejb-plugin中使用以下行。
WEB, EJB, API modules
<configuration>
<archive>
<addMavenDescriptor>false</addMavenDescriptor>
<manifest>
<addClasspath>true</addClasspath>
</manifest>
<manifestEntries>
<Class-Path>logback</Class-Path>
</manifestEntries>
</archive>
...