Log4j 使用嵌入式Jetty和Tapestry进行日志记录

Log4j 使用嵌入式Jetty和Tapestry进行日志记录,log4j,jetty,slf4j,tapestry,embedded-jetty,Log4j,Jetty,Slf4j,Tapestry,Embedded Jetty,我有一个WARWeb应用程序,它使用Tapestry框架。它使用slf4j+log4j,工作良好 我还有一个带有嵌入式jetty 8的简单服务器应用程序,用于部署war 我也希望在服务器中使用slf4j+log4j 因此,我将slf4j和log4j依赖项添加到我的服务器pom.xml中: 现在,实际的绑定和记录器应该只出现在服务器应用程序中。 但是,在服务器启动时,我得到: Exception in thread "main" java.lang.LinkageError: loader co

我有一个WARWeb应用程序,它使用Tapestry框架。它使用slf4j+log4j,工作良好

我还有一个带有嵌入式jetty 8的简单服务器应用程序,用于部署war

我也希望在服务器中使用slf4j+log4j

因此,我将slf4j和log4j依赖项添加到我的服务器pom.xml中:

现在,实际的绑定和记录器应该只出现在服务器应用程序中。 但是,在服务器启动时,我得到:

Exception in thread "main" java.lang.LinkageError: loader constraint violation: when resolving method "org.slf4j.impl.StaticLoggerBinder.getLoggerFactory()Lorg/slf4j/ILoggerFactory;" the class loader (instance of org/eclipse/jetty/webapp/WebAppClassLoader) of the current class, org/slf4j/LoggerFactory, and the class loader (instance of sun/misc/Launcher$AppClassLoader) for resolved class, org/slf4j/impl/StaticLoggerBinder, have different Class objects for the type taticLoggerBinder.getLoggerFactory()Lorg/slf4j/ILoggerFactory; used in the signature
at org.slf4j.LoggerFactory.getILoggerFactory(LoggerFactory.java:299)
at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:269)
at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:281)
at org.apache.tapestry5.TapestryFilter.<init>(TapestryFilter.java:56)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:526)
at java.lang.Class.newInstance(Class.java:374)
at org.eclipse.jetty.servlet.ServletContextHandler$Context.createFilter(ServletContextHandler.java:1051)
at org.eclipse.jetty.servlet.FilterHolder.doStart(FilterHolder.java:104)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:64)
at org.eclipse.jetty.servlet.ServletHandler.initialize(ServletHandler.java:763)
at org.eclipse.jetty.servlet.ServletContextHandler.startContext(ServletContextHandler.java:265)
at org.eclipse.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1242)
at org.eclipse.jetty.server.handler.ContextHandler.doStart(ContextHandler.java:717)
at org.eclipse.jetty.webapp.WebAppContext.doStart(WebAppContext.java:494)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:64)
at org.eclipse.jetty.server.handler.HandlerWrapper.doStart(HandlerWrapper.java:95)
at org.eclipse.jetty.server.Server.doStart(Server.java:282)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:64)
...
线程“main”java.lang.LinkageError中的异常:加载程序约束冲突:在解析方法“org.slf4j.impl.StaticLoggerBinder.getLoggerFactory()Lorg/slf4j/ILOGERFactory”时;当前类的类加载器(org/eclipse/jetty/webapp/WebAppClassLoader实例)、org/slf4j/LoggerFactory和类加载器解析类org/slf4j/impl/StaticLoggerBinder的(sun/misc/Launcher$AppClassLoader实例)具有不同的类对象,其类型为TatiBloggerBinder.getLoggerFactory()Lorg/slf4j/ILoggerFactory;用于签名中
位于org.slf4j.LoggerFactory.getILoggerFactory(LoggerFactory.java:299)
位于org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:269)
位于org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:281)
位于org.apache.tapestry5.TapestryFilter(TapestryFilter.java:56)
位于sun.reflect.NativeConstructorAccessorImpl.newInstance0(本机方法)
位于sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
在sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
位于java.lang.reflect.Constructor.newInstance(Constructor.java:526)
位于java.lang.Class.newInstance(Class.java:374)
位于org.eclipse.jetty.servlet.ServletContextHandler$Context.createFilter(ServletContextHandler.java:1051)
位于org.eclipse.jetty.servlet.FilterHolder.doStart(FilterHolder.java:104)
位于org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:64)
位于org.eclipse.jetty.servlet.ServletHandler.initialize(ServletHandler.java:763)
位于org.eclipse.jetty.servlet.ServletContextHandler.startContext(ServletContextHandler.java:265)
位于org.eclipse.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1242)
位于org.eclipse.jetty.server.handler.ContextHandler.doStart(ContextHandler.java:717)
位于org.eclipse.jetty.webapp.WebAppContext.doStart(WebAppContext.java:494)
位于org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:64)
位于org.eclipse.jetty.server.handler.HandlerWrapper.doStart(HandlerWrapper.java:95)
位于org.eclipse.jetty.server.server.doStart(server.java:282)
位于org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:64)
...
一直到我的jetty Server.start()调用


我遗漏了什么?

问题是,您的类路径上有两个版本的slf4j-log4j12。从外观上看,您正设法排除较新版本而不是较旧版本。slf4j抱怨说,它期望的版本比找到的版本更新


在我看来,1.6.1版本通过嵌入式jetty服务器进入了您的类路径。您是否也通过maven设置了jetty依赖项?如果是,请将排除项也添加到jetty依赖项中。无论哪种方式,您都需要检查类路径并以某种方式解决冲突的版本。好的,谢谢帮助joostschouten和用户2424794。我已经让它工作了。

mvn dependency:tree
显示,其他web应用程序的dependency:
qpid客户端
将另一个
slf4j api
导入war。
因此,另一种排除是必要的:

<dependency>
    <groupId>org.apache.qpid</groupId>
    <artifactId>qpid-client</artifactId>
    <version>0.22</version>
    <exclusions>
        <exclusion>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
        </exclusion>
    </exclusions>
</dependency>
当然,
slf4j api
slf4j-log4j12
log4j
作为服务器的依赖项添加,服务器将其“提供”给war应用程序


现在一切都可以正常编译、运行和记录了。

您有一个依赖项问题。我没有在看到依赖项树时一直使用排除,而是在pom.xml中对标记进行重新排序。这里的规则是,依赖项的第一个外观获胜。因此,如果您希望继承的依赖项被另一个忽略,只需移动要忽略继承的依赖项之前的依赖项标记


这使pom更具可读性,还可以控制树中使用的依赖项的版本。只有在极少数情况下,我必须使用标记。

您是否尝试过从命令行
mvn dependency:tree
,以确保您没有从其他地方拾取罐子?您也可以使用maven pom中的
部分。T他的部分可以用来强制依赖项的特定版本,而不管它是如何进入依赖项树的。
<exclusions>  
    <exclusion>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-log4j12</artifactId>
    </exclusion>

    <exclusion>
        <groupId>log4j</groupId>
        <artifactId>log4j</artifactId>
    </exclusion>
</exclusions>
Exception in thread "main" java.lang.LinkageError: loader constraint violation: when resolving method "org.slf4j.impl.StaticLoggerBinder.getLoggerFactory()Lorg/slf4j/ILoggerFactory;" the class loader (instance of org/eclipse/jetty/webapp/WebAppClassLoader) of the current class, org/slf4j/LoggerFactory, and the class loader (instance of sun/misc/Launcher$AppClassLoader) for resolved class, org/slf4j/impl/StaticLoggerBinder, have different Class objects for the type taticLoggerBinder.getLoggerFactory()Lorg/slf4j/ILoggerFactory; used in the signature
at org.slf4j.LoggerFactory.getILoggerFactory(LoggerFactory.java:299)
at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:269)
at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:281)
at org.apache.tapestry5.TapestryFilter.<init>(TapestryFilter.java:56)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:526)
at java.lang.Class.newInstance(Class.java:374)
at org.eclipse.jetty.servlet.ServletContextHandler$Context.createFilter(ServletContextHandler.java:1051)
at org.eclipse.jetty.servlet.FilterHolder.doStart(FilterHolder.java:104)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:64)
at org.eclipse.jetty.servlet.ServletHandler.initialize(ServletHandler.java:763)
at org.eclipse.jetty.servlet.ServletContextHandler.startContext(ServletContextHandler.java:265)
at org.eclipse.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1242)
at org.eclipse.jetty.server.handler.ContextHandler.doStart(ContextHandler.java:717)
at org.eclipse.jetty.webapp.WebAppContext.doStart(WebAppContext.java:494)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:64)
at org.eclipse.jetty.server.handler.HandlerWrapper.doStart(HandlerWrapper.java:95)
at org.eclipse.jetty.server.Server.doStart(Server.java:282)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:64)
...
<dependency>
    <groupId>org.apache.qpid</groupId>
    <artifactId>qpid-client</artifactId>
    <version>0.22</version>
    <exclusions>
        <exclusion>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
        </exclusion>
    </exclusions>
</dependency>
<dependency>
    <groupId>org.apache.tapestry</groupId>
    <artifactId>tapestry-core</artifactId>
    <version>${tapestry-release-version}</version>
    <exclusions>  
        <exclusion>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
        </exclusion>
        <exclusion>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
        </exclusion>
        <exclusion>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
        </exclusion>
    </exclusions>
</dependency>
<dependency>
     <groupId>org.slf4j</groupId>
     <artifactId>slf4j-api</artifactId>
     <version>1.7.5</version>
     <scope>provided</scope>
</dependency>