当前位置: 首页 > 知识库问答 >
问题:

引用@ConfigMapping对象的CDI单例的JAR-RS过滤器注入在Quarkus中失败

薛高澹
2023-03-14

我尝试使用最新的Qarkus配置工具:@ConfigMapping,所以我定义了一个GreetingConfig对象:

@ConfigMapping(prefix = "org.acme.greeting")
public interface GreetingConfig {
    String prefix();
}

该配置被注入到CDI Singleton中:

@Singleton
public class GreetingService {

    @Inject GreetingConfig config;

    public String greet(String user) {
        return config.prefix().concat(" - Hello ").concat(user).concat(" !!");
    }
}

单例被注入到JAX-RS过滤器和JAX-RS资源中

@Provider
public class GreetingFilter implements ContainerRequestFilter {

    private static final Logger LOGGER = Logger.getLogger(GreetingFilter.class.getName());

    @Inject GreetingService service;

    @Override
    public void filter(ContainerRequestContext requestContext) throws IOException {
        LOGGER.log(Level.INFO, service.greet("Quarkus"));
    }
}
@Path("/hello")
public class GreetingResource {

    @Inject GreetingService service;

    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public String hello(@QueryParam("user") @DefaultValue("Quarkus") String user) {
        return service.greet(user);
    }
}

application.properties文件还包含:

org.acme.greeting.prefix=ACME Greetings

应用程序在启动时崩溃:

java.lang.RuntimeException: java.lang.ExceptionInInitializerError

    at io.quarkus.test.junit.QuarkusTestExtension.throwBootFailureException(QuarkusTestExtension.java:712)
    at io.quarkus.test.junit.QuarkusTestExtension.interceptTestClassConstructor(QuarkusTestExtension.java:785)
    at org.junit.jupiter.engine.execution.ExecutableInvoker.lambda$invoke$0(ExecutableInvoker.java:105)
    at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106)
    at org.junit.jupiter.api.extension.InvocationInterceptor.interceptTestClassConstructor(InvocationInterceptor.java:72)
    at org.junit.jupiter.engine.execution.ExecutableInvoker.lambda$invoke$0(ExecutableInvoker.java:105)
    at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106)
    at org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:64)
    at org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:45)
    at org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:37)
    at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:104)
    at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:77)
    at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.invokeTestClassConstructor(ClassBasedTestDescriptor.java:342)
    at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.instantiateTestClass(ClassBasedTestDescriptor.java:289)
    at org.junit.jupiter.engine.descriptor.ClassTestDescriptor.instantiateTestClass(ClassTestDescriptor.java:79)
    at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.instantiateAndPostProcessTestInstance(ClassBasedTestDescriptor.java:267)
    at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$testInstancesProvider$2(ClassBasedTestDescriptor.java:259)
    at java.base/java.util.Optional.orElseGet(Optional.java:369)
    at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$testInstancesProvider$3(ClassBasedTestDescriptor.java:258)
    at org.junit.jupiter.engine.execution.TestInstancesProvider.getTestInstances(TestInstancesProvider.java:31)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$prepare$0(TestMethodTestDescriptor.java:101)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.prepare(TestMethodTestDescriptor.java:100)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.prepare(TestMethodTestDescriptor.java:65)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$prepare$1(NodeTestTask.java:111)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.prepare(NodeTestTask.java:111)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:79)
    at java.base/java.util.ArrayList.forEach(ArrayList.java:1541)
    at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:143)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:129)
    at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:127)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:126)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:84)
    at java.base/java.util.ArrayList.forEach(ArrayList.java:1541)
    at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:143)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:129)
    at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:127)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:126)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:84)
    at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:32)
    at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
    at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:51)
    at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:108)
    at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:88)
    at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:54)
    at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:67)
    at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:52)
    at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:96)
    at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:75)
    at com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:71)
    at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)
    at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:235)
    at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:54)
Caused by: java.lang.ExceptionInInitializerError
    at java.base/java.lang.Class.forName0(Native Method)
    at java.base/java.lang.Class.forName(Class.java:398)
    at io.quarkus.runner.bootstrap.StartupActionImpl.run(StartupActionImpl.java:165)
    at io.quarkus.test.junit.QuarkusTestExtension.doJavaStart(QuarkusTestExtension.java:380)
    at io.quarkus.test.junit.QuarkusTestExtension.ensureStarted(QuarkusTestExtension.java:680)
    at io.quarkus.test.junit.QuarkusTestExtension.beforeAll(QuarkusTestExtension.java:727)
    at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$invokeBeforeAllCallbacks$8(ClassBasedTestDescriptor.java:368)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.invokeBeforeAllCallbacks(ClassBasedTestDescriptor.java:368)
    at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.before(ClassBasedTestDescriptor.java:192)
    at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.before(ClassBasedTestDescriptor.java:78)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:136)
    ... 31 more
Caused by: java.lang.RuntimeException: Failed to start quarkus
    at io.quarkus.runner.ApplicationImpl.<clinit>(ApplicationImpl.zig:225)
    ... 43 more
Caused by: java.lang.RuntimeException: Error injecting org.acme.GreetingService org.acme.api.filter.GreetingFilter.service
    at org.acme.api.filter.GreetingFilter_Bean.create(GreetingFilter_Bean.zig:148)
    at org.acme.api.filter.GreetingFilter_Bean.create(GreetingFilter_Bean.zig:171)
    at io.quarkus.arc.impl.AbstractSharedContext.createInstanceHandle(AbstractSharedContext.java:96)
    at io.quarkus.arc.impl.AbstractSharedContext$1.get(AbstractSharedContext.java:29)
    at io.quarkus.arc.impl.AbstractSharedContext$1.get(AbstractSharedContext.java:26)
    at io.quarkus.arc.impl.LazyValue.get(LazyValue.java:26)
    at io.quarkus.arc.impl.ComputingCache.computeIfAbsent(ComputingCache.java:69)
    at io.quarkus.arc.impl.AbstractSharedContext.get(AbstractSharedContext.java:26)
    at org.acme.api.filter.GreetingFilter_Bean.get(GreetingFilter_Bean.zig:203)
    at org.acme.api.filter.GreetingFilter_Bean.get(GreetingFilter_Bean.zig:219)
    at io.quarkus.arc.impl.ArcContainerImpl.beanInstanceHandle(ArcContainerImpl.java:433)
    at io.quarkus.arc.impl.ArcContainerImpl.beanInstanceHandle(ArcContainerImpl.java:446)
    at io.quarkus.arc.impl.ArcContainerImpl$1.get(ArcContainerImpl.java:269)
    at io.quarkus.arc.impl.ArcContainerImpl$1.get(ArcContainerImpl.java:266)
    at io.quarkus.resteasy.common.runtime.QuarkusConstructorInjector.construct(QuarkusConstructorInjector.java:39)
    at org.jboss.resteasy.core.providerfactory.ResteasyProviderFactoryImpl.injectedInstance(ResteasyProviderFactoryImpl.java:1399)
    at org.jboss.resteasy.core.interception.jaxrs.JaxrsInterceptorRegistryImpl$AbstractInterceptorFactory.createInterceptor(JaxrsInterceptorRegistryImpl.java:150)
    at org.jboss.resteasy.core.interception.jaxrs.JaxrsInterceptorRegistryImpl$OnDemandInterceptorFactory.initialize(JaxrsInterceptorRegistryImpl.java:168)
    at org.jboss.resteasy.core.interception.jaxrs.JaxrsInterceptorRegistryImpl$OnDemandInterceptorFactory.checkInitialize(JaxrsInterceptorRegistryImpl.java:183)
    at org.jboss.resteasy.core.interception.jaxrs.JaxrsInterceptorRegistryImpl$OnDemandInterceptorFactory.getInterceptor(JaxrsInterceptorRegistryImpl.java:193)
    at org.jboss.resteasy.core.interception.jaxrs.JaxrsInterceptorRegistryImpl$AbstractInterceptorFactory.postMatch(JaxrsInterceptorRegistryImpl.java:131)
    at org.jboss.resteasy.core.interception.jaxrs.JaxrsInterceptorRegistryImpl.postMatch(JaxrsInterceptorRegistryImpl.java:288)
    at org.jboss.resteasy.core.interception.jaxrs.ContainerRequestFilterRegistryImpl.postMatch(ContainerRequestFilterRegistryImpl.java:30)
    at org.jboss.resteasy.core.interception.jaxrs.ContainerRequestFilterRegistryImpl.postMatch(ContainerRequestFilterRegistryImpl.java:12)
    at org.jboss.resteasy.core.ResourceMethodInvoker.<init>(ResourceMethodInvoker.java:142)
    at org.jboss.resteasy.core.ResourceMethodRegistry.processMethod(ResourceMethodRegistry.java:381)
    at org.jboss.resteasy.core.ResourceMethodRegistry.register(ResourceMethodRegistry.java:308)
    at org.jboss.resteasy.core.ResourceMethodRegistry.addResourceFactory(ResourceMethodRegistry.java:259)
    at org.jboss.resteasy.core.ResourceMethodRegistry.addResourceFactory(ResourceMethodRegistry.java:227)
    at org.jboss.resteasy.core.ResourceMethodRegistry.addResourceFactory(ResourceMethodRegistry.java:208)
    at org.jboss.resteasy.core.ResourceMethodRegistry.addResourceFactory(ResourceMethodRegistry.java:192)
    at org.jboss.resteasy.core.ResourceMethodRegistry.addResourceFactory(ResourceMethodRegistry.java:175)
    at org.jboss.resteasy.core.ResourceMethodRegistry.addPerRequestResource(ResourceMethodRegistry.java:87)
    at org.jboss.resteasy.core.ResteasyDeploymentImpl.registerResources(ResteasyDeploymentImpl.java:518)
    at org.jboss.resteasy.core.ResteasyDeploymentImpl.registration(ResteasyDeploymentImpl.java:475)
    at org.jboss.resteasy.core.ResteasyDeploymentImpl.startInternal(ResteasyDeploymentImpl.java:164)
    at org.jboss.resteasy.core.ResteasyDeploymentImpl.start(ResteasyDeploymentImpl.java:121)
    at io.quarkus.resteasy.runtime.standalone.ResteasyStandaloneRecorder.staticInit(ResteasyStandaloneRecorder.java:37)
    at io.quarkus.deployment.steps.ResteasyStandaloneBuildStep$staticInit-210558872.deploy_0(ResteasyStandaloneBuildStep$staticInit-210558872.zig:897)
    at io.quarkus.deployment.steps.ResteasyStandaloneBuildStep$staticInit-210558872.deploy(ResteasyStandaloneBuildStep$staticInit-210558872.zig:40)
    at io.quarkus.runner.ApplicationImpl.<clinit>(ApplicationImpl.zig:205)
    ... 43 more
Caused by: java.lang.RuntimeException: Error injecting org.acme.config.GreetingConfig org.acme.GreetingService.config
    at org.acme.GreetingService_Bean.create(GreetingService_Bean.zig:199)
    at org.acme.GreetingService_Bean.create(GreetingService_Bean.zig:222)
    at io.quarkus.arc.impl.AbstractSharedContext.createInstanceHandle(AbstractSharedContext.java:96)
    at io.quarkus.arc.impl.AbstractSharedContext$1.get(AbstractSharedContext.java:29)
    at io.quarkus.arc.impl.AbstractSharedContext$1.get(AbstractSharedContext.java:26)
    at io.quarkus.arc.impl.LazyValue.get(LazyValue.java:26)
    at io.quarkus.arc.impl.ComputingCache.computeIfAbsent(ComputingCache.java:69)
    at io.quarkus.arc.impl.AbstractSharedContext.get(AbstractSharedContext.java:26)
    at org.acme.GreetingService_Bean.get(GreetingService_Bean.zig:254)
    at org.acme.GreetingService_Bean.get(GreetingService_Bean.zig:270)
    at org.acme.api.filter.GreetingFilter_Bean.create(GreetingFilter_Bean.zig:131)
    ... 83 more
Caused by: java.util.NoSuchElementException: SRCFG00027: Could not find a mapping for org.acme.config.GreetingConfig
    at io.smallrye.config.ConfigMappings.getConfigMapping(ConfigMappings.java:73)
    at io.smallrye.config.SmallRyeConfig.getConfigMapping(SmallRyeConfig.java:423)
    at io.quarkus.arc.runtime.ConfigMappingCreator.create(ConfigMappingCreator.java:28)
    at org.acme.config.GreetingConfig_04302c935a6cb43e5f29ca4271833ab99b620b3b_Synthetic_Bean.create(GreetingConfig_04302c935a6cb43e5f29ca4271833ab99b620b3b_Synthetic_Bean.zig:128)
    at org.acme.config.GreetingConfig_04302c935a6cb43e5f29ca4271833ab99b620b3b_Synthetic_Bean.get(GreetingConfig_04302c935a6cb43e5f29ca4271833ab99b620b3b_Synthetic_Bean.zig:159)
    at org.acme.config.GreetingConfig_04302c935a6cb43e5f29ca4271833ab99b620b3b_Synthetic_Bean.get(GreetingConfig_04302c935a6cb43e5f29ca4271833ab99b620b3b_Synthetic_Bean.zig:182)
    at io.quarkus.arc.impl.CurrentInjectionPointProvider.get(CurrentInjectionPointProvider.java:52)
    at org.acme.GreetingService_Bean.create(GreetingService_Bean.zig:182)
    ... 93 more

JAR-RS资源中的注入适用于服务的任何bean类型(@ApplicationScope或@Singleton),但在过滤器中,只能注入@ApplicationScope bean,以避免运行时异常。。。

我们不能在JAX-RS@提供程序(过滤器或BodyWritter)中注入带有配置映射的伪范围bean,这是一个错误还是正常的?

共有2个答案

方焱
2023-03-14

基于Marek回答(感谢解决方案;-)),也可以选择在Service Bean中的配置对象上使用基于实例的注入,并在提供程序中保留经典注入...

也许让bean知道它的配置注入并处理实例对象本身是更好的设计方法,顺便说一句,初始想法是一样的,避免了运行时问题,而配置对象在使用实例的提供程序实例化时不可用。

@Singleton
public class GreetingService {

    @Inject Instance<GreetingConfig> config;

    public String greet(String user) {
        return config.get().prefix().concat(" - Hello ").concat(user).concat(" !!");
    }
}
习旻
2023-03-14

不幸的是,这不是一个错误。这是jax rs的一个特性:-)

  1. 我检查了您的配置类,它与CDI beans一起工作

解决方案是将服务放入实例类。

@Inject Instance<GreetingService> service;

@Override
public void filter(ContainerRequestContext requestContext) throws IOException {
   LOGGER.log(Level.INFO, service.get().greet("Quarkus"));
}

它将注入委托给后期阶段(运行时的一种惰性注入)。

我在这里找到了更多信息https://javaee.github.io/javaee-spec/javadocs/javax/enterprise/inject/Instance.html

 类似资料:
  • 关于创建支持CDI的shiro Realms的信息已经足够多了。在我的情况下,我需要CDI在自定义shiro过滤器,这可能吗? 西罗。伊尼

  • 我想在Quarkus中注入bean一个静态编程语言字段。示例文件看起来像 构造函数参数注入工作正常,但字段仍处于未初始化状态。 控制台输出: 有可能在科特林的Quarkus中使用CDI场注入吗?如果是,需要为注射设置什么才能工作? 我是从uberjar运行应用程序,而不是从本地图像运行。 jar包含生成的类org.example.InjectDemo_Bean包含一个方法的分解版本,该方法不显示任

  • 我正在尝试将一个无状态的EJB注入我的EntityListner。调用了我的EntityListener的方法,但注入的EJB解析为,因此引发了NullPointerException。 我在这里发现的前面的问题是关于这个问题的,JPA只提供JPA2.1上的CDI,但不提供JPA2.0上的CDI,但我使用的是JPA2.1。那么这里还有什么问题呢? 将我的EJB注入到其他会话bean中运行良好,无论

  • 问题内容: 由于JPA 2.0不支持注入EntityListener(将使用JPA 2.1),因此决定使用JNDI查找来获取,并通过它来获取登录用户。我定义了一个与此类似的东西: 在会话范围内以以下方式管理用户: 我想知道这种方法有什么缺点或要注意的地方。性能吞吐量?当有多个登录用户在其自己的范围内同时更新实体时,会发生什么情况? Hibernate JPA 2.0 缝焊CDI Glassfish

  • 问题内容: 考虑简单的Django模型和: 使用参与者总数来注释事件查询很容易: 如何用筛选的参与者计数进行注释? 我需要查询所有事件,而与参与者人数无关,例如,我不需要按带注释的结果进行过滤。如果有参与者,那没关系,我只需要带有0注释的值即可。 文档中的示例在这里不起作用,因为它从查询中排除了对象,而不是使用注释了对象0。 更新。Django 1.8具有新的条件表达式功能,因此我们现在可以像这样

  • 本文向大家介绍AngularJS 过滤器的简单实例,包括了AngularJS 过滤器的简单实例的使用技巧和注意事项,需要的朋友参考一下 AngularJS 过滤器 过滤器可以使用一个管道字符(|)添加到表达式和指令中。 AngularJS 过滤器 AngularJS 过滤器可用于转换数据: 过滤器 描述 currency 格式化数字为货币格式。 filter 从数组项中选择一个子集。 lowerc