eclipse-ee4j / eclipse-ee4j/jersey
Context injection doesn't work for registered bean proxied instance
- Dominant language
- Java
- Stars
- 730
- Forks
- 382
- PR merge metrics
- No merged PRs in 30d
Description
Similar to #3398 / #2443"), context injection in an advised instance does not work.
This test has been created in the jersey-spring3 sub-project ([https://github.com/jersey/jersey/tree/2.x/ext/spring3](https://github.com/jersey/jersey/tree/2.x/ext/spring3)).
The fix of #3398 don't work, the new code is not even invoked. In this case, notice in the below example the .register(context.getBean(JaxRsResource.class)) that illustrate programatic registration of resources, typically actual code (that work for non advised bean) looks like :
```
webApplicationContext.getBeansWithAnnotation(ThisKindOfService.class)
.forEach((name, resource) -> register(resource));
```
Also notice in the below example that JaxRsResource.class is an interface that is shareable.
```
package org.glassfish.jersey.server.spring.proxies;
import javax.inject.Provider;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Application;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.UriInfo;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import org.glassfish.jersey.logging.LoggingFeature;
import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.server.spring.scope.RequestContextFilter;
import org.glassfish.jersey.test.JerseyTest;
import org.junit.Assert;
import org.junit.Test;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.concurrent.ConcurrentMapCache;
import org.springframework.cache.support.SimpleCacheManager;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Service;
import static java.util.Collections.singletonList;
public class SpringWithProxiesResourceTest extends JerseyTest {
@Override
protected Application configure() {
ApplicationContext context = new AnnotationConfigApplicationContext(SpringWithProxyConfiguration.class);
return new ResourceConfig()
.register(RequestContextFilter.class)
.register(LoggingFeature.class)
.register(context.getBean(JaxRsResource.class))
.property("contextConfig", context);
}
@Test
public void shouldUseDefaultComponent() {
final String result = target("spring-resource").request().get(String.class);
Assert.assertEquals("spring-resource", result);
}
@Configuration
@EnableCaching
public static class SpringWithProxyConfiguration {
@Bean
public JaxRsResource jaxRsResource() {
return new SpringWithProxiesResourceImpl();
}
@Bean
public CacheManager cacheManager() {
SimpleCacheManager cm = new SimpleCacheManager();
cm.setCaches(singletonList(new ConcurrentMapCache("default")));
return cm;
}
}
@Service
public static class SpringWithProxiesResourceImpl implements JaxRsResource {
@Context
Provider uriInfoProvider;
@Context
private UriInfo uriInfo;
@Cacheable("default")
@Override
public String doSomething() {
return uriInfo.getPath();
}
}
@Path("spring-resource")
public interface JaxRsResource {
@GET
@Produces(MediaType.TEXT_PLAIN)
String doSomething();
}
}
```
The issue is that the extension is not even used in this situation. The applicationHandler invokes directly locator.inject(instance), and this doesn't work as this code doesn't perform the unwrapping necessary for spring proxies. This part of the code doesn't even provide an extension mechanism.
Relevant code : [https://github.com/jersey/jersey/blob/2.x/core-server/src/main/java/org/glassfish/jersey/server/ApplicationHandler.java#L615-L621](https://github.com/jersey/jersey/blob/2.x/core-server/src/main/java/org/glassfish/jersey/server/ApplicationHandler.java#L615-L621)
Having a way to tell Jersey to inject in the advised bean could solve the issue
```
locator.inject(((Advised) instance).getTargetSource().getTarget())
```
#### Environment
Java 8
Spring 3/4
#### Affected Versions
[2.24.1]
Contributor guide
Assessment
This issue has not been assessed yet.