到目前为止,我一直在使用 Maven 目标开发 Tapestry 5.1.0.5 Web 应用程序来编译/打包/执行应用程序。我使用 mvn jetty:run 目标来运行 Jetty maven 插件。这总是工作得很好。Maven 似乎使用了 Jetty 6.1.9。
我现在需要设置一个不使用 Maven 目标执行的生产环境。我认为 Jetty 看起来很简单,它已经在使用 Maven。我得到了 6.1.26(后来也尝试了 6.1.9,但没有运气),将我的应用程序 WAR 文件放入 webapp 目录,然后尝试运行它......没有运气。
每次我收到此错误时,都不会改变:
2010-11-17 18:33:13.436:WARN::Error starting handlers
java.lang.NoClassDefFoundError: org/apache/log4j/Level
at org.slf4j.LoggerFactory.getSingleton(LoggerFactory.java:228)
at org.slf4j.LoggerFactory.bind(LoggerFactory.java:120)
at org.slf4j.LoggerFactory.performInitialization(LoggerFactory.java:111)
at org.slf4j.LoggerFactory.getILoggerFactory(LoggerFactory.java:269)
at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:242)
at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:255)
at org.apache.tapestry5.TapestryFilter.<init>(TapestryFilter.java:45)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
at java.lang.Class.newInstance0(Class.java:355)
at java.lang.Class.newInstance(Class.java:308)
at org.mortbay.jetty.servlet.Holder.newInstance(Holder.java:153)
at org.mortbay.jetty.servlet.FilterHolder.doStart(FilterHolder.java:92)
at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
at org.mortbay.jetty.servlet.ServletHandler.initialize(ServletHandler.java:713)
at org.mortbay.jetty.servlet.Context.startContext(Context.java:140)
at org.mortbay.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1282)
at org.mortbay.jetty.handler.ContextHandler.doStart(ContextHandler.java:518)
at org.mortbay.jetty.webapp.WebAppContext.doStart(WebAppContext.java:499)
at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
at org.mortbay.jetty.handler.HandlerCollection.doStart(HandlerCollection.java:152)
at org.mortbay.jetty.handler.ContextHandlerCollection.doStart(ContextHandlerCollection.java:156)
at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
at org.mortbay.jetty.handler.HandlerCollection.doStart(HandlerCollection.java:152)
at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
at org.mortbay.jetty.handler.HandlerWrapper.doStart(HandlerWrapper.java:130)
at org.mortbay.jetty.Server.doStart(Server.java:224)
at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
at org.mortbay.xml.XmlConfiguration.main(XmlConfiguration.java:985)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.mortbay.start.Main.invokeMain(Main.java:194)
at org.mortbay.start.Main.start(Main.java:534)
at org.mortbay.start.Main.start(Main.java:441)
at org.mortbay.start.Main.main(Main.java:119)
我最初使用 Log4J 1.2.8 作为整个应用程序的手动依赖项的一部分。我阅读了这个网站http://tapestry.apache.org/tapestry5.1/jetty.html然后意识到我应该使用 1.2.12 或更高版本的 TRACE 级别。首先,我将依赖项更新为 LOG4J 1.2.16。这没有用。
然后我做了一些进一步的阅读,表明 apache-commons-logging 依赖项可能会由于它的工作方式而导致日志记录问题。我遍历了整个依赖层次结构,并从所有内容中排除了 apache-commons-logging。在这一点上,该应用程序仍然可以与 maven jetty 插件一起使用,所以我这样做并没有破坏任何东西。但是当我部署 WAR 时,我仍然遇到异常,所以这不是解决方案。
下一步我意识到 Tapestry-ioc 依赖在我的系统端 log4j 和它想要的版本之间的 log4j 版本上发生冲突。似乎它使用 log4j 1.2.13 并且依赖项中的 slf4j 使用了 compile Log4J 1.2.14。
我将我的系统依赖项更新为第一个 1.2.14(因为此错误发生在 Tapestry 的 slf4j 中),然后在 1.2.13 再次失败时。这两种情况都没有发生。
我听说过要确保 Jetty 不会使用用于其自己的日志记录的较低版本覆盖您的 Log4J。然而,在 Jetty 文件中我找不到任何 log4j 依赖项。