Jersey compatibility with log4j2 - failing to start servlets - jersey

I'm having issues getting Jersey 1.19 to work with log4j2 on Tomcat7. My project's working assembly against log4j1 consists of the following:
slf4j-api: 1.5.6
slf4j-log4j12: 1.5.6
log4j: 1.2.14
I have a test project using log4j2 working successfully (logs are written to a file) with the following:
slf4j-api: 1.5.6
slf4j-log4j12: 1.5.6
log4j-1.2-api: 2.11.0
log4j-api: 2.11.0
log4j-core: 2.11.0
I am including log4j-1.2-api and the slf4j-log4j12 for the 'bridge' between log4j 1 and 2 per documentation, as there is legacy code I am unable to touch that uses log4j1.
As soon as I remove log4j 1.2.14 from my real project's assembly, and add in the bridge (log4j-1.2-api) and the api and core for log4j2, I run into the following exception when the the first HTTP request hits the server after startup. Reverting back to log4j1 resolves the issue.
My log4j2.xml file (which works on the test project) is located in the servlets /WEB-INF/classes folder. I've also tried it in the /WEB-INF folder.
asm.jar is 3.3.1 if that matters - I see it in the stacktrace.
Is there a compatibility issue I haven't read about getting these to play together?
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: Although Jersey 1.19.x can scan classes compiled with JDK 1.8, it fails on multi-release classes in META-INF/versions/9 compiled with JDK 9.
Remark: although this is an old question, even today there are some application using Jersey 1.19.x. Due to security problems they should upgrade to Log4j2 version 2.12.4 immediately if the run on Java 7 (which is itself a security risk) or the latest version if they run on Java 8+ (2.17.2 at the moment of writing). Since Jersey 1.19.x has no known security problems, its upgrade can be performed at a later time.
You have the same problem as in LOG4J2-3445: Log4j2 artifacts are multi-release, which means that most of the classes are compiled with Java 8 (supported by your old Jersey release), but some (in /META-INF/versions/9) are compiled with Java 9. The class scanner included in your Jersey version can not parse them.
You can try multiple workarounds:
Let Tomcat scan the classes instead of Jersey. This is available since Servlet 3.0 (Tomcat 7). To enable container annotation scanning in Jersey declare your servlet without a <servlet-class> parameter and a <servlet-name> equal to javax.ws.rs.core.Application:
<servlet>
<servlet-name>javax.ws.rs.core.Application</servlet-name>
</servlet>
This should also save up some startup time, since multiple Java EE technologies can profit of a single class scan.
If the workaround above does not solve your problem, you can restrict the paths scanned by Jersey using the com.sun.jersey.config.property.classpath servlet parameter (cf. javadoc). A setting of "/WEB-INF/classes" should be enough for most purposes.

Related

Log4j2 configuration location with JVM arguments for Web application that uses Spring Framework 5.2

I am upgrading log4j 1.2 to log4j 2.17.1 for a Spring Web application Servlet - 3.1 and Spring 5.2.2
1- The log4j2.xml file with all the configurations for Appenders etc is in a file outside the classpath(external file in the deployed server) - example - /tomcat/conf/log4j2.xml
Previously log4j was configured using this following JVM argument -
-Dlog4j.configuration = file:/opt/tomcat/conf/log4j.xml
I am just gonna change this to -
-Dlog4j.configuration = file:/opt/tomcat/conf/log4j2.xml
Question is, is this change enough for the new log4j2.xml to be used now. All the other stuff in the project is setup.
Do I need any more changes in web.xml etc, If I am already using this JVM argument ?

In spring-boot 2.6.2 Could not initialize Logback logging from classpath:logback-spring.groovy

I migrated my spring boot app for spring-boot 2.5.6 to spring-boot 2.6.2, but since then the start up tells
java.lang.IllegalStateException: Could not initialize Logback logging from classpath:logback-spring.groovyCaused by: ch.qos.logback.core.LogbackException:
Caused by: ch.qos.logback.core.LogbackException:Unexpected filename extension of file [file:/xyz/out/production/resources/logback-spring.groovy]. Should be either .groovy or .xml
Can someone help if you have a solution?
Thanks
Logback 1.2.9 dropped the support for Groovy.
You can either migrate your logback.groovy to logback.xml or downgrade the logback version to 1.2.7 (logback.version=1.2.7) and see if they’ll come around and support Groovy again (which they might).

Unable to deploy war to Tomcat

I get this error when deploying application war to the server:
12-Sep-2018 10:21:54.726 SEVERE [localhost-startStop-1] org.apache.catalina.startup.ContextConfig.processAnnotationsJar Unable to process Jar entry [module-info.class] from Jar [file:/xxx/apache-tomcat-8.0.41_xxxx/webapps/xxx/WEB-INF/lib/jaxb-api-2.3.0.jar] for annotations
org.apache.tomcat.util.bcel.classfile.ClassFormatException: Invalid byte tag in constant pool: 19
Informations:
Application is a micro-service created with Spring Boot
Java used is version 8
Tomcat version: tomcat-8.0.41
Thank you.
module-info.class is a module descriptor for Java’s module system that was introduced in Java 9. Some code in Tomcat 8.0 is unable to read the bytecode in that class file so deployment is failing.
I believe this is a limitation of Tomcat 8.0 that has been fixed in 8.5. Also note that an end-of-life announcement has been made for 8.0 so you should be planning to upgrade ASAP even without this problem.

UnsupportedClassVersion - JacksonAutoDiscoverable

I'm trying to use IBM Rational Application Developer version 9.0 with WebSphere Application Server v7.0 running Java 1.6 and use JAX-RS with org.glassfish.jersey version 2.6. This is not a maven project, so I created another maven project, added the root dependencies there and built it so it pulled down all of the jars. I moved them over into my non-maven project.
When I run the project, I start the server (or try to hit a resource) I get the following error message: java.lang.UnsupportedClassVersionError: JVMCFRE003 bad major version; class=org/glassfish/jersey/jackson/internal/JacksonAutoDiscoverable, offset=6
I have a different application that successfully uses jersey deployed WAS7 on this same machine. I've compared the project and server configurations and see no major difference, particularly no difference in the Installed JRE", Execution Environments or Java Compiler Compliance Level (all using 1.6).
Even though the maven project is using jersey 2.6, I have also tried other lower jersey versions in the non-maven project to see if it's an issue with the dependencies being built for 1.7 but that doesn't seem to be the case at all.
Here is the list of dependencies I have in my library:
aopalliance-repackaged-2.2.0.jar
hk2-api-2.2.0.jar
hk2-locator-2.2.0.jar
hk2-utils-2.2.0.jar
jackson-core-asl-1.9.13.jar
jackson-jaxrs-1.9.13.jar
jackson-mapper-asl-1.9.13.jar
jackson-xc-1.9.13.jar
javassist-3.18.1-GA.jar
javax.annotation-api-1.2.jar
javax.inject-2.2.0.jar
javax.ws.rs-api-2.0.jar
jersey-client-2.6.jar
jersey-common-2.6.jar
jersey-container-servlet-core-2.6.jar
jersey-guava-2.6.jar
jersey-media-json-jackson-2.6.jar
jersey-server-2.6.jar
osgi-resource-locator-1.0.1.jar
validation-api-1.1.0.Final.jar

Grails 1.2.1 with Spring 3.0.0 dependency problem under Jetty

Just moved to Grails 1.2.1 (used 1.1.1 before). Changed application.properties, ran grails upgrade, fixed BuildConfig and Bootstrap - everything works just fine from grails console.
However, getting a problem when deploy packaged war under jetty 6.1.22:
1581 [main] ERROR org.springframework.web.context.ContextLoader - Context initialization failed org.springframework.beans.factory.access.BootstrapException: Error executing bootstraps; nested exception is java.lang.NoSuchMethodError: org.codehaus.groovy.grails.commons.spring.ReloadAwareAutowireCapableBeanFactory.setParameterNameDiscoverer(Lorg/springframework/core/ParameterNameDiscoverer;)V
My project is built with maven2. I researched the war dependencies and see that both spring 2.5.6 and 3.0.0.RELEASE are used there.
I then tried to suppress use of spring 2.5.6 and got a problem with Acegi plugin (using version 0.5.1):
2010-03-10 21:06:56.440:WARN::Nested in org.springframework.beans.factory.access.BootstrapException: Error executing bootstraps; nested exception is java.lang.NoSuchMethodError: org.springframework.web.context.ConfigurableWebApplicationContext.setId(Ljava/lang/String;)V
Any help would be greatly appreciated.
The problem is caused by the fact that in new version of Spring
ConfigurableWebApplicationContext is located in spring-web.jar, but the interface it inherits ConfigurableApplicationContext, which contains setId(String) method is in located in spring-context.jar.
If you have a library which has been compiled against older version of spring-context it will fail with NoMethodFound exception.
The solution is to locate and recompile that library against latest Spring version.
If you are using Spring version below 3.0 you could try to put full Spring bundle Jar instead of separate packages.

Resources