org.glassfish.jersey.process.internal.RequestScoped 有多个活动上下文



我在检索ContainerRequestFilter中的RequestScoped对象时遇到困难,我尝试通过将Provider注入过滤器来做到这一点。我的应用程序配置如下:

class MyResourceConfig extends ResourceConfig
{
public static class MyBinder extends AbstractBinder 
{
@Override
protected void configure()
{
bindFactory(PolicyFactory.class)
.to(Policy.class)
.in(RequestScoped.class);
}
}
public MyResourceConfig()
{
register(new MyBinder());
register(MyDynamicFeature.class);
}
}
@Provider
class MyDynamicFeature implements DynamicFeature
{
@Override
public void configure(ResourceInfo ri, FeatureContext ctx)
{
ctx.register(MyRequestFilter.class);
}
}
@Priority(Priorities.AUTHENTICATION)
public class MyRequestFilter implements ContainerRequestFilter
{
@Context
private HttpServletRequest request;
@Context
private ResourceInfo resourceInfo;
@Inject
private javax.inject.Provider<Policy> policyProvider;
@Override
public void filter(ContainerRequestContext requestContext) throws IOException
{
policyProvider.get();
}
}

MyRequestFilter中调用提供程序时,我收到以下异常:

A MultiException has 2 exceptions.  They are:
1. java.lang.IllegalStateException: There is more than one active context for org.glassfish.jersey.process.internal.RequestScoped
2. java.lang.IllegalStateException: While attempting to create a service for SystemDescriptor(
implementation=com.*.PolicyFactory
contracts={com.*.Policy}
scope=org.glassfish.jersey.process.internal.RequestScoped
qualifiers={}
descriptorType=PROVIDE_METHOD
descriptorVisibility=NORMAL
metadata=
rank=0
loader=org.glassfish.hk2.utilities.binding.AbstractBinder$2@16c49a23
proxiable=null
proxyForSameScope=null
analysisName=null
id=178
locatorId=48
identityHashCode=1250168232
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:2120)
at org.jvnet.hk2.internal.ServiceLocatorImpl.internalGetService(ServiceLocatorImpl.java:777)
at org.jvnet.hk2.internal.ServiceLocatorImpl.getUnqualifiedService(ServiceLocatorImpl.java:789)
at org.jvnet.hk2.internal.IterableProviderImpl.get(IterableProviderImpl.java:111)
at com.*.MyEndpointFilter.hasResourceAccess(MyEndpointFilter.java:127)
at com.*.MyEndpointFilter.filter(MyEndpointFilter.java:52)
at org.glassfish.jersey.server.ContainerFilteringStage.apply(ContainerFilteringStage.java:132)
at org.glassfish.jersey.server.ContainerFilteringStage.apply(ContainerFilteringStage.java:68)
at org.glassfish.jersey.process.internal.Stages.process(Stages.java:197)
at org.glassfish.jersey.server.ServerRuntime$1.run(ServerRuntime.java:269)
at org.glassfish.jersey.internal.Errors$1.call(Errors.java:272)
at org.glassfish.jersey.internal.Errors$1.call(Errors.java:268)
at org.glassfish.jersey.internal.Errors.process(Errors.java:316)
at org.glassfish.jersey.internal.Errors.process(Errors.java:298)
at org.glassfish.jersey.internal.Errors.process(Errors.java:268)
at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:289)
at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:256)
at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:703)
at org.glassfish.jersey.servlet.WebComponent.serviceImpl(WebComponent.java:416)
... 12 more
Caused by: 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:2216)
at org.jvnet.hk2.internal.ServiceLocatorImpl.access$000(ServiceLocatorImpl.java:128)
at org.jvnet.hk2.internal.ServiceLocatorImpl$3.compute(ServiceLocatorImpl.java:188)
at org.jvnet.hk2.internal.ServiceLocatorImpl$3.compute(ServiceLocatorImpl.java:184)
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:2230)
at org.jvnet.hk2.internal.Utilities.createService(Utilities.java:2104)
... 30 more

调试时,我观察到创建了 2 个Hk2RequestScope实例,具有以下堆栈跟踪:

Thread [main] (Suspended (breakpoint at line 61 in Hk2RequestScope))    
Hk2RequestScope.createContext() line: 61  
Hk2RequestScope(RequestScope).runInScope(Producer<T>) line: 411   
JerseyInvocation.invoke() line: 752   
JerseyInvocation$Builder.method(String, Entity<?>) line: 445  
JerseyInvocation$Builder.post(Entity<?>) line: 351    
LoginTest.testBadNewPassword() line: 181  
NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) line: not available [native method]    
NativeMethodAccessorImpl.invoke(Object, Object[]) line: 62    
DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: 43    
Method.invoke(Object, Object...) line: 498    
ReflectionUtils.invokeMethod(Method, Object, Object...) line: 513 
ExecutableInvoker.invoke(Method, Object, ExtensionContext, ExtensionRegistry) line: 115   
TestMethodTestDescriptor.lambda$invokeTestMethod$6(ExtensionContext, JupiterEngineExecutionContext) line: 170 
22179697.execute() line: not available    
ThrowableCollector.execute(Executable) line: 40   
TestMethodTestDescriptor.invokeTestMethod(JupiterEngineExecutionContext, Node$DynamicTestExecutor) line: 166  
TestMethodTestDescriptor.execute(JupiterEngineExecutionContext, Node$DynamicTestExecutor) line: 113   
TestMethodTestDescriptor.execute(EngineExecutionContext, Node$DynamicTestExecutor) line: 58   
HierarchicalTestExecutor$NodeExecutor.lambda$executeRecursively$3(ExecutionTracker) line: 113 
1803669141.execute() line: not available  
SingleTestExecutor.executeSafely(SingleTestExecutor$Executable) line: 66  
HierarchicalTestExecutor$NodeExecutor.executeRecursively(ExecutionTracker) line: 108  
HierarchicalTestExecutor$NodeExecutor.execute(C, ExecutionTracker) line: 79   
HierarchicalTestExecutor$NodeExecutor.lambda$executeRecursively$2(ExecutionTracker, TestDescriptor) line: 121 
232307208.accept(Object) line: not available  
ForEachOps$ForEachOp$OfRef<T>.accept(T) line: 184 
ReferencePipeline$2$1.accept(P_OUT) line: 175 
LinkedHashMap$LinkedKeyIterator(Iterator<E>).forEachRemaining(Consumer<? super E>) line: 116  
Spliterators$IteratorSpliterator<T>.forEachRemaining(Consumer<? super T>) line: 1801  
ReferencePipeline$2(AbstractPipeline<E_IN,E_OUT,S>).copyInto(Sink<P_IN>, Spliterator<P_IN>) line: 481 
ReferencePipeline$2(AbstractPipeline<E_IN,E_OUT,S>).wrapAndCopyInto(S, Spliterator<P_IN>) line: 471   
ForEachOps$ForEachOp$OfRef<T>(ForEachOps$ForEachOp<T>).evaluateSequential(PipelineHelper<T>, Spliterator<S>) line: 151    
ForEachOps$ForEachOp$OfRef<T>.evaluateSequential(PipelineHelper, Spliterator) line: 174   
ReferencePipeline$2(AbstractPipeline<E_IN,E_OUT,S>).evaluate(TerminalOp<E_OUT,R>) line: 234   
ReferencePipeline$2(ReferencePipeline<P_IN,P_OUT>).forEach(Consumer<? super P_OUT>) line: 418 
HierarchicalTestExecutor$NodeExecutor.lambda$executeRecursively$3(ExecutionTracker) line: 121 
1803669141.execute() line: not available  
SingleTestExecutor.executeSafely(SingleTestExecutor$Executable) line: 66  
HierarchicalTestExecutor$NodeExecutor.executeRecursively(ExecutionTracker) line: 108  
HierarchicalTestExecutor$NodeExecutor.execute(C, ExecutionTracker) line: 79   
HierarchicalTestExecutor$NodeExecutor.lambda$executeRecursively$2(ExecutionTracker, TestDescriptor) line: 121 
232307208.accept(Object) line: not available  
ForEachOps$ForEachOp$OfRef<T>.accept(T) line: 184 
ReferencePipeline$2$1.accept(P_OUT) line: 175 
LinkedHashMap$LinkedKeyIterator(Iterator<E>).forEachRemaining(Consumer<? super E>) line: 116  
Spliterators$IteratorSpliterator<T>.forEachRemaining(Consumer<? super T>) line: 1801  
ReferencePipeline$2(AbstractPipeline<E_IN,E_OUT,S>).copyInto(Sink<P_IN>, Spliterator<P_IN>) line: 481 
ReferencePipeline$2(AbstractPipeline<E_IN,E_OUT,S>).wrapAndCopyInto(S, Spliterator<P_IN>) line: 471   
ForEachOps$ForEachOp$OfRef<T>(ForEachOps$ForEachOp<T>).evaluateSequential(PipelineHelper<T>, Spliterator<S>) line: 151    
ForEachOps$ForEachOp$OfRef<T>.evaluateSequential(PipelineHelper, Spliterator) line: 174   
ReferencePipeline$2(AbstractPipeline<E_IN,E_OUT,S>).evaluate(TerminalOp<E_OUT,R>) line: 234   
ReferencePipeline$2(ReferencePipeline<P_IN,P_OUT>).forEach(Consumer<? super P_OUT>) line: 418 
HierarchicalTestExecutor$NodeExecutor.lambda$executeRecursively$3(ExecutionTracker) line: 121 
1803669141.execute() line: not available  
SingleTestExecutor.executeSafely(SingleTestExecutor$Executable) line: 66  
HierarchicalTestExecutor$NodeExecutor.executeRecursively(ExecutionTracker) line: 108  
HierarchicalTestExecutor$NodeExecutor.execute(C, ExecutionTracker) line: 79   
HierarchicalTestExecutor<C>.execute() line: 55    
JupiterTestEngine(HierarchicalTestEngine<C>).execute(ExecutionRequest) line: 43   
DefaultLauncher.execute(TestEngine, ExecutionRequest) line: 170   
DefaultLauncher.execute(Root, ConfigurationParameters, TestExecutionListener...) line: 154    
DefaultLauncher.execute(LauncherDiscoveryRequest, TestExecutionListener...) line: 90  
JUnit5TestReference.run(TestExecution) line: 86   
TestExecution.run(ITestReference[]) line: 38  
RemoteTestRunner.runTests(String[], String, TestExecution) line: 538  
RemoteTestRunner.runTests(TestExecution) line: 760    
RemoteTestRunner.run() line: 460  
RemoteTestRunner.main(String[]) line: 206 
Thread [grizzly-http-server-1] (Suspended (breakpoint at line 61 in Hk2RequestScope))   
Hk2RequestScope.createContext() line: 61  
ServerRuntime.process(ContainerRequest) line: 249 
ApplicationHandler.handle(ContainerRequest) line: 703 
WebComponent.serviceImpl(URI, URI, HttpServletRequest, HttpServletResponse) line: 416 
WebComponent.service(URI, URI, HttpServletRequest, HttpServletResponse) line: 370 
ServletContainer.service(URI, URI, HttpServletRequest, HttpServletResponse) line: 389 
ServletContainer.service(HttpServletRequest, HttpServletResponse) line: 342   
ServletContainer.service(ServletRequest, ServletResponse) line: 229   
FilterChainImpl.doFilter(ServletRequest, ServletResponse) line: 147   
FilterChainImpl.invokeFilterChain(ServletRequest, ServletResponse) line: 106  
ServletHandler.doServletService(Request, Response) line: 226  
ServletHandler.service(Request, Response) line: 173   
HttpHandler$1.run() line: 224 
FixedThreadPool$BasicWorker(AbstractThreadPool$Worker).doWork() line: 593 
FixedThreadPool$BasicWorker(AbstractThreadPool$Worker).run() line: 573    
Thread.run() line: 748    

在这种特殊情况下,我正在从单元测试中调用 Grizzly 为 servlet 部署。当不使用 servlet 部署以及实际实时运行应用程序 (Tomcat( 时,也会发生此问题。

如何解决此问题?

问题与较新版本的泽西岛隔离。以下 MCVE 不适用于泽西岛 2.27 或 2.26,但传递 2.25:

build.gradle

apply plugin: 'java'
apply plugin: 'eclipse-wtp'
repositories {
mavenCentral()
}
sourceSets {
src {
java {
srcDirs = ["src/main/java"];
}
}
test {
java {
srcDirs = ["test/main/java"];
}
}
}
def jerseyVersion = '2.25'
dependencies {
compile "org.glassfish.jersey.containers:jersey-container-servlet:${jerseyVersion}"
compile "org.glassfish.jersey.inject:jersey-hk2:${jerseyVersion}"
testCompile "org.junit.jupiter:junit-jupiter-api:5.2.0"
testCompile "org.junit.jupiter:junit-jupiter-engine:5.2.0"
testCompile "org.junit.platform:junit-platform-launcher:1.2.0"
testCompile "org.glassfish.jersey.test-framework:jersey-test-framework-core:${jerseyVersion}"
testCompile "org.glassfish.jersey.test-framework.providers:jersey-test-framework-provider-grizzly2:${jerseyVersion}"
}
version = '1.0'
jar {
manifest.attributes provider: 'gradle'
}

测试.java

package test;
import static org.junit.jupiter.api.Assertions.assertEquals;
import java.io.IOException;
import javax.inject.Inject;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerRequestFilter;
import javax.ws.rs.container.DynamicFeature;
import javax.ws.rs.container.ResourceInfo;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.FeatureContext;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import org.glassfish.hk2.api.Factory;
import org.glassfish.hk2.utilities.binding.AbstractBinder;
import org.glassfish.jersey.process.internal.RequestScoped;
import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.test.JerseyTest;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
public class MyJerseyTest extends JerseyTest
{
public static class Policy
{
public int getA()
{
return 1;
}
}
static class PolicyFactory implements Factory<Policy>
{
@Override
public Policy provide()
{
return new Policy();
}
@Override
public void dispose(Policy instance)
{
}
}
public static class MyRequestFilter implements ContainerRequestFilter
{
@Inject
private javax.inject.Provider<Policy> policyProvider;
@Override
public void filter(ContainerRequestContext requestContext) throws IOException
{
Policy policy = policyProvider.get();
if(policy.getA() != 1)
{
throw new WebApplicationException(Status.FORBIDDEN);
}
}
}
public static class MyDynamicFeature implements DynamicFeature
{
@Override
public void configure(ResourceInfo ri, FeatureContext ctx)
{
ctx.register(MyRequestFilter.class);
}
}
@Path("/test")
public static class MyEndpoint
{
@Context
Policy policy;
public MyEndpoint()
{
}
@GET
@Produces(MediaType.APPLICATION_JSON)
public Response doTest()
{
return Response.ok().build();
}
}
public static class MyResourceConfig extends ResourceConfig
{
public static class MyBinder extends AbstractBinder
{
@Override
protected void configure()
{
bindFactory(PolicyFactory.class)
.to(Policy.class)
.in(RequestScoped.class);
}
}
public MyResourceConfig()
{
register(new MyBinder());
register(MyDynamicFeature.class);
register(MyEndpoint.class);
}
}
@BeforeEach
public void beforeEach() throws Exception
{
// Workaround for JUnit 5
setUp();
}
@AfterEach
public void afterEach() throws Exception
{
// Workaround for JUnit 5
tearDown();
}
@Override
public ResourceConfig configure()
{
return new MyResourceConfig();
}
@Test
public void testMyEndpoint()
{
Response response = target("test").request().get();
assertEquals(Status.OK.getStatusCode(), response.getStatus());
}
}

最新更新