Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Injection error when using a DynamicFeature #5618

Closed
zUniQueX opened this issue Apr 20, 2024 · 3 comments · Fixed by #5624
Closed

Injection error when using a DynamicFeature #5618

zUniQueX opened this issue Apr 20, 2024 · 3 comments · Fixed by #5624

Comments

@zUniQueX
Copy link
Contributor

Recently we have received an issue at dropwizard with a strange behavior regarding Jersey dependency injection. I've now reproduced this issue with Jersey-related classes only to exclude a dropwizard issue. The problem can be observed with the following ContainerRequestFilter:

public static class InjectedFilter implements ContainerRequestFilter {
    @Inject
    private InjectionManager injectionManager;
    @Override
    public void filter(ContainerRequestContext requestContext) throws IOException {
        Ref<HttpServletRequest> requestRef = injectionManager.getInstance((new GenericType<Ref<HttpServletRequest>>() {}).getType());
        if (requestRef == null || requestRef.get() == null) {
            throw new IllegalStateException("Request not injected");
        }
    }
}

When registering this filter directly to the ResourceConfig as a Class like resourceConfig.register(InjectedFilter.class) the filter works fine and the Ref<HttpServletRequest> holds the current request.

However, when registering this filter through the FeatureContext of a DynamicFeature, HK2 throws an exception:

MultiException stack 1 of 2
java.lang.IllegalStateException: There is more than one active context for org.glassfish.jersey.process.internal.RequestScoped
	at org.jvnet.hk2.internal.ServiceLocatorImpl._resolveContext(ServiceLocatorImpl.java:2222)
...
MultiException stack 2 of 2
java.lang.IllegalStateException: While attempting to create a service for SystemDescriptor(
	implementation=org.glassfish.jersey.inject.hk2.InstanceSupplierFactoryBridge
	contracts={org.glassfish.jersey.internal.util.collection.Ref}
	scope=org.glassfish.jersey.process.internal.RequestScoped
	qualifiers={}
	descriptorType=PROVIDE_METHOD
	descriptorVisibility=NORMAL
	metadata=
	rank=0
	loader=org.glassfish.hk2.utilities.binding.AbstractBinder$2@6e59af3d
	proxiable=null
	proxyForSameScope=null
	analysisName=null
	id=23
	locatorId=0
	identityHashCode=239875089
	reified=true) in scope org.glassfish.jersey.process.internal.RequestScoped an error occured while locating the context
	at org.jvnet.hk2.internal.Utilities.createService(Utilities.java:2093)

Here is a Jersey test case to reproduce the behavior:

public class InjectionTest extends JerseyTest {
    @Path("hello")
    public static class HelloResource {
        @GET
        public String getHello() {
            return "Hello World!";
        }
    }
    @Override
    protected Application configure() {
        ResourceConfig resourceConfig = new ResourceConfig(HelloResource.class);
        resourceConfig.register(new InjectedFilterRegistrar(InjectedFilter.class));
        return resourceConfig;
    }
    @Override
    protected TestContainerFactory getTestContainerFactory() throws TestContainerException {
        return new JettyTestContainerFactory();
    }
    @Test
    public void test() {
        final String hello = target("hello").request().get(String.class);
        assertEquals("Hello World!", hello);
    }
    public static class InjectedFilter implements ContainerRequestFilter {
        @Inject
        private InjectionManager injectionManager;
        @Override
        public void filter(ContainerRequestContext requestContext) throws IOException {
            Ref<HttpServletRequest> requestRef = injectionManager.getInstance((new GenericType<Ref<HttpServletRequest>>() {}).getType());
            if (requestRef == null || requestRef.get() == null) {
                throw new IllegalStateException("Request not injected");
            }
        }
    }
    public static class InjectedFilterRegistrar implements DynamicFeature {
        private final Class<?> filterToRegister;
        public InjectedFilterRegistrar(Class<?> filterToRegister) {
            this.filterToRegister = filterToRegister;
        }
        @Override
        public void configure(ResourceInfo resourceInfo, FeatureContext context) {
            context.register(filterToRegister);
        }
    }
}
@jansupol
Copy link
Contributor

It looks like it used to be working fine on DropWizard 4.0.1 but it does not in 4.0.6. What Jersey versions are there?

@zUniQueX
Copy link
Contributor Author

Hi @jansupol. Dropwizard 4.0.1 works fine because the aforementioned filter was firstly introduced in Dropwizard 4.0.3 (which uses Jersey 3.0.11).

The current Dropwizard version 4.0.7 uses Jersey 3.0.12.

@jansupol
Copy link
Contributor

@zUniQueX We will fix this. But beware of the InjectedFilterRegistrar being invoked for each endpoint method, including the synthetic ones (for HTTP OPTIONS for instance).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants