Maven依赖和日志记录 - Slf4j和Log4j

时间:2014-05-21 06:49:59

标签: maven log4j slf4j

我正在使用Maven来管理基于spring的项目中的项目依赖项。

<dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.16</version>
    <!-- <scope>provided</scope> -->
    </dependency>

    <dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <version>1.7.5</version>
    <!-- <scope>provided</scope> -->
</dependency>

但是,部署在同一服务器上的其他一些项目使用tomcat的lib目录中的 slf4j和log4j 库,我无法删除它们。

  

tomcat的lib目录中存在的Slf4J和Log4J版本是

     
    

SLF4J-API-1.4.2

         

的log4j-1.2.14

         

SLF4J-log4j12-1.5.2

  

当我从tomcat的lib目录中删除这些库并使用项目的pom中提到的库时,我的项目工作正常

当我在项目的pom文件中注释依赖项并使用tomcat的lib中存在的那个时,抛出异常

> SEVERE: Exception sending context initialized event to listener instance of class org.springframework.web.context.ContextLoaderListener
java.lang.NoSuchMethodError: org.slf4j.impl.StaticLoggerBinder.getSingleton()Lorg/slf4j/impl/StaticLoggerBinder;
    at org.slf4j.LoggerFactory.bind(LoggerFactory.java:128)
    at org.slf4j.LoggerFactory.performInitialization(LoggerFactory.java:107)
    at org.slf4j.LoggerFactory.getILoggerFactory(LoggerFactory.java:295)
    at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:269)
    at org.apache.commons.logging.impl.SLF4JLogFactory.getInstance(SLF4JLogFactory.java:155)
    at org.apache.commons.logging.impl.SLF4JLogFactory.getInstance(SLF4JLogFactory.java:131)
    at org.apache.commons.logging.LogFactory.getLog(LogFactory.java:657)
    at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:282)
    at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:106)
    at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4797)
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5291)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1559)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1549)
    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
    at java.util.concurrent.FutureTask.run(FutureTask.java:166)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
    at java.lang.Thread.run(Thread.java:722)

>May 21, 2014 11:57:27 AM org.apache.catalina.core.StandardContext startInternal
SEVERE: Error listenerStart
May 21, 2014 11:57:27 AM org.apache.catalina.core.StandardContext startInternal
SEVERE: Context [/onevalue] startup failed due to previous errors
May 21, 2014 11:57:27 AM org.apache.catalina.core.ApplicationContext log
INFO: Closing Spring root WebApplicationContext
May 21, 2014 11:57:27 AM org.apache.catalina.core.StandardContext listenerStop
SEVERE: Exception sending context destroyed event to listener instance of class org.springframework.web.context.ContextLoaderListener
java.lang.ExceptionInInitializerError
    at org.springframework.web.context.ContextLoaderListener.contextDestroyed(ContextLoaderListener.java:116)
    at org.apache.catalina.core.StandardContext.listenerStop(StandardContext.java:4837)
    at org.apache.catalina.core.StandardContext.stopInternal(StandardContext.java:5484)
    at org.apache.catalina.util.LifecycleBase.stop(LifecycleBase.java:232)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:160)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1559)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1549)
    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
    at java.util.concurrent.FutureTask.run(FutureTask.java:166)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
    at java.lang.Thread.run(Thread.java:722)
Caused by: java.lang.IllegalStateException: org.slf4j.LoggerFactory could not be successfully initialized. See also http://www.slf4j.org/codes.html#unsuccessfulInit
    at org.slf4j.LoggerFactory.getILoggerFactory(LoggerFactory.java:303)
    at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:269)
    at org.apache.commons.logging.impl.SLF4JLogFactory.getInstance(SLF4JLogFactory.java:155)
    at org.apache.commons.logging.impl.SLF4JLogFactory.getInstance(SLF4JLogFactory.java:131)
    at org.apache.commons.logging.LogFactory.getLog(LogFactory.java:657)
    at org.springframework.web.context.ContextCleanupListener.<clinit>(ContextCleanupListener.java:43)
    ... 12 more

我还尝试使用maven范围“提供”,同时将库保存在tomcat的lib目录中。虽然项目运行,但现在日志记录机制不起作用,没有创建日志,甚至System.out.println()也无法在控制台窗口上打印任何内容

2 个答案:

答案 0 :(得分:2)

似乎您需要将项目降级到slf4j 1.4.2以使用tomcat中可用的log4j。它们是二进制不兼容的。之后你也会继续<scope>provided</scope>,所以你不要把它们加倍。

另一种方法是让其他项目包含库本身并从tomcat中删除。我知道tomcat上没有其他排除机制。

供参考,可能没有帮助,我目前部署在weblogic上,它有一个部署规范,允许排除服务器公共类并改为使用捆绑类,例如下面的代码片段(带参考)

<wls:prefer-application-packages>
<!-- http://blog.terrencemiao.com/archives/annoying-slf4j-problem-in-weblogic-server-12c -->
  <wls:package-name>org.slf4j</wls:package-name>
    </wls:prefer-application-packages>

答案 1 :(得分:0)

<dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>1.7.5</version>
</dependency>

这是我的配置,它对我来说很好。