While updating my project from JDK 8 to 17, I found that jersey-server 1.19.2 is not compatible with JDK 17. Therefore, I tried updating it to 2.43 (if I go beyond 2.x, I'll also have to update javax to jakarta). After migrating, I am getting a null value in ContextResolver. This was working fine with Java 8 and Jersey 1.
@Context
public void setMyProvider(ContextResolver<MyProducer> myProvider){
if(myProvider != null) // getting null value here
this.myProducer = myProvider.getContext(MyProducer.class);
}
Here are the changes I made when upgrading to Jersey 2.x:
Jersey1 pom dependencies
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-core</artifactId>
<version>1.19.2</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-json</artifactId>
<version>1.19.2</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-server</artifactId>
<version>1.19.2</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-servlet</artifactId>
<version>1.19.2</version>
</dependency>
Jersey2 Pom dependencies changes:
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet</artifactId>
<version>2.43</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
<version>2.43</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-server</artifactId>
<version>2.43</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.inject</groupId>
<artifactId>jersey-hk2</artifactId>
<version>2.43</version>
</dependency>
Jersey1 web.xml:
<servlet>
<servlet-name>Jersey Web Application</servlet-name>
<servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>com.patientkeeper.jerseydemo</param-value>
</init-param>
<init-param>
<param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
<param-value>true</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>Jersey Web Application</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
jersey2 web.xml changes:
<servlet>
<servlet-name>Jersey Web Application</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>com.example.jerseydemo</param-value>
</init-param>
<init-param>
<param-name>jersey.config.server.provider.classnames</param-name>
<param-value>org.glassfish.jersey.jackson.JacksonFeature</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Jersey Web Application</servlet-name>
<url-pattern>/api/*</url-pattern>
</servlet-mapping>
These are the provider and resource class[no change]
@Provider
public class TestProucer implements ContextResolver<MyProducer> {
public TestProucer(){
System.out.println("Test Producer working");
}
@Override
public MyProducer getContext(Class<?> aClass) {
return new MyProducer("this is a test");
}
}
@Path("/hello-world")
public class HelloResource {
private MyProducer myProducer;
@Context
public void setMyProvider(ContextResolver<MyProducer> myProvider2){
if(myProvider2 != null)
this.myProducer = myProvider2.getContext(MyProducer.class);
}
@GET
@Produces("text/plain")
public String hello() {
System.out.println(myProducer);
return "Hello, World!";
}
}
For the minimum working project where I can reproduce the issue, search for Jersery2DemoJDK17 on GitHub, as I am not able to post the link here.
some other specs: Java: 17 Jersey: 2.43 Tomcat server: 9 Maven: 3.8.8 IntelliJ: 2021.3.3 Ultimate
I also tried to register the provider differently by creating a ResourceConfig class:
public class ResourceApp extends ResourceConfig {
public ResourceApp() {
packages("com.example.jerseydemo2");
register(TestProucer.class);
register(JacksonFeature.class);
register(HelloResource.class);
}
}
and adding it to web.xml:
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>com.example.jerseydemo2.ResourceApp</param-value>
</init-param>
But I still got a null value for ContextResolver.
You need to inject Providers instead of directly injecting the ContextResolver:
public void setMyProvider(@Context Providers providers){
ContextResolver<MyProducer> myprovider = providers.getContextResolver(MyProducer.class, MediaType.WILDCARD_TYPE);
if(myProvider != null)
this.myProducer = myProvider.getContext(null);
}