eclipse-ee4j / jersey

Eclipse Jersey Project - Read our Wiki:
https://github.com/eclipse-ee4j/jersey/wiki
Other
690 stars 351 forks source link

@Immediate binding fail after Container#reload #3497

Open jerseyrobot opened 7 years ago

jerseyrobot commented 7 years ago

I managed to reproduce this with a simple gist.

The code is really self-explanatory but basically I'm binding a service with Immediate scope and then trying to reload the application using the org.glassfish.jersey.server.spi.Container#reload method.

The result is the following exception:

Jan 24, 2017 11:15:23 PM org.glassfish.grizzly.http.server.NetworkListener start
INFO: Started listener bound to [localhost:8080]
Jan 24, 2017 11:15:23 PM org.glassfish.grizzly.http.server.HttpServer start
INFO: [HttpServer] Started.
Exception in thread "main" javax.ws.rs.InternalServerErrorException: HTTP 500 Request failed.
    at org.glassfish.jersey.client.JerseyInvocation.convertToException(JerseyInvocation.java:1032)
    at org.glassfish.jersey.client.JerseyInvocation.translate(JerseyInvocation.java:819)
    at org.glassfish.jersey.client.JerseyInvocation.access$700(JerseyInvocation.java:92)
    at org.glassfish.jersey.client.JerseyInvocation$2.call(JerseyInvocation.java:701)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:228)
    at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:444)
    at org.glassfish.jersey.client.JerseyInvocation.invoke(JerseyInvocation.java:697)
    at org.glassfish.jersey.client.JerseyInvocation$Builder.method(JerseyInvocation.java:420)
    at org.glassfish.jersey.client.JerseyInvocation$Builder.get(JerseyInvocation.java:316)
    at com.github.fabriziocucci.App.main(App.java:102)
Jan 24, 2017 11:15:23 PM org.glassfish.jersey.internal.Errors logErrors
WARNING: The following warnings have been detected: WARNING: Unknown HK2 failure detected:
MultiException stack 1 of 4
java.lang.IllegalStateException: Could not find an active context for org.glassfish.hk2.api.Immediate
    at org.jvnet.hk2.internal.ServiceLocatorImpl._resolveContext(ServiceLocatorImpl.java:2200)
    at org.jvnet.hk2.internal.ServiceLocatorImpl.access$000(ServiceLocatorImpl.java:125)
    at org.jvnet.hk2.internal.ServiceLocatorImpl$3.compute(ServiceLocatorImpl.java:185)
    at org.jvnet.hk2.internal.ServiceLocatorImpl$3.compute(ServiceLocatorImpl.java:181)
    at org.glassfish.hk2.utilities.cache.Cache$OriginThreadAwareFuture$1.call(Cache.java:97)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at org.glassfish.hk2.utilities.cache.Cache$OriginThreadAwareFuture.run(Cache.java:154)
    at org.glassfish.hk2.utilities.cache.Cache.compute(Cache.java:199)
    at org.jvnet.hk2.internal.ServiceLocatorImpl.resolveContext(ServiceLocatorImpl.java:2208)
    at org.jvnet.hk2.internal.Utilities.createService(Utilities.java:2000)
    at org.jvnet.hk2.internal.ServiceLocatorImpl.getService(ServiceLocatorImpl.java:682)
    at org.jvnet.hk2.internal.ThreeThirtyResolver.resolve(ThreeThirtyResolver.java:78)
    at org.jvnet.hk2.internal.ClazzCreator.resolve(ClazzCreator.java:212)
    at org.jvnet.hk2.internal.ClazzCreator.resolveAllDependencies(ClazzCreator.java:229)
    at org.jvnet.hk2.internal.ClazzCreator.create(ClazzCreator.java:358)
    at org.jvnet.hk2.internal.SystemDescriptor.create(SystemDescriptor.java:487)
    at org.glassfish.jersey.process.internal.RequestScope.findOrCreate(RequestScope.java:162)
    at org.jvnet.hk2.internal.Utilities.createService(Utilities.java:2022)
    at org.jvnet.hk2.internal.ServiceLocatorImpl.internalGetService(ServiceLocatorImpl.java:774)
    at org.jvnet.hk2.internal.ServiceLocatorImpl.internalGetService(ServiceLocatorImpl.java:737)
    at org.jvnet.hk2.internal.ServiceLocatorImpl.getService(ServiceLocatorImpl.java:707)
    at org.glassfish.jersey.internal.inject.Injections.getOrCreate(Injections.java:172)
    at org.glassfish.jersey.server.model.MethodHandler$ClassBasedMethodHandler.getInstance(MethodHandler.java:284)
    at org.glassfish.jersey.server.internal.routing.PushMethodHandlerRouter.apply(PushMethodHandlerRouter.java:74)
    at org.glassfish.jersey.server.internal.routing.RoutingStage._apply(RoutingStage.java:109)
    at org.glassfish.jersey.server.internal.routing.RoutingStage._apply(RoutingStage.java:112)
    at org.glassfish.jersey.server.internal.routing.RoutingStage._apply(RoutingStage.java:112)
    at org.glassfish.jersey.server.internal.routing.RoutingStage._apply(RoutingStage.java:112)
    at org.glassfish.jersey.server.internal.routing.RoutingStage.apply(RoutingStage.java:92)
    at org.glassfish.jersey.server.internal.routing.RoutingStage.apply(RoutingStage.java:61)
    at org.glassfish.jersey.process.internal.Stages.process(Stages.java:197)
    at org.glassfish.jersey.server.ServerRuntime$2.run(ServerRuntime.java:318)
    at org.glassfish.jersey.internal.Errors$1.call(Errors.java:271)
    at org.glassfish.jersey.internal.Errors$1.call(Errors.java:267)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:267)
    at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:317)
    at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:305)
    at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:1154)
    at org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpContainer.service(GrizzlyHttpContainer.java:384)
    at org.glassfish.grizzly.http.server.HttpHandler$1.run(HttpHandler.java:224)
    at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:593)
    at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:573)
    at java.lang.Thread.run(Thread.java:745)
MultiException stack 2 of 4
java.lang.IllegalStateException: While attempting to create a service for SystemDescriptor(
    implementation=com.github.fabriziocucci.App$ImmediateGreetingService
    contracts={com.github.fabriziocucci.App$ImmediateGreetingService}
    scope=org.glassfish.hk2.api.Immediate
    qualifiers={}
    descriptorType=CLASS
    descriptorVisibility=NORMAL
    metadata=
    rank=0
    loader=org.glassfish.hk2.utilities.binding.AbstractBinder$2@7462aabb
    proxiable=null
    proxyForSameScope=null
    analysisName=null
    id=122
    locatorId=3
    identityHashCode=231711221
    reified=true) in scope org.glassfish.hk2.api.Immediate an error occured while locating the context
    at org.jvnet.hk2.internal.Utilities.createService(Utilities.java:2005)
    at org.jvnet.hk2.internal.ServiceLocatorImpl.getService(ServiceLocatorImpl.java:682)
    at org.jvnet.hk2.internal.ThreeThirtyResolver.resolve(ThreeThirtyResolver.java:78)
    at org.jvnet.hk2.internal.ClazzCreator.resolve(ClazzCreator.java:212)
    at org.jvnet.hk2.internal.ClazzCreator.resolveAllDependencies(ClazzCreator.java:229)
    at org.jvnet.hk2.internal.ClazzCreator.create(ClazzCreator.java:358)
    at org.jvnet.hk2.internal.SystemDescriptor.create(SystemDescriptor.java:487)
    at org.glassfish.jersey.process.internal.RequestScope.findOrCreate(RequestScope.java:162)
    at org.jvnet.hk2.internal.Utilities.createService(Utilities.java:2022)
    at org.jvnet.hk2.internal.ServiceLocatorImpl.internalGetService(ServiceLocatorImpl.java:774)
    at org.jvnet.hk2.internal.ServiceLocatorImpl.internalGetService(ServiceLocatorImpl.java:737)
    at org.jvnet.hk2.internal.ServiceLocatorImpl.getService(ServiceLocatorImpl.java:707)
    at org.glassfish.jersey.internal.inject.Injections.getOrCreate(Injections.java:172)
    at org.glassfish.jersey.server.model.MethodHandler$ClassBasedMethodHandler.getInstance(MethodHandler.java:284)
    at org.glassfish.jersey.server.internal.routing.PushMethodHandlerRouter.apply(PushMethodHandlerRouter.java:74)
    at org.glassfish.jersey.server.internal.routing.RoutingStage._apply(RoutingStage.java:109)
    at org.glassfish.jersey.server.internal.routing.RoutingStage._apply(RoutingStage.java:112)
    at org.glassfish.jersey.server.internal.routing.RoutingStage._apply(RoutingStage.java:112)
    at org.glassfish.jersey.server.internal.routing.RoutingStage._apply(RoutingStage.java:112)
    at org.glassfish.jersey.server.internal.routing.RoutingStage.apply(RoutingStage.java:92)
    at org.glassfish.jersey.server.internal.routing.RoutingStage.apply(RoutingStage.java:61)
    at org.glassfish.jersey.process.internal.Stages.process(Stages.java:197)
    at org.glassfish.jersey.server.ServerRuntime$2.run(ServerRuntime.java:318)
    at org.glassfish.jersey.internal.Errors$1.call(Errors.java:271)
    at org.glassfish.jersey.internal.Errors$1.call(Errors.java:267)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:267)
    at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:317)
    at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:305)
    at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:1154)
    at org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpContainer.service(GrizzlyHttpContainer.java:384)
    at org.glassfish.grizzly.http.server.HttpHandler$1.run(HttpHandler.java:224)
    at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:593)
    at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:573)
    at java.lang.Thread.run(Thread.java:745)
MultiException stack 3 of 4
java.lang.IllegalArgumentException: While attempting to resolve the dependencies of com.github.fabriziocucci.App$HelloWorldResource errors were found
    at org.jvnet.hk2.internal.ClazzCreator.resolveAllDependencies(ClazzCreator.java:247)
    at org.jvnet.hk2.internal.ClazzCreator.create(ClazzCreator.java:358)
    at org.jvnet.hk2.internal.SystemDescriptor.create(SystemDescriptor.java:487)
    at org.glassfish.jersey.process.internal.RequestScope.findOrCreate(RequestScope.java:162)
    at org.jvnet.hk2.internal.Utilities.createService(Utilities.java:2022)
    at org.jvnet.hk2.internal.ServiceLocatorImpl.internalGetService(ServiceLocatorImpl.java:774)
    at org.jvnet.hk2.internal.ServiceLocatorImpl.internalGetService(ServiceLocatorImpl.java:737)
    at org.jvnet.hk2.internal.ServiceLocatorImpl.getService(ServiceLocatorImpl.java:707)
    at org.glassfish.jersey.internal.inject.Injections.getOrCreate(Injections.java:172)
    at org.glassfish.jersey.server.model.MethodHandler$ClassBasedMethodHandler.getInstance(MethodHandler.java:284)
    at org.glassfish.jersey.server.internal.routing.PushMethodHandlerRouter.apply(PushMethodHandlerRouter.java:74)
    at org.glassfish.jersey.server.internal.routing.RoutingStage._apply(RoutingStage.java:109)
    at org.glassfish.jersey.server.internal.routing.RoutingStage._apply(RoutingStage.java:112)
    at org.glassfish.jersey.server.internal.routing.RoutingStage._apply(RoutingStage.java:112)
    at org.glassfish.jersey.server.internal.routing.RoutingStage._apply(RoutingStage.java:112)
    at org.glassfish.jersey.server.internal.routing.RoutingStage.apply(RoutingStage.java:92)
    at org.glassfish.jersey.server.internal.routing.RoutingStage.apply(RoutingStage.java:61)
    at org.glassfish.jersey.process.internal.Stages.process(Stages.java:197)
    at org.glassfish.jersey.server.ServerRuntime$2.run(ServerRuntime.java:318)
    at org.glassfish.jersey.internal.Errors$1.call(Errors.java:271)
    at org.glassfish.jersey.internal.Errors$1.call(Errors.java:267)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:267)
    at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:317)
    at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:305)
    at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:1154)
    at org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpContainer.service(GrizzlyHttpContainer.java:384)
    at org.glassfish.grizzly.http.server.HttpHandler$1.run(HttpHandler.java:224)
    at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:593)
    at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:573)
    at java.lang.Thread.run(Thread.java:745)
MultiException stack 4 of 4
java.lang.IllegalStateException: Unable to perform operation: resolve on com.github.fabriziocucci.App$HelloWorldResource
    at org.jvnet.hk2.internal.ClazzCreator.create(ClazzCreator.java:387)
    at org.jvnet.hk2.internal.SystemDescriptor.create(SystemDescriptor.java:487)
    at org.glassfish.jersey.process.internal.RequestScope.findOrCreate(RequestScope.java:162)
    at org.jvnet.hk2.internal.Utilities.createService(Utilities.java:2022)
    at org.jvnet.hk2.internal.ServiceLocatorImpl.internalGetService(ServiceLocatorImpl.java:774)
    at org.jvnet.hk2.internal.ServiceLocatorImpl.internalGetService(ServiceLocatorImpl.java:737)
    at org.jvnet.hk2.internal.ServiceLocatorImpl.getService(ServiceLocatorImpl.java:707)
    at org.glassfish.jersey.internal.inject.Injections.getOrCreate(Injections.java:172)
    at org.glassfish.jersey.server.model.MethodHandler$ClassBasedMethodHandler.getInstance(MethodHandler.java:284)
    at org.glassfish.jersey.server.internal.routing.PushMethodHandlerRouter.apply(PushMethodHandlerRouter.java:74)
    at org.glassfish.jersey.server.internal.routing.RoutingStage._apply(RoutingStage.java:109)
    at org.glassfish.jersey.server.internal.routing.RoutingStage._apply(RoutingStage.java:112)
    at org.glassfish.jersey.server.internal.routing.RoutingStage._apply(RoutingStage.java:112)
    at org.glassfish.jersey.server.internal.routing.RoutingStage._apply(RoutingStage.java:112)
    at org.glassfish.jersey.server.internal.routing.RoutingStage.apply(RoutingStage.java:92)
    at org.glassfish.jersey.server.internal.routing.RoutingStage.apply(RoutingStage.java:61)
    at org.glassfish.jersey.process.internal.Stages.process(Stages.java:197)
    at org.glassfish.jersey.server.ServerRuntime$2.run(ServerRuntime.java:318)
    at org.glassfish.jersey.internal.Errors$1.call(Errors.java:271)
    at org.glassfish.jersey.internal.Errors$1.call(Errors.java:267)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:267)
    at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:317)
    at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:305)
    at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:1154)
    at org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpContainer.service(GrizzlyHttpContainer.java:384)
    at org.glassfish.grizzly.http.server.HttpHandler$1.run(HttpHandler.java:224)
    at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:593)
    at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:573)
    at java.lang.Thread.run(Thread.java:745)

Affected Versions

[2.25.1]

jerseyrobot commented 6 years ago
jerseyrobot commented 7 years ago

@glassfishrobot Commented Reported by fabrizio.cucci

jerseyrobot commented 7 years ago

@glassfishrobot Commented fabrizio.cucci said: I was looking into the code and I may have found the issue.

When the application starts for the first time, the ApplicationHandler#initialize method is invoked, which in turn does:

// Configure binders and features. runtimeConfig.configureMetaProviders(locator);

That results in a call to the CommonConfig#configureMetaProviders which does:

// Next, configure all features configureFeatures(
    locator,
    new HashSet<FeatureRegistration>(),
    resetRegistrations());

The CommonConfig#resetRegistrations method copies the list of FeatureRegistration and then clears the list:

private List<FeatureRegistration> resetRegistrations() {
    final List<FeatureRegistration> result = new ArrayList<FeatureRegistration>(newFeatureRegistrations);
    newFeatureRegistrations.clear();
    return result;
}

When the Container#reload method is invoked, because the same ApplicationHandler#runtimeConfig is used, my ImmediateScopeFeature won't be in the CommonConfig#newFeatureRegistrations anymore and therefore won't be configured.

I don't have a big picture of the codebase but the two options that I can think of are:

Of course, calling the overloaded version of Container#reload(ResourceConfig) works fine because the RuntimeConfig is not reused.

By the way, I would be glad to contribute the fix with some hint.

jerseyrobot commented 7 years ago

@glassfishrobot Commented fabrizio.cucci said: Also, after re-reading my own report, I realized something else. In my case, the ImmediateScopeFeature is removed from the CommonConfig#newFeatureRegistrations and this is the reason why it's not re-configured on Container#reload(). But this means that, potentially, any other custom feature won't be re-configured upon Container#reload().

jerseyrobot commented 7 years ago

@glassfishrobot Commented This issue was imported from java.net JIRA JERSEY-3225

jerseyrobot commented 7 years ago

@fabriziocucci Commented pavelbucek said (on 17 Mar 2017, at 10:33):

Hi Fabrizio,

I'm sorry, we are currently not looking into mentioned issue.

I briefly looked into the code and I believe that CommonConfig should be recreated during the reload, but I'd need to debug it to be sure.

Would it be possible to extract your usecase to a minimal reproducer and share it?

Thanks and regards, Pavel

jerseyrobot commented 7 years ago

@fabriziocucci Commented fabrizio.cucci said (on 17 March 2017 at 12:54):

Hi Pavel,

thanks a lot for your prompt reply.

Is the gist attached to the issue description sufficient?

I'll post the link here too: https://gist.github.com/fabriziocucci/5660af43ebeb7ec04f20ed293cd5676f

Thanks, Fabrizio

jerseyrobot commented 7 years ago

@fabriziocucci Commented Added missing updates sent on mailing list since one particular comment from Pavel could be useful in resolving this:

I briefly looked into the code and I believe that CommonConfig should be recreated during the reload, but I'd need to debug it to be sure.

jerseyrobot commented 6 years ago

@fabriziocucci Commented @mpotociar I wanted to edit title and description to highlight the fact that this is not a HK2-related issue but actually any feature is not re-configured upon org.glassfish.jersey.server.spi.Container#reload.

Unfortunately, I'm not able to do that because the issue was physically reported by glasshfishrobot.

Anyway, please find below a more general test that proves my point:

Affected Versions: