我正在try 使用Kotlin Coroutines运行一个Spring Boot应用程序.当我在JVM模式下执行此命令时,一切都按预期工作,但当我以本机映像执行时,我收到以下错误:

Stacktrace

java.lang.NoSuchMethodException: kotlin.internal.jdk8.JDK8PlatformImplementations.<init>()
        at java.base@17.0.5/java.lang.Class.getConstructor0(DynamicHub.java:3585) ~[CoroutinesAotExample:na]
        at java.base@17.0.5/java.lang.Class.newInstance(DynamicHub.java:626) ~[CoroutinesAotExample:na]
        at kotlin.internal.PlatformImplementationsKt.<clinit>(PlatformImplementations.kt:54) ~[na:na]
        at kotlin.random.Random.<clinit>(Random.kt:271) ~[CoroutinesAotExample:1.7.21-release-272(1.7.21)]
        at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.<init>(CoroutineScheduler.kt:637) ~[CoroutinesAotExample:na]
        at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.<init>(CoroutineScheduler.kt:592) ~[CoroutinesAotExample:na]
        at kotlinx.coroutines.scheduling.CoroutineScheduler.createNewWorker(CoroutineScheduler.kt:481) ~[CoroutinesAotExample:na]
        at kotlinx.coroutines.scheduling.CoroutineScheduler.tryCreateWorker(CoroutineScheduler.kt:439) ~[CoroutinesAotExample:na]
        at kotlinx.coroutines.scheduling.CoroutineScheduler.signalBlockingWork(CoroutineScheduler.kt:420) ~[CoroutinesAotExample:na]
        at kotlinx.coroutines.scheduling.CoroutineScheduler.dispatch(CoroutineScheduler.kt:401) ~[CoroutinesAotExample:na]
        at kotlinx.coroutines.scheduling.SchedulerCoroutineDispatcher.dispatchWithContext$kotlinx_coroutines_core(Dispatcher.kt:103) ~[CoroutinesAotExample:na]
        at kotlinx.coroutines.scheduling.UnlimitedIoScheduler.dispatch(Dispatcher.kt:39) ~[na:na]
        at kotlinx.coroutines.internal.LimitedDispatcher.dispatch(LimitedDispatcher.kt:67) ~[na:na]
        at kotlinx.coroutines.scheduling.DefaultIoScheduler.dispatch(Dispatcher.kt:65) ~[na:na]
        at kotlinx.coroutines.internal.DispatchedContinuationKt.resumeCancellableWith(DispatchedContinuation.kt:322) ~[na:na]
        at kotlinx.coroutines.intrinsics.CancellableKt.startCoroutineCancellable(Cancellable.kt:30) ~[na:na]
        at kotlinx.coroutines.intrinsics.CancellableKt.startCoroutineCancellable$default(Cancellable.kt:25) ~[na:na]
        at kotlinx.coroutines.CoroutineStart.invoke(CoroutineStart.kt:110) ~[CoroutinesAotExample:na]
        at kotlinx.coroutines.AbstractCoroutine.start(AbstractCoroutine.kt:126) ~[CoroutinesAotExample:na]
        at kotlinx.coroutines.BuildersKt__Builders_commonKt.async(Builders.common.kt:91) ~[na:na]
        at kotlinx.coroutines.BuildersKt.async(Unknown Source) ~[na:na]
        at kotlinx.coroutines.BuildersKt__Builders_commonKt.async$default(Builders.common.kt:82) ~[na:na]
        at kotlinx.coroutines.BuildersKt.async$default(Unknown Source) ~[na:na]
        at info.novatec.coroutines.business.ClaimNumberService$generateClaimNumber$1$1.invokeSuspend(ClaimNumberService.kt:16) ~[na:na]
        at info.novatec.coroutines.business.ClaimNumberService$generateClaimNumber$1$1.invoke(ClaimNumberService.kt) ~[na:na]
        at info.novatec.coroutines.business.ClaimNumberService$generateClaimNumber$1$1.invoke(ClaimNumberService.kt) ~[na:na]
        at kotlinx.coroutines.intrinsics.UndispatchedKt.startUndispatchedOrReturn(Undispatched.kt:89) ~[na:na]
        at kotlinx.coroutines.BuildersKt__Builders_commonKt.withContext(Builders.common.kt:169) ~[na:na]
        at kotlinx.coroutines.BuildersKt.withContext(Unknown Source) ~[na:na]
        at info.novatec.coroutines.business.ClaimNumberService$generateClaimNumber$1.invokeSuspend(ClaimNumberService.kt:15) ~[na:na]
        at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33) ~[CoroutinesAotExample:1.7.21-release-272(1.7.21)]
        at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106) ~[CoroutinesAotExample:na]
        at kotlinx.coroutines.EventLoopImplBase.processNextEvent(EventLoop.common.kt:284) ~[CoroutinesAotExample:na]
        at kotlinx.coroutines.BlockingCoroutine.joinBlocking(Builders.kt:85) ~[na:na]
        at kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking(Builders.kt:59) ~[na:na]
        at kotlinx.coroutines.BuildersKt.runBlocking(Unknown Source) ~[na:na]
        at kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking$default(Builders.kt:38) ~[na:na]
        at kotlinx.coroutines.BuildersKt.runBlocking$default(Unknown Source) ~[na:na]
        at info.novatec.coroutines.business.ClaimNumberService.generateClaimNumber(ClaimNumberService.kt:14) ~[CoroutinesAotExample:na]
        at info.novatec.coroutines.api.ClaimNumberController.isClaimNumberValid(ClaimNumberController.kt:23) ~[CoroutinesAotExample:na]
        at java.base@17.0.5/java.lang.reflect.Method.invoke(Method.java:568) ~[CoroutinesAotExample:na]
        at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:207) ~[CoroutinesAotExample:6.0.2]
        at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:152) ~[CoroutinesAotExample:6.0.2]
        at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:117) ~[CoroutinesAotExample:6.0.2]
        at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:884) ~[CoroutinesAotExample:6.0.2]
        at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:797) ~[CoroutinesAotExample:6.0.2]
        at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[CoroutinesAotExample:6.0.2]
        at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1080) ~[CoroutinesAotExample:6.0.2]
        at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:973) ~[CoroutinesAotExample:6.0.2]
        at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1003) ~[CoroutinesAotExample:6.0.2]
        at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:895) ~[CoroutinesAotExample:6.0.2]
        at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:705) ~[CoroutinesAotExample:6.0]
        at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:880) ~[CoroutinesAotExample:6.0.2]
        at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:814) ~[CoroutinesAotExample:6.0]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:223) ~[na:na]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:158) ~[na:na]
        at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) ~[CoroutinesAotExample:10.1.1]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:185) ~[na:na]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:158) ~[na:na]
        at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[CoroutinesAotExample:6.0.2]
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[CoroutinesAotExample:6.0.2]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:185) ~[na:na]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:158) ~[na:na]
        at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[CoroutinesAotExample:6.0.2]
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[CoroutinesAotExample:6.0.2]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:185) ~[na:na]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:158) ~[na:na]
        at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[CoroutinesAotExample:6.0.2]
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[CoroutinesAotExample:6.0.2]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:185) ~[na:na]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:158) ~[na:na]
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:197) ~[na:na]
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97) ~[na:na]
        at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:542) ~[CoroutinesAotExample:10.1.1]
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:119) ~[na:na]
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) ~[CoroutinesAotExample:10.1.1]
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78) ~[na:na]
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:357) ~[na:na]
        at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:400) ~[na:na]
        at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) ~[CoroutinesAotExample:10.1.1]
        at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:861) ~[na:na]
        at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1739) ~[na:na]
        at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52) ~[CoroutinesAotExample:10.1.1]
        at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) ~[na:na]
        at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) ~[na:na]
        at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[na:na]
        at java.base@17.0.5/java.lang.Thread.run(Thread.java:833) ~[CoroutinesAotExample:na]
        at org.graalvm.nativeimage.builder/com.oracle.svm.core.thread.PlatformThreads.threadStartRoutine(PlatformThreads.java:775) ~[CoroutinesAotExample:na]
        at org.graalvm.nativeimage.builder/com.oracle.svm.core.posix.thread.PosixPlatformThreads.pthreadStartRoutine(PosixPlatformThreads.java:203) ~[na:na]

我想添加一个运行时提示,就像在Spring文档中解释的那样.不幸的是,这个类是内部的,我现在不知道如何为Graalvm提供提示

RuntimeHintRegistry

not正在编译,因为kotlin.internal.jdk8.JDK8PlatformImplementations是内部的

import org.springframework.aot.hint.MemberCategory
import org.springframework.aot.hint.RuntimeHints
import org.springframework.aot.hint.RuntimeHintsRegistrar
import kotlin.internal.jdk8.JDK8PlatformImplementations

class CoroutinesAsyncRuntimeHints: RuntimeHintsRegistrar {

    override fun registerHints(hints: RuntimeHints, classLoader: ClassLoader?) {
        hints.reflection().registerType(JDK8PlatformImplementations::class.java, MemberCategory.INVOKE_DECLARED_CONSTRUCTORS)
    }
}

你可以在这里找到一个最小的例子CoroutinesAotExample

你有什么办法为graalvm添加一个手动运行时提示吗?

推荐答案

这个问题已经得到解决:

https://github.com/spring-projects-experimental/spring-native/issues/1646

https://youtrack.jetbrains.com/issue/KT-51579

当前的解决方法是:

META-INF/native-image下创建文件reflect-config.json

内容为reflect-config.json

[
  {
    "name": "kotlin.reflect.jvm.internal.ReflectionFactoryImpl",
    "allDeclaredConstructors":true
  },
  {
    "name": "kotlin.KotlinVersion",
    "allPublicMethods": true,
    "allDeclaredFields":true,
    "allDeclaredMethods":true,
    "allDeclaredConstructors":true
  },
  {
    "name": "kotlin.KotlinVersion[]"
  },
  {
    "name": "kotlin.KotlinVersion$Companion"
  },
  {
    "name": "kotlin.KotlinVersion$Companion[]"
  },
  {
    "name": "kotlin.internal.jdk8.JDK8PlatformImplementations",
    "allPublicMethods": true,
    "allDeclaredFields":true,
    "allDeclaredMethods":true,
    "allDeclaredConstructors":true
  }
]

Kotlin相关问答推荐

测试Compose Multiplatform UI时,为另一个文件设置ComposeRule()

等待下一个值时暂停Kotlin Coroutine

无法访问类kotlin.coroutines.CoroutineContext';.判断模块类路径中是否存在丢失或冲突的依赖项

新的jOOQ Gradle插件无法正确处理自引用关系

为什么Kotlin协程程序即使有延迟也能输出?

如何定义一个函数来接受任何具有特定字段的数据类

Mockk:对同一函数进行两次存根会忽略第一个行为

Kotlin 复制列表中的项目以创建具有相同数据的不同对象的新列表

为什么Kotlin不用static inner class来实现带有object关键字的单例呢?

使用事务时未调用 Kafka ConsumerInterceptor onCommit

通过顺序多米诺骨牌操作列表管理对象的最佳方法是什么?

在 APK META-INF/library_release.kotlin_module 中复制的重复文件

Moshi:解析单个对象或对象列表(kotlin)

Kotlin 中多个 init 块的用例?

模拟异常 - 没有找到答案

如何将map函数应用于Kotlin中的数组并更改其值?

从片段(fragment)中的点击事件启动协同程序

@StringRes、@DrawableRes、@LayoutRes等android注释使用kotlin参数进行判断

目前不支持 Gradle 项目的自动库版本更新.请手动更新您的 build.gradle

Kotlin:在何时使用枚举