无法加载球衣测试中的注入值
injected values in jersey test can not be loaded
我是 运行 我在 tomee 中的应用程序,正在尝试通过 jersey 测试框架测试我的 jax-rs 网络服务。
我添加了如下的maven依赖:
<dependency>
<groupId>org.glassfish.jersey.test-framework</groupId>
<artifactId>jersey-test-framework-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.test-framework.providers</groupId>
<artifactId>jersey-test-framework-provider-grizzly2</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.inject</groupId>
<artifactId>jersey-hk2</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-common</artifactId>
<version>${jersey.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
<scope>test</scope>
</dependency>
在我的资源中 class 我有
@Inject
private AuthenticationTokenService authenticationTokenService;
在我的服务中 class 我有:
@Inject
private AuthenticationTokenIssuer tokenIssuer;
@Inject
private AuthenticationTokenParser tokenParser;
在这两个class里面我有
@Inject
private AuthenticationTokenSettings settings;
我想我的问题是因为 AuthenticationTokenSettings
中的成员
@Inject
@Config("token")
private String token;
这些是通过 Properties 对象从文件中使用限定符 @Config 注入的。
我写了一个 InjectionResolver class 来解析
@Singleton
public static class ConfigInjectionResolver implements InjectionResolver<Configurable>
{
private static Properties properties;
public ConfigurableInjectionResolver()
{
properties = new Properties();
InputStream stream = ConfigurationProducer.class.getResourceAsStream("/application.properties");
if (stream == null)
{
throw new RuntimeException("Cannot find application.properties configuration file.");
}
try
{
this.properties.load(stream);
}
catch (final IOException e)
{
throw new RuntimeException("Configuration file cannot be loaded.");
}
}
@Override
public Object resolve(Injectee injectee, ServiceHandle<?> handle)
{
if (String.class == injectee.getRequiredType())
{
AnnotatedElement elem = injectee.getParent();
if (elem instanceof Constructor)
{
Constructor ctor = (Constructor) elem;
Configurable config = (Configurable) ctor.getParameterAnnotations()[injectee.getPosition()][0];
return properties.get(config.value());
}
else
{
Configurable configurable = elem.getAnnotation(Configurable.class);
return properties.get(configurable.value());
}
}
return null;
}
@Override
public boolean isConstructorParameterIndicator()
{
return true;
}
@Override
public boolean isMethodParameterIndicator()
{
return false;
}
}
在我覆盖的配置方法中,我创建了这样的抽象活页夹。
ResourceConfig resourceConfig = new ResourceConfig(
AuthenticationResource.class);
resourceConfig.register(new AbstractBinder()
{
@Override
protected void configure()
{
bind(AuthenticationTokenService.class).
to(AuthenticationResource.class);
bind(AuthenticationTokenIssuer.class).
to(AuthenticationTokenService.class);
bind(AuthenticationTokenParser.class).
to(AuthenticationTokenService.class);
bind(AuthenticationTokenSettings.class).
to(AuthenticationTokenIssuer.class);
bind(AuthenticationTokenSettings.class).
to(AuthenticationTokenParser.class);
bind(ConfigurableInjectionResolver.class)
.to(new TypeLiteral<InjectionResolver<Configurable>>()
{
})
.in(Singleton.class);
.
.
.
.
我有如下异常:
Apr 15, 2020 2:05:15 AM org.glassfish.jersey.internal.Errors logErrors
WARNING: The following warnings have been detected: WARNING: HK2 service reification failed for [com.transport.webservices.security.service.AuthenticationTokenService] with an exception:
MultiException stack 1 of 2
java.lang.NoSuchMethodException: Could not find a suitable constructor in com.transport.webservices.security.service.AuthenticationTokenService class.
at org.glassfish.jersey.inject.hk2.JerseyClassAnalyzer.getConstructor(JerseyClassAnalyzer.java:168)
.
.
MultiException stack 2 of 2
java.lang.IllegalArgumentException: Errors were discovered while reifying SystemDescriptor(
implementation=com.transport.webservices.security.service.AuthenticationTokenService
contracts={com.transport.webservices.security.api.resource.AuthenticationResource}
scope=org.glassfish.hk2.api.PerLookup
qualifiers={}
descriptorType=CLASS
descriptorVisibility=NORMAL
metadata=
rank=0
loader=org.glassfish.hk2.utilities.binding.AbstractBinder@71a88a3e
proxiable=null
proxyForSameScope=null
analysisName=null
id=142
locatorId=0
identityHashCode=1099971211
reified=false)
at org.jvnet.hk2.internal.SystemDescriptor.reify(SystemDescriptor.java:681)
.
.
WARNING: HK2 service reification failed for [com.transport.webservices.security.service.AuthenticationTokenService] with an exception:
MultiException stack 1 of 2
java.lang.NoSuchMethodException: Could not find a suitable constructor in com.transport.webservices.security.service.AuthenticationTokenService class.
.
.
MultiException stack 2 of 2
java.lang.IllegalArgumentException: Errors were discovered while reifying SystemDescriptor(
implementation=com.transport.webservices.security.service.AuthenticationTokenService
contracts={com.transport.webservices.security.api.resource.AuthenticationResource}
scope=org.glassfish.hk2.api.PerLookup
qualifiers={}
descriptorType=CLASS
descriptorVisibility=NORMAL
metadata=
rank=0
loader=org.glassfish.hk2.utilities.binding.AbstractBinder@71a88a3e
proxiable=null
proxyForSameScope=null
analysisName=null
id=142
locatorId=0
identityHashCode=1099971211
reified=false)
at org.jvnet.hk2.internal.SystemDescriptor.reify(SystemDescriptor.java:681)
.
.
WARNING: Unknown HK2 failure detected:
MultiException stack 1 of 3
org.glassfish.hk2.api.UnsatisfiedDependencyException: There was no object available for injection at SystemInjecteeImpl(requiredType=AuthenticationTokenSettings,parent=AuthenticationTokenIssuer,qualifiers={},position=-1,optional=false,self=false,unqualified=null,672817351)
.
.
MultiException stack 2 of 3
java.lang.IllegalArgumentException: While attempting to resolve the dependencies of com.transport.webservices.security.service.AuthenticationTokenIssuer errors were found
.
.
MultiException stack 3 of 3
java.lang.IllegalStateException: Unable to perform operation: resolve on com.transport.webservices.security.service.AuthenticationTokenIssuer
.
.
WARNING: Unknown HK2 failure detected:
MultiException stack 1 of 5
org.glassfish.hk2.api.UnsatisfiedDependencyException: There was no object available for injection at SystemInjecteeImpl(requiredType=AuthenticationTokenSettings,parent=AuthenticationTokenIssuer,qualifiers={},position=-1,optional=false,self=false,unqualified=null,672817351)
.
.
MultiException stack 2 of 5
java.lang.IllegalArgumentException: While attempting to resolve the dependencies of com.transport.webservices.security.service.AuthenticationTokenIssuer errors were found
.
.
MultiException stack 3 of 5
java.lang.IllegalStateException: Unable to perform operation: resolve on com.transport.webservices.security.service.AuthenticationTokenIssuer
.
.
MultiException stack 4 of 5
java.lang.IllegalArgumentException: While attempting to resolve the dependencies of com.transport.webservices.security.api.resource.AuthenticationResource errors were found
.
.
MultiException stack 5 of 5
java.lang.IllegalStateException: Unable to perform operation: resolve on com.transport.webservices.security.api.resource.AuthenticationResource
.
.
java.lang.AssertionError: Should return status 200 expected:<200> but was:<500>
at org.junit.Assert.fail(Assert.java:88)
除此之外,我还必须添加以下 maven 依赖项,因为我现有的 soap classes 在我为 jersey 测试添加了 maven 依赖项后放弃了编译,我不明白为什么。
不知道是不是这个问题
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.1</version>
</dependency>
<dependency>
<groupId>javax.xml.ws</groupId>
<artifactId>jaxws-api</artifactId>
<version>2.3.1</version>
</dependency>
<dependency>
<groupId>javax.jws</groupId>
<artifactId>javax.jws-api</artifactId>
<version>1.1</version>
</dependency>
我创建了一个 class 扩展 AnnotationLiteral
如下:
public static class ConfigurableQualifierLiteral extends AnnotationLiteral<Configurable> implements Configurable
{
String value;
ConfigurableQualifierLiteral(String value)
{
this.value = value;
}
@Override
public String value()
{
return value;
}
}
然后在我的 AbstractBinder
中,我绑定了我的注释成员如下:
bind(Long.valueOf(36000)).to(new TypeLiteral<Long>()
{
}).qualifiedBy(new TestAuthenticationResource.ConfigurableQualifierLiteral("authentication.jwt.validFor"));
我是 运行 我在 tomee 中的应用程序,正在尝试通过 jersey 测试框架测试我的 jax-rs 网络服务。
我添加了如下的maven依赖:
<dependency>
<groupId>org.glassfish.jersey.test-framework</groupId>
<artifactId>jersey-test-framework-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.test-framework.providers</groupId>
<artifactId>jersey-test-framework-provider-grizzly2</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.inject</groupId>
<artifactId>jersey-hk2</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-common</artifactId>
<version>${jersey.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
<scope>test</scope>
</dependency>
在我的资源中 class 我有
@Inject
private AuthenticationTokenService authenticationTokenService;
在我的服务中 class 我有:
@Inject
private AuthenticationTokenIssuer tokenIssuer;
@Inject
private AuthenticationTokenParser tokenParser;
在这两个class里面我有
@Inject
private AuthenticationTokenSettings settings;
我想我的问题是因为 AuthenticationTokenSettings
@Inject
@Config("token")
private String token;
这些是通过 Properties 对象从文件中使用限定符 @Config 注入的。
我写了一个 InjectionResolver class 来解析
@Singleton
public static class ConfigInjectionResolver implements InjectionResolver<Configurable>
{
private static Properties properties;
public ConfigurableInjectionResolver()
{
properties = new Properties();
InputStream stream = ConfigurationProducer.class.getResourceAsStream("/application.properties");
if (stream == null)
{
throw new RuntimeException("Cannot find application.properties configuration file.");
}
try
{
this.properties.load(stream);
}
catch (final IOException e)
{
throw new RuntimeException("Configuration file cannot be loaded.");
}
}
@Override
public Object resolve(Injectee injectee, ServiceHandle<?> handle)
{
if (String.class == injectee.getRequiredType())
{
AnnotatedElement elem = injectee.getParent();
if (elem instanceof Constructor)
{
Constructor ctor = (Constructor) elem;
Configurable config = (Configurable) ctor.getParameterAnnotations()[injectee.getPosition()][0];
return properties.get(config.value());
}
else
{
Configurable configurable = elem.getAnnotation(Configurable.class);
return properties.get(configurable.value());
}
}
return null;
}
@Override
public boolean isConstructorParameterIndicator()
{
return true;
}
@Override
public boolean isMethodParameterIndicator()
{
return false;
}
}
在我覆盖的配置方法中,我创建了这样的抽象活页夹。
ResourceConfig resourceConfig = new ResourceConfig(
AuthenticationResource.class);
resourceConfig.register(new AbstractBinder()
{
@Override
protected void configure()
{
bind(AuthenticationTokenService.class).
to(AuthenticationResource.class);
bind(AuthenticationTokenIssuer.class).
to(AuthenticationTokenService.class);
bind(AuthenticationTokenParser.class).
to(AuthenticationTokenService.class);
bind(AuthenticationTokenSettings.class).
to(AuthenticationTokenIssuer.class);
bind(AuthenticationTokenSettings.class).
to(AuthenticationTokenParser.class);
bind(ConfigurableInjectionResolver.class)
.to(new TypeLiteral<InjectionResolver<Configurable>>()
{
})
.in(Singleton.class);
.
.
.
.
我有如下异常:
Apr 15, 2020 2:05:15 AM org.glassfish.jersey.internal.Errors logErrors
WARNING: The following warnings have been detected: WARNING: HK2 service reification failed for [com.transport.webservices.security.service.AuthenticationTokenService] with an exception:
MultiException stack 1 of 2
java.lang.NoSuchMethodException: Could not find a suitable constructor in com.transport.webservices.security.service.AuthenticationTokenService class.
at org.glassfish.jersey.inject.hk2.JerseyClassAnalyzer.getConstructor(JerseyClassAnalyzer.java:168)
.
.
MultiException stack 2 of 2
java.lang.IllegalArgumentException: Errors were discovered while reifying SystemDescriptor(
implementation=com.transport.webservices.security.service.AuthenticationTokenService
contracts={com.transport.webservices.security.api.resource.AuthenticationResource}
scope=org.glassfish.hk2.api.PerLookup
qualifiers={}
descriptorType=CLASS
descriptorVisibility=NORMAL
metadata=
rank=0
loader=org.glassfish.hk2.utilities.binding.AbstractBinder@71a88a3e
proxiable=null
proxyForSameScope=null
analysisName=null
id=142
locatorId=0
identityHashCode=1099971211
reified=false)
at org.jvnet.hk2.internal.SystemDescriptor.reify(SystemDescriptor.java:681)
.
.
WARNING: HK2 service reification failed for [com.transport.webservices.security.service.AuthenticationTokenService] with an exception:
MultiException stack 1 of 2
java.lang.NoSuchMethodException: Could not find a suitable constructor in com.transport.webservices.security.service.AuthenticationTokenService class.
.
.
MultiException stack 2 of 2
java.lang.IllegalArgumentException: Errors were discovered while reifying SystemDescriptor(
implementation=com.transport.webservices.security.service.AuthenticationTokenService
contracts={com.transport.webservices.security.api.resource.AuthenticationResource}
scope=org.glassfish.hk2.api.PerLookup
qualifiers={}
descriptorType=CLASS
descriptorVisibility=NORMAL
metadata=
rank=0
loader=org.glassfish.hk2.utilities.binding.AbstractBinder@71a88a3e
proxiable=null
proxyForSameScope=null
analysisName=null
id=142
locatorId=0
identityHashCode=1099971211
reified=false)
at org.jvnet.hk2.internal.SystemDescriptor.reify(SystemDescriptor.java:681)
.
.
WARNING: Unknown HK2 failure detected:
MultiException stack 1 of 3
org.glassfish.hk2.api.UnsatisfiedDependencyException: There was no object available for injection at SystemInjecteeImpl(requiredType=AuthenticationTokenSettings,parent=AuthenticationTokenIssuer,qualifiers={},position=-1,optional=false,self=false,unqualified=null,672817351)
.
.
MultiException stack 2 of 3
java.lang.IllegalArgumentException: While attempting to resolve the dependencies of com.transport.webservices.security.service.AuthenticationTokenIssuer errors were found
.
.
MultiException stack 3 of 3
java.lang.IllegalStateException: Unable to perform operation: resolve on com.transport.webservices.security.service.AuthenticationTokenIssuer
.
.
WARNING: Unknown HK2 failure detected:
MultiException stack 1 of 5
org.glassfish.hk2.api.UnsatisfiedDependencyException: There was no object available for injection at SystemInjecteeImpl(requiredType=AuthenticationTokenSettings,parent=AuthenticationTokenIssuer,qualifiers={},position=-1,optional=false,self=false,unqualified=null,672817351)
.
.
MultiException stack 2 of 5
java.lang.IllegalArgumentException: While attempting to resolve the dependencies of com.transport.webservices.security.service.AuthenticationTokenIssuer errors were found
.
.
MultiException stack 3 of 5
java.lang.IllegalStateException: Unable to perform operation: resolve on com.transport.webservices.security.service.AuthenticationTokenIssuer
.
.
MultiException stack 4 of 5
java.lang.IllegalArgumentException: While attempting to resolve the dependencies of com.transport.webservices.security.api.resource.AuthenticationResource errors were found
.
.
MultiException stack 5 of 5
java.lang.IllegalStateException: Unable to perform operation: resolve on com.transport.webservices.security.api.resource.AuthenticationResource
.
.
java.lang.AssertionError: Should return status 200 expected:<200> but was:<500>
at org.junit.Assert.fail(Assert.java:88)
除此之外,我还必须添加以下 maven 依赖项,因为我现有的 soap classes 在我为 jersey 测试添加了 maven 依赖项后放弃了编译,我不明白为什么。 不知道是不是这个问题
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.1</version>
</dependency>
<dependency>
<groupId>javax.xml.ws</groupId>
<artifactId>jaxws-api</artifactId>
<version>2.3.1</version>
</dependency>
<dependency>
<groupId>javax.jws</groupId>
<artifactId>javax.jws-api</artifactId>
<version>1.1</version>
</dependency>
我创建了一个 class 扩展 AnnotationLiteral
如下:
public static class ConfigurableQualifierLiteral extends AnnotationLiteral<Configurable> implements Configurable
{
String value;
ConfigurableQualifierLiteral(String value)
{
this.value = value;
}
@Override
public String value()
{
return value;
}
}
然后在我的 AbstractBinder
中,我绑定了我的注释成员如下:
bind(Long.valueOf(36000)).to(new TypeLiteral<Long>()
{
}).qualifiedBy(new TestAuthenticationResource.ConfigurableQualifierLiteral("authentication.jwt.validFor"));