【问题标题】:injected values in jersey test can not be loaded无法加载球衣测试中的注入值
【发布时间】:2020-07-27 20:11:46
【问题描述】:

我在 tomee 中运行我的应用程序并尝试通过 jersey 测试框架测试我的 jax-rs Web 服务。

我添加了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>

在我的资源类里面我有

@Inject
private AuthenticationTokenService authenticationTokenService;

在我的服务类中,我有:

@Inject
private AuthenticationTokenIssuer tokenIssuer;

@Inject
private AuthenticationTokenParser tokenParser;

在这两个类中我有

@Inject
private AuthenticationTokenSettings settings;

我猜我的问题是因为AuthenticationTokenSettings中的成员

@Inject
@Config("token")
private String token;

这些是通过属性对象从文件中注入限定符@Config。

我写了一个 InjectionResolver 类来解析

@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$2@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$2@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 依赖项,因为在我为 jersey 测试添加 maven 依赖项后,我现有的 soap 类放弃了编译,我不明白为什么。 我不知道我的问题是关于这个的。

<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>

【问题讨论】:

  • 在运行应用程序时是否有效?
  • 另外,为什么要TypeLiteral&lt;InjectionResolver&lt;Configurable&gt;&gt;?不应该是配置吗?那是你的注释
  • 它在 tomee 上运行,对于第二个问题,这是一个错字对不起。我尝试了字段注入和构造函数注入,但仍然无法使其在球衣测试中正常工作。
  • 当我把它转换成 ctr.注入并绑定为AuthenticationTokenService authenticationTokenService = new AuthenticationTokenService( Long.valueOf(properties.getProperty("authentication.jwt.validFor")), Integer.valueOf(properties.getProperty("authentication.jwt.refreshLimit")), new AuthenticationTokenIssuer(authenticationTokenSettings), new AuthenticationTokenParser(authenticationTokenSettings)); bind(authenticationTokenService). to(AuthenticationTokenService.class);
  • 但是上面的解决方案看起来不像是最佳实践,此外,正如我在原始问题中所说的那样,该应用程序不能以这种方式工作。我不确定这是否与依赖关系有关?任何帮助将不胜感激

标签: java jax-rs jersey-test-framework


【解决方案1】:

我创建了一个扩展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"));

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-05-27
    • 1970-01-01
    • 2014-02-20
    • 1970-01-01
    • 2015-04-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多