我正在开发一个新项目并尝试首次使用Gradle。该应用程序是一个Web应用程序,因此我在war
的顶部配置了jetty
和gradle.build
个插件:
apply plugin: 'war'
apply plugin: 'jetty'
在我的代码中,我编程到Apache Commons Logging API进行日志记录。我的一个依赖项(OpenSAML)使用SLF4J API进行日志记录。对于实际的日志记录配置,我最熟悉log4j 1.2,因此我想用它来实际执行日志记录。
要配置这些依赖项,我在gradle.build
文件中有以下内容:
// Logging API
compile group: 'org.slf4j', name: 'slf4j-api', version: '1.7.21'
compile group: 'org.slf4j', name: 'jcl-over-slf4j', version: '1.7.21'
// Logging at runtime
runtime group: 'org.slf4j', name: 'slf4j-log4j12', version: '1.7.21'
runtime group: 'log4j', name: 'log4j', version: '1.2.17'
当我使用命令gradle jettyRunWar
运行我的应用程序并且servlet执行尝试记录某些内容时,我收到以下错误:
java.lang.ExceptionInInitializerError
at org.slf4j.impl.StaticLoggerBinder.<init>(StaticLoggerBinder.java:72)
at org.slf4j.impl.StaticLoggerBinder.<clinit>(StaticLoggerBinder.java:45)
at org.slf4j.LoggerFactory.bind(LoggerFactory.java:150)
at org.slf4j.LoggerFactory.performInitialization(LoggerFactory.java:124)
at org.slf4j.LoggerFactory.getILoggerFactory(LoggerFactory.java:412)
at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:357)
at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:383)
at sso.HomePageServlet.<clinit>(HomePageServlet.java:23)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:422)
at java.lang.Class.newInstance(Class.java:442)
at org.mortbay.jetty.servlet.Holder.newInstance(Holder.java:153)
at org.mortbay.jetty.servlet.ServletHolder.initServlet(ServletHolder.java:428)
at org.mortbay.jetty.servlet.ServletHolder.getServlet(ServletHolder.java:339)
at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:487)
at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:390)
at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:182)
at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765)
at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:440)
at org.mortbay.jetty.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:230)
at org.mortbay.jetty.handler.HandlerCollection.handle(HandlerCollection.java:114)
at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
at org.mortbay.jetty.Server.handle(Server.java:326)
at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:542)
at org.mortbay.jetty.HttpConnection$RequestHandler.headerComplete(HttpConnection.java:926)
at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:549)
at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:212)
at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)
at org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:410)
at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:582)
Caused by: java.lang.IllegalStateException: Detected both log4j-over-slf4j.jar AND bound slf4j-log4j12.jar on the class path, preempting StackOverflowError. See also http://www.slf4j.org/codes.html#log4jDelegationLoop for more details.
at org.slf4j.impl.Log4jLoggerFactory.<clinit>(Log4jLoggerFactory.java:54)
... 33 more
错误显然是log4j-over-slf4j.jar
也在类路径中。我的申请没有列出这个。使用gradle dependencies --configuration runtime
也不会列出此.jar文件。此.jar存在的唯一位置是gradle\lib
目录。启动Jetty时,Gradle是否可能包含自己的类路径?
有没有办法阻止这种情况?
概述here的解决方案似乎不起作用。
gradle -v
显示:
------------------------------------------------------------
Gradle 2.14.1
------------------------------------------------------------
Build time: 2016-07-18 06:38:37 UTC
Revision: d9e2113d9fb05a5caabba61798bdb8dfdca83719
Groovy: 2.4.4
Ant: Apache Ant(TM) version 1.9.6 compiled on June 29 2015
JVM: 1.8.0_45 (Oracle Corporation 25.45-b02)
OS: Windows 7 6.1 amd64
答案 0 :(得分:4)
在发布我的问题后,我看到Gradle 3.0已被释放。在发行说明中,它表示已弃用jetty
插件,并且应使用Gretty
。
升级到Gradle 3.0并切换到使用Gretty
解决了问题。
jetty
插件在您的网络应用中包含Gradle的类路径这一事实&#39;运行时路径是jetty
插件工作方式的问题,看起来它不会被修复。
答案 1 :(得分:0)
我知道这已经几年了,版本太晚了,但是为了完全关闭,我确认内部gradle日志正在干扰。我的日志包括以下内容:
SLF4J: Found binding in [jar:file:/**/.gradle/**/gradle-2.14.1/lib/gradle-logging-2.14.1.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/**/build/tmp/jettyRunWar/webapp/WEB-INF/lib/slf4j-log4j12-1.7.25.jar!/org/slf4j/impl/StaticLoggerBinder.class]
gradle-logging-2.14.1.jar 包含有问题的 org.apache.log4j.Log4jLoggerFactory 类。
由于我们要处理的是遗留的整体式多项目构建,因此我们还没有准备好提高gradle版本的安全性(一个人就好了)。当依赖项 slf4j-log4j12 从版本 1.7.2 更新到 1.7.25 时,我们遇到了这个问题(我们做得还不够好)单独)。对于我们来说,解决方案是在添加检查之前将其降低到版本 1.7.13 。