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

@Context injection when CDI is enabled and @DisableDiscovery is specified does not work #4493

Closed
aivarhe opened this issue Jul 8, 2022 · 6 comments
Assignees
Labels
cdi CDI jax-rs JAX-RS and Jersey related issues P2 testing
Projects

Comments

@aivarhe
Copy link

aivarhe commented Jul 8, 2022

Environment Details

  • Helidon Version: 2.5.0
  • Helidon MP
  • JDK version: 11.0.12
  • OS: Windows 10
  • Docker version (if applicable):

Problem Description

Injecting UriInfo with @context in an ExceptionMapper works when the Helidon application is running but when running unit test cases for the ExceptionMapper with @HelidonTest, the UriInfo does not get injected. Our test classes have @DisableDiscovery and CDI extensions included.

Steps to reproduce

Use attached reproducible project to recreate the issue. When running the application, http://localhost:8080/greet/boom will trigger the exception and the UriInfo in the ExceptionMapper will be injected, when the same scenario is run from the test, UriInfo is not injected
UriInfoReproducible.zip

@github-actions github-actions bot added this to Triage in Backlog Jul 8, 2022
@aivarhe
Copy link
Author

aivarhe commented Jul 8, 2022

Injecting HttpHeaders in ExceptionMapper also does not work properly when running test with @HelidonTest, @DisableDiscovery and CDI extensions included, in particular case the the HttpHeaders are injected but when calling getRequestHeaders() an exception is thrown(see below). Injecting HttpHeaders in ExceptionMapper works properly when application in running.

2022.07.08 14:32:43.531 SEVERE org.glassfish.jersey.server.ServerRuntime$Responder Thread[helidon-1,5,server]: An exception has been thrown from an exception mapper class com.test.exception.ResourceNotFoundExceptionMapper$Proxy$_$$_WeldClientProxy.
java.lang.IllegalStateException: Not inside a request scope.
	at org.glassfish.jersey.internal.guava.Preconditions.checkState(Preconditions.java:169)
	at org.glassfish.jersey.process.internal.RequestScope.current(RequestScope.java:153)
	at org.glassfish.jersey.inject.hk2.RequestContext.findOrCreate(RequestContext.java:55)
	at org.jvnet.hk2.internal.MethodInterceptorImpl.internalInvoke(MethodInterceptorImpl.java:65)
	at org.jvnet.hk2.internal.MethodInterceptorImpl.invoke(MethodInterceptorImpl.java:101)
	at org.jvnet.hk2.internal.MethodInterceptorInvocationHandler.invoke(MethodInterceptorInvocationHandler.java:39)
	at com.sun.proxy.$Proxy110.getRequestHeaders(Unknown Source)
	at com.test.exception.ResourceNotFoundExceptionMapper.toResponse(ResourceNotFoundExceptionMapper.java:41)
	at com.test.exception.ResourceNotFoundExceptionMapper.toResponse(ResourceNotFoundExceptionMapper.java:1)
	at com.test.exception.ResourceNotFoundExceptionMapper$Proxy$_$$_WeldClientProxy.toResponse(Unknown Source)
	at org.glassfish.jersey.server.ServerRuntime$Responder.mapException(ServerRuntime.java:528)
	at org.glassfish.jersey.server.ServerRuntime$Responder.process(ServerRuntime.java:405)
	at org.glassfish.jersey.server.ServerRuntime$AsyncResponder$4.run(ServerRuntime.java:872)
	at org.glassfish.jersey.internal.Errors$1.call(Errors.java:248)
	at org.glassfish.jersey.internal.Errors$1.call(Errors.java:244)
	at org.glassfish.jersey.internal.Errors.process(Errors.java:292)
	at org.glassfish.jersey.internal.Errors.process(Errors.java:274)
	at org.glassfish.jersey.internal.Errors.process(Errors.java:244)
	at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:265)
	at org.glassfish.jersey.server.ServerRuntime$AsyncResponder.resume(ServerRuntime.java:889)
	at org.glassfish.jersey.server.ServerRuntime$AsyncResponder.resume(ServerRuntime.java:867)
	at com.test.resource.AppResource.lambda$4(AppResource.java:176)
	at java.base/java.util.concurrent.CompletableFuture.uniHandle(CompletableFuture.java:930)
	at java.base/java.util.concurrent.CompletableFuture.uniHandleStage(CompletableFuture.java:946)
	at java.base/java.util.concurrent.CompletableFuture.handle(CompletableFuture.java:2266)
	at java.base/java.util.concurrent.CompletableFuture.handle(CompletableFuture.java:143)
	at com.test.resource.AppResource.getResource(AppResource.java:172)
	at com.test.resource.AppResourceTest$ApplicationScopedAppResource$Proxy$_$$_WeldClientProxy.getResource(Unknown Source)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
	at org.glassfish.jersey.server.model.internal.ResourceMethodInvocationHandlerFactory.lambda$static$0(ResourceMethodInvocationHandlerFactory.java:52)
	at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher$1.run(AbstractJavaResourceMethodDispatcher.java:124)
	at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.invoke(AbstractJavaResourceMethodDispatcher.java:167)
	at org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$VoidOutInvoker.doDispatch(JavaResourceMethodDispatcherProvider.java:159)
	at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.dispatch(AbstractJavaResourceMethodDispatcher.java:79)
	at org.glassfish.jersey.server.model.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:475)
	at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:397)
	at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:81)
	at org.glassfish.jersey.server.ServerRuntime$1.run(ServerRuntime.java:255)
	at org.glassfish.jersey.internal.Errors$1.call(Errors.java:248)
	at org.glassfish.jersey.internal.Errors$1.call(Errors.java:244)
	at org.glassfish.jersey.internal.Errors.process(Errors.java:292)
	at org.glassfish.jersey.internal.Errors.process(Errors.java:274)
	at org.glassfish.jersey.internal.Errors.process(Errors.java:244)
	at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:265)
	at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:234)
	at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:684)
	at io.helidon.webserver.jersey.JerseySupport$JerseyHandler.lambda$doAccept$4(JerseySupport.java:327)
	at io.helidon.common.context.Contexts.runInContext(Contexts.java:117)
	at io.helidon.common.context.ContextAwareExecutorImpl.lambda$wrap$7(ContextAwareExecutorImpl.java:154)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
	at java.base/java.lang.Thread.run(Thread.java:834)

@spericas spericas added the bug Something isn't working label Jul 8, 2022
@spericas
Copy link
Member

spericas commented Jul 8, 2022

I have verified that this is indeed the case. For some reason, the bean is known to CDI (via @AddBean), but Jersey does not perform @Context injection into it unless CDI discovery is enabled.

@spericas spericas added cdi CDI testing jax-rs JAX-RS and Jersey related issues labels Jul 8, 2022
@ljnelson
Copy link
Member

ljnelson commented Jul 8, 2022

(My blind guess here is that some Jersey-to-CDI integration nugget is not added via @AddExtension. Disabling discovery also prevents portable extensions from being loaded, wherever they might be found.)

@spericas
Copy link
Member

@ljnelson Test adds a few extensions by hand, but perhaps the list is incomplete, not sure. Regular @Context injection seems work fine.

@m0mus m0mus added the P2 label Jul 21, 2022
@m0mus m0mus moved this from Triage to High priority in Backlog Jul 21, 2022
@tomas-langer
Copy link
Member

tomas-langer commented Jul 28, 2022

The problem came from the exception mapper beeing registered twice - once through CDI as a bean (@AddBean annotation) and second time from JAX-RS. As the CDI bean was already created, JAX-RS did not inject it.
To make this work, please change your test class annotations to:

@HelidonTest(resetPerTest = true)
@DisableDiscovery
@AddExtension(ServerCdiExtension.class)
@AddExtension(JaxRsCdiExtension.class)
@AddExtension(CdiComponentProvider.class)
@AddBean(HelloWorldApplication.class)

(removed JAX-RS resource and exception mapper, added JAX-RS application)

You may also consider adding ConfigCdiExtension.

@tomas-langer tomas-langer removed the bug Something isn't working label Jul 28, 2022
@tomas-langer
Copy link
Member

I will close this issue, as the provided solution works without issues (tried with reproducer).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cdi CDI jax-rs JAX-RS and Jersey related issues P2 testing
Projects
Backlog
  
Closed
Development

No branches or pull requests

5 participants