Jersey multiple provider instances for multiple provider interfaces; again?
Conrad-T-Pino opened this issue · comments
I'm suggesting not fixed in Jersey 2.35 nor 2.44. I'm logging in no argument constructor and see four (4) log entries; one for each implemented Contract.class for the first request but not thereafter.
Ideally I wanted singleton state as class field in singleton instance. Logs suggest I must use static field to circumvent multiple instances.
public class ClientCapture implements
ClientRequestFilter, ClientResponseFilter, ReaderInterceptor, WriterInterceptor {
public ClientCapture() {
super();
logger.info("ClientCapture()");
}
...
}
25-Aug-2024 15:02:24.978 INFO [pool-6-thread-1] tmms.rest.ClientCapture.<init> ClientCapture()
25-Aug-2024 15:02:24.978 INFO [pool-6-thread-1] tmms.rest.ClientCapture.<init> ClientCapture()
25-Aug-2024 15:02:24.982 INFO [pool-6-thread-1] tmms.rest.ClientCapture.<init> ClientCapture()
25-Aug-2024 15:02:24.983 INFO [pool-6-thread-1] tmms.rest.ClientCapture.<init> ClientCapture()
25-Aug-2024 15:02:25.078 INFO [pool-6-thread-1] tmms.rest.ClientCapture.filter (ClientRequestContext)
25-Aug-2024 15:02:25.090 INFO [pool-6-thread-1] tmms.rest.ClientCapture.aroundWriteTo (WriterInterceptorContext)
25-Aug-2024 15:02:25.785 INFO [pool-6-thread-1] tmms.rest.ClientCapture.filter (ClientRequestContext, ClientResponseContext)
25-Aug-2024 15:02:25.790 INFO [pool-6-thread-1] tmms.rest.ClientCapture.aroundReadFrom (ReaderInterceptorContext)
Originally posted by @Conrad-T-Pino in #3888 (comment) and #3796
@Conrad-T-Pino What Injection module do you use? jersey-cdi2-se
or jersey-hk2
?
Again, context matters:
- Container: time constraints require using existing Tomcat 9 installation
- Specification: Servlet 4.0, JSP 2.3, EL 3.0, Java EE 8, CDI 2.0, JPA 2.2, JSF 2.3
- User: experienced Tomcat webapp developer doing first JAX-RS (Jersey) application
- Application: reverse proxy complex rate limiting Telnyx JSON API into trivial GET API
- Telnyx: client Java SDK doesn't expose response headers but does expose JAX-RS Client
Objective is capture Telnyx client response headers:
final com.telnyx.sdk.ApiClient apiClient = com.telnyx.sdk.Configuration.getDefaultApiClient();
final javax.ws.rs.client.Client httpClient = apiClient.getHttpClient();
httpClient.register(tmms.rest.ClientCapture.class);
@jansupol ClientCapture
class is NOT annotated and ignored by org.glassfish.jersey.servlet.ServletContainer
@jansupol jersey-hk2
is in play. Redacted pom.xml
follows:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>tmms.rest</groupId>
<artifactId>tmms</artifactId>
<version>0.0.0-dev</version>
<packaging>war</packaging>
<name>tmms</name>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<telnyx.version>3.6.1</telnyx.version>
<jersey.version>2.44</jersey.version>
<webapp.lib>${project.build.directory}/${project.build.finalName}/WEB-INF/lib</webapp.lib>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.glassfish.jersey</groupId>
<artifactId>jersey-bom</artifactId>
<version>${jersey.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>jakarta.servlet</groupId>
<artifactId>jakarta.servlet-api</artifactId>
<version>4.0.4</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet</artifactId>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.inject</groupId>
<artifactId>jersey-hk2</artifactId>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.ext</groupId>
<artifactId>jersey-bean-validation</artifactId>
</dependency>
<dependency>
<groupId>com.telnyx.sdk</groupId>
<artifactId>telnyx</artifactId>
<version>${telnyx.version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<finalName>tmms</finalName>
<pluginManagement>
<plugins>
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>3.1.0</version>
</plugin>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.0.2</version>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.1</version>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>3.2.2</version>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
To verify container provider behavior I restacked my classes:
//@Provider
public class Interceptors implements ReaderInterceptor, WriterInterceptor {
public Interceptors() {
super();
logger.info("Interceptors()");
}
...
}
//@Provider
public class ClientCapture extends Interceptors implements ClientRequestFilter, ClientResponseFilter {
public ClientCapture() {
super();
logger.info("ClientCapture()");
}
...
}
@Provider
public class ContainerCapture extends Interceptors implements ContainerRequestFilter, ContainerResponseFilter {
public ContainerCapture() {
super();
logger.info("ContainerCapture()");
}
...
}
The client constructors log as expected:
26-Aug-2024 14:19:37.349 INFO [pool-6-thread-1] tmms.rest.Interceptors.<init> Interceptors()
26-Aug-2024 14:19:37.349 INFO [pool-6-thread-1] tmms.rest.ClientCapture.<init> ClientCapture()
26-Aug-2024 14:19:37.350 INFO [pool-6-thread-1] tmms.rest.Interceptors.<init> Interceptors()
26-Aug-2024 14:19:37.350 INFO [pool-6-thread-1] tmms.rest.ClientCapture.<init> ClientCapture()
26-Aug-2024 14:19:37.354 INFO [pool-6-thread-1] tmms.rest.Interceptors.<init> Interceptors()
26-Aug-2024 14:19:37.354 INFO [pool-6-thread-1] tmms.rest.ClientCapture.<init> ClientCapture()
26-Aug-2024 14:19:37.355 INFO [pool-6-thread-1] tmms.rest.Interceptors.<init> Interceptors()
26-Aug-2024 14:19:37.355 INFO [pool-6-thread-1] tmms.rest.ClientCapture.<init> ClientCapture()
26-Aug-2024 14:19:37.449 INFO [pool-6-thread-1] tmms.rest.ClientCapture.filter (ClientRequestContext):
26-Aug-2024 14:19:37.462 INFO [pool-6-thread-1] tmms.rest.Interceptors.aroundWriteTo (WriterInterceptorContext):
26-Aug-2024 14:19:38.339 INFO [pool-6-thread-1] tmms.rest.ClientCapture.filter (ClientRequestContext, ClientResponseContext):
26-Aug-2024 14:19:38.344 INFO [pool-6-thread-1] tmms.rest.Interceptors.aroundReadFrom (ReaderInterceptorContext):
The container constructors are silent in all cases:
26-Aug-2024 14:51:04.756 INFO [catalina-exec-1] tmms.rest.ContainerCapture.filter (ContainerRequestContext):
26-Aug-2024 14:51:05.051 INFO [catalina-exec-1] tmms.rest.ContainerCapture.filter (ContainerRequestContext, ContainerResponseContext):
26-Aug-2024 14:51:05.057 INFO [catalina-exec-1] tmms.rest.Interceptors.aroundWriteTo (WriterInterceptorContext):
26-Aug-2024 14:51:06.390 INFO [catalina-exec-4] tmms.rest.ContainerCapture.filter (ContainerRequestContext):
26-Aug-2024 14:51:06.392 INFO [catalina-exec-4] tmms.rest.Interceptors.aroundReadFrom (ReaderInterceptorContext):
26-Aug-2024 14:51:07.020 INFO [catalina-exec-2] tmms.rest.ContainerCapture.filter (ContainerRequestContext):
26-Aug-2024 14:51:07.022 INFO [catalina-exec-2] tmms.rest.Interceptors.aroundReadFrom (ReaderInterceptorContext):
- Thread 1 is request from our test client.
- Threads 4 & 2 are Telnyx webhook updates.