如何在Kotlin的Quarkus中使用CDI场注入?

问题描述 投票:0回答:1

我想在Quarkus的Kotlin田地中注入豆类。示例文件看起来像

package org.example

import com.google.inject.Inject
import javax.enterprise.inject.spi.BeanManager
import javax.ws.rs.GET
import javax.ws.rs.Path

@Path("injectDemo")
open class InjectDemo @Inject constructor(val bm1: BeanManager) {

    @field:Inject
    protected open lateinit var bm2: BeanManager

    @GET
    fun demo() {
        println("bm1 $bm1")
        println("bm2 $bm2")
    }
}

构造函数参数注入工作正常,但是字段bm2仍未初始化。

控制台输出:

bm1 io.quarkus.arc.impl.BeanManagerImpl@6b7ac97f
2020-05-21 03:45:11,670 ERROR [io.qua.ver.htt.run.QuarkusErrorHandler] (executor-thread-1) HTTP Request to /injectDemo failed, error id: ac118d6b-a26e-47e7-8c10-12e6a96e50ba-3: org.jboss.resteasy.spi.UnhandledException: kotlin.UninitializedPropertyAccessException: lateinit property bm2 has not been initialized
    at org.jboss.resteasy.core.ExceptionHandler.handleApplicationException(ExceptionHandler.java:106)
    at org.jboss.resteasy.core.ExceptionHandler.handleException(ExceptionHandler.java:372)
    at org.jboss.resteasy.core.SynchronousDispatcher.writeException(SynchronousDispatcher.java:216)
    at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:515)
    at org.jboss.resteasy.core.SynchronousDispatcher.lambda$invoke$4(SynchronousDispatcher.java:259)
    at org.jboss.resteasy.core.SynchronousDispatcher.lambda$preprocess$0(SynchronousDispatcher.java:160)
    at org.jboss.resteasy.core.interception.jaxrs.PreMatchContainerRequestContext.filter(PreMatchContainerRequestContext.java:362)
    at org.jboss.resteasy.core.SynchronousDispatcher.preprocess(SynchronousDispatcher.java:163)
    at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:245)
    at io.quarkus.resteasy.runtime.standalone.RequestDispatcher.service(RequestDispatcher.java:73)
    at io.quarkus.resteasy.runtime.standalone.VertxRequestHandler.dispatch(VertxRequestHandler.java:123)
    at io.quarkus.resteasy.runtime.standalone.VertxRequestHandler.access$000(VertxRequestHandler.java:36)
    at io.quarkus.resteasy.runtime.standalone.VertxRequestHandler$1.run(VertxRequestHandler.java:87)
    at org.jboss.threads.ContextClassLoaderSavingRunnable.run(ContextClassLoaderSavingRunnable.java:35)
    at org.jboss.threads.EnhancedQueueExecutor.safeRun(EnhancedQueueExecutor.java:2046)
    at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.doRunTask(EnhancedQueueExecutor.java:1578)
    at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1452)
    at org.jboss.threads.DelegatingRunnable.run(DelegatingRunnable.java:29)
    at org.jboss.threads.ThreadLocalResettingRunnable.run(ThreadLocalResettingRunnable.java:29)
    at java.base/java.lang.Thread.run(Thread.java:832)
    at org.jboss.threads.JBossThread.run(JBossThread.java:479)
Caused by: kotlin.UninitializedPropertyAccessException: lateinit property bm2 has not been initialized
    at org.example.InjectDemo.getBm2(InjectDemo.kt:12)
    at org.example.InjectDemo.demo(InjectDemo.kt:17)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:564)
    at org.jboss.resteasy.core.MethodInjectorImpl.invoke(MethodInjectorImpl.java:167)
    at org.jboss.resteasy.core.MethodInjectorImpl.invoke(MethodInjectorImpl.java:130)
    at org.jboss.resteasy.core.ResourceMethodInvoker.internalInvokeOnTarget(ResourceMethodInvoker.java:621)
    at org.jboss.resteasy.core.ResourceMethodInvoker.invokeOnTargetAfterFilter(ResourceMethodInvoker.java:487)
    at org.jboss.resteasy.core.ResourceMethodInvoker.lambda$invokeOnTarget$2(ResourceMethodInvoker.java:437)
    at org.jboss.resteasy.core.interception.jaxrs.PreMatchContainerRequestContext.filter(PreMatchContainerRequestContext.java:362)
    at org.jboss.resteasy.core.ResourceMethodInvoker.invokeOnTarget(ResourceMethodInvoker.java:439)
    at org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:400)
    at org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:374)
    at org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:67)
    at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:488)
    ... 17 more

是否有可能在Kotlin的Quarkus中使用CDI场注入?如果是,则需要设置什么才能使注射工作?

我正在从uberjar而不是本地映像运行该应用程序。

jar包含生成的类org.example.InjectDemo_Bean,其中包含方法create()的反汇编版本,该方法未显示对bm2字段进行任何注入的尝试:

    public InjectDemo create(CreationalContext var1) {
        Object var2 = this.injectProviderSupplier1.get();
        CreationalContextImpl var3 = CreationalContextImpl.child((InjectableReferenceProvider)var2, var1);
        Object var4 = ((InjectableReferenceProvider)var2).get((CreationalContext)var3);
        return new InjectDemo((BeanManager)var4);
    }
kotlin cdi inject quarkus
1个回答
0
投票

根据https://quarkus.io/guides/kotlin#cdi-inject-with-kotlin Kotlin批注反射未命中Target批注,这导致注入失败。解决方案是添加字段javax.enterprise.inject.Default批注:

    @field:Default
    @field:Inject
    protected open lateinit var bm2: BeanManager
© www.soinside.com 2019 - 2024. All rights reserved.