到目前为止,我一直在使用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时,我仍然得到例外,因此这不是解决方案。
下一步我意识到我的系统端log4j和它想要的log4j版本之间的tapestry-ioc依赖是冲突的。它似乎使用log4j 1.2.13并且依赖项中的slf4j使用编译Log4J 1.2.14。
我将系统依赖关系更新为1.2.14(因为此错误发生在Tapestry中的slf4j),然后再次以1.2.13再次失败。这些案件都没有发生。
我听说过确保Jetty不会覆盖你用于自己日志记录的较低版本的Log4J。然而Jetty文件中没有任何地方可以找到任何log4j依赖。
答案 0 :(得分:1)
我准备猜测:
这可能是由
引起的当maven下载了log4j依赖项时,它失败或被破坏 - 尝试删除maven存储库中的log4j目录(windows:docs和settings / user / .m2 /....)
< / LI>存在某种依赖性冲突,而且maven正在通过不包括任何一种方式来解决它 - 这不太可能,我认为它将包括最新版本
< / LI>其他一些maven插件或配置导致log4j jar被从WAR创建中排除(duh)
不知道还有什么可能导致这个...
编辑评论:
是的啊,是的,现在你提到它我有这个问题!我有几个'自我管理'(即不是maven托管)罐子,据我所知,将它们包含在maven类路径中的唯一方法是给它们一个system
范围。你的问题变成:“我如何在maven构建中包含非maven jar?”
scope
元素的文档:
如果您使用systemPath更改条目的范围,依赖项的范围 - 编译,运行时,测试,系统和提供。用于计算用于编译,测试等的各种类路径。它还有助于确定要在此项目的分布中包含哪些工件。有关更多信息,请参阅依赖性机制。
也会在您的pom中出现错误:
只有系统范围的依赖项才能指定systemPath。
编辑2:找到了一个很好的解决方案......
我找到this 'issue' report,并按照上一条评论建议的路径:
我们不会这样做。我想你可以添加一个webresource部分,其中包含你想要的文件和targetPath。
Here's the documentation regarding the mechanism.
所以你需要做的是:
<build>
...
<plugins>
...
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.1.1</version>
<configuration>
<webResources>
<resource>
<directory>unmanaged-lib</directory>
<targetPath>WEB-INF/lib</targetPath>
<includes>
<include>**/*.jar</include>
</includes>
</resource>
</webResources>
</configuration>
</plugin>
...
<plugins>
...
<build>
注意:在这种情况下,路径'unmanaged-lib'是项目根目录中的目录(即与pom.xml一起使用)