我在 Tomcat7 上使用 Jersey 1.19 与 log4j2 时遇到问题。我的项目针对 log4j1 的工作程序集包含以下内容:
- slf4j-api:1.5.6
- slf4j-log4j12:1.5.6
- log4j:1.2.14
我有一个使用 log4j2 的测试项目成功运行(日志写入文件),内容如下:
- slf4j-api:1.5.6
- slf4j-log4j12:1.5.6
- log4j-1.2-api:2.11.0
- log4j-api:2.11.0
- log4j-核心:2.11.0
我在每个文档中都包含了 log4j-1.2-api 和 slf4j-log4j12 作为 log4j 1 和 2 之间的“桥梁”,因为我无法触及使用 log4j1 的遗留代码。
一旦我从真实项目的程序集中删除 log4j 1.2.14,并添加桥 (log4j-1.2-api) 以及 log4j2 的 api 和核心,当第一个 HTTP 请求到达服务器时,我就会遇到以下异常启动后。恢复到 log4j1 可以解决该问题。
我的 log4j2.xml 文件(适用于测试项目)位于 servlets /WEB-INF/classes 文件夹中。我也在/WEB-INF文件夹中尝试过。
如果这很重要的话,asm.jar 是 3.3.1 - 我在堆栈跟踪中看到它。
是否存在我还没有读到的关于让这些一起玩的兼容性问题?
java.lang.IllegalArgumentException
jersey.repackaged.org.objectweb.asm.ClassReader.<init>(ClassReader.java:170)
jersey.repackaged.org.objectweb.asm.ClassReader.<init>(ClassReader.java:153)
jersey.repackaged.org.objectweb.asm.ClassReader.<init>(ClassReader.java:424)
com.sun.jersey.spi.scanning.AnnotationScannerListener.onProcess(AnnotationScannerListener.java:138)
com.sun.jersey.core.spi.scanning.JarFileScanner.scan(JarFileScanner.java:97)
com.sun.jersey.spi.scanning.servlet.WebAppResourcesScanner$1.f(WebAppResourcesScanner.java:94)
com.sun.jersey.core.util.Closing.f(Closing.java:71)
com.sun.jersey.spi.scanning.servlet.WebAppResourcesScanner.scan(WebAppResourcesScanner.java:92)
com.sun.jersey.spi.scanning.servlet.WebAppResourcesScanner.scan(WebAppResourcesScanner.java:79)
com.sun.jersey.api.core.ScanningResourceConfig.init(ScanningResourceConfig.java:80)
com.sun.jersey.api.core.servlet.WebAppResourceConfig.init(WebAppResourceConfig.java:102)
com.sun.jersey.api.core.servlet.WebAppResourceConfig.<init>(WebAppResourceConfig.java:89)
com.sun.jersey.api.core.servlet.WebAppResourceConfig.<init>(WebAppResourceConfig.java:74)
com.sun.jersey.spi.container.servlet.WebComponent.getWebAppResourceConfig(WebComponent.java:668)
com.sun.jersey.spi.container.servlet.ServletContainer.getDefaultResourceConfig(ServletContainer.java:435)
com.sun.jersey.spi.container.servlet.ServletContainer.getDefaultResourceConfig(ServletContainer.java:602)
com.sun.jersey.spi.container.servlet.WebServletConfig.getDefaultResourceConfig(WebServletConfig.java:87)
com.sun.jersey.spi.container.servlet.WebComponent.createResourceConfig(WebComponent.java:699)
com.sun.jersey.spi.container.servlet.WebComponent.createResourceConfig(WebComponent.java:674)
com.sun.jersey.spi.container.servlet.WebComponent.init(WebComponent.java:205)
com.sun.jersey.spi.container.servlet.ServletContainer.init(ServletContainer.java:394)
com.sun.jersey.spi.container.servlet.ServletContainer.init(ServletContainer.java:577)
javax.servlet.GenericServlet.init(GenericServlet.java:158)
org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:506)
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:962)
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:445)
org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1115)
org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:637)
org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.doRun(AprEndpoint.java:2549)
org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.run(AprEndpoint.java:2538)
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
java.lang.Thread.run(Thread.java:748)
TL;DR:虽然 Jersey 1.19.x 可以扫描使用 JDK 1.8 编译的类,但它无法扫描META-INF/versions/9
使用 JDK 9 编译。
Remark:虽然这是一个老问题,但即使在今天也有一些应用程序使用 Jersey 1.19.x。由于安全问题,他们应该升级到 Log4j2 版本2.12.4
如果在 Java 7 上运行(这本身就是一个安全风险),则立即更新;如果在 Java 8+ 上运行,则立即更新最新版本(2.17.2
在撰写本文时)。由于 Jersey 1.19.x 没有已知的安全问题,因此可以稍后进行升级。
你有同样的问题LOG4J2-3445 https://issues.apache.org/jira/browse/LOG4J2-3445:Log4j2 工件是多版本的,这意味着大多数类都是用 Java 8 编译的(受旧 Jersey 版本支持),但有些类(在/META-INF/versions/9
)是用 Java 9 编译的。Jersey 版本中包含的类扫描器无法解析它们。
您可以尝试多种解决方法:
- 让 Tomcat 代替 Jersey 扫描类。从 Servlet 3.0 (Tomcat 7) 开始可用。要在 Jersey 中启用容器注释扫描,请声明您的 servlet,无需使用
<servlet-class>
参数和一个<servlet-name>
等于javax.ws.rs.core.Application
:
<servlet>
<servlet-name>javax.ws.rs.core.Application</servlet-name>
</servlet>
这还应该节省一些启动时间,因为多种 Java EE 技术可以从单个类扫描中获益。
- 如果上述解决方法不能解决您的问题,您可以使用以下命令限制 Jersey 扫描的路径
com.sun.jersey.config.property.classpath
servlet 参数(参见javadoc https://www.javadoc.io/doc/com.sun.jersey/jersey-servlet/latest/com/sun/jersey/spi/container/servlet/ServletContainer.html)。 “/WEB-INF/classes”的设置对于大多数用途来说应该足够了。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)