Quarkus 与 Microstream - 类加载器问题

问题描述

我试图让 Microstream 与 Quarkus 一起运行,但 Microstream 无法找到我的 DaTaroot 类。 缺少类型所需的类型处理程序的运行时类型:org.acme.getting.started.DaTaroot

该问题仅在使用 quarkus:dev 时出现。 测试(使用和不使用 @QuarkusTest 注释)并在 Docker 中运行应用程序工作正常。

2021-01-26 10:14:31,831 ERROR [io.qua.run.Application] (Quarkus Main Thread) Failed to start application (with profile dev): one.microstream.persistence.exceptions.PersistenceException: Missing runtime type for required type handler for type: org.acme.getting.started.DaTaroot
at one.microstream.persistence.types.PersistenceTypeHandlerManager$Default.validateExistingType(PersistenceTypeHandlerManager.java:370)
at one.microstream.persistence.types.PersistenceTypeHandlerManager$Default.ensureTypeHandler(PersistenceTypeHandlerManager.java:420)
at one.microstream.persistence.types.PersistenceTypeHandlerManager$Default.lambda$2(PersistenceTypeHandlerManager.java:465)
at one.microstream.collections.ChainStorageStrong.iterate(ChainStorageStrong.java:1315)
at one.microstream.collections.HashEnum.iterate(HashEnum.java:650)
at one.microstream.persistence.types.PersistenceTypeHandlerManager$Default.ensureTypeHandlers(PersistenceTypeHandlerManager.java:464)
at one.microstream.persistence.types.PersistenceTypeHandlerManager$Default.ensureTypeHandlersByTypeIds(PersistenceTypeHandlerManager.java:455)
at one.microstream.storage.types.EmbeddedStorageManager$Default.ensurerequiredTypeHandlers(EmbeddedStorageManager.java:301)
at one.microstream.storage.types.EmbeddedStorageManager$Default.start(EmbeddedStorageManager.java:213)
at one.microstream.storage.types.EmbeddedStorageManager$Default.start(EmbeddedStorageManager.java:1)
at org.acme.getting.started.App.createStorageManager(App.java:48)
at org.acme.getting.started.App.storageManager(App.java:68)
at org.acme.getting.started.App.init(App.java:87)
at org.acme.getting.started.App_Observer_init_c6e577ab5da11c32214e7d0c965f6089ddc75405.notify(App_Observer_init_c6e577ab5da11c32214e7d0c965f6089ddc75405.zig:147)
at io.quarkus.arc.impl.EventImpl$Notifier.notifyObservers(EventImpl.java:282)
at io.quarkus.arc.impl.EventImpl$Notifier.notify(EventImpl.java:267)
at io.quarkus.arc.impl.EventImpl.fire(EventImpl.java:69)
at io.quarkus.arc.runtime.LifecycleEventRunner.fireStartupEvent(LifecycleEventRunner.java:23)
at io.quarkus.arc.runtime.ArcRecorder.handleLifecycleEvents(ArcRecorder.java:60)
at io.quarkus.deployment.steps.LifecycleEventsBuildStep$startupEvent-858218658.deploy_0(LifecycleEventsBuildStep$startupEvent-858218658.zig:81)
at io.quarkus.deployment.steps.LifecycleEventsBuildStep$startupEvent-858218658.deploy(LifecycleEventsBuildStep$startupEvent-858218658.zig:40)
at io.quarkus.runner.ApplicationImpl.doStart(ApplicationImpl.zig:620)
at io.quarkus.runtime.Application.start(Application.java:90)
at io.quarkus.runtime.ApplicationLifecycleManager.run(ApplicationLifecycleManager.java:97)
at io.quarkus.runtime.Quarkus.run(Quarkus.java:66)
at io.quarkus.runtime.Quarkus.run(Quarkus.java:42)
at io.quarkus.runtime.Quarkus.run(Quarkus.java:119)
at io.quarkus.runner.GeneratedMain.main(GeneratedMain.zig:29)
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 io.quarkus.runner.bootstrap.StartupActionImpl$3.run(StartupActionImpl.java:134)
at java.base/java.lang.Thread.run(Thread.java:832)

根据此线程:https://forum.microstream.one/?qa=99/still-not-loading-now-using-existing-root-instead 是类加载器的问题。

将 ClassloaderProvide for Microstream 设置为 Thread.currentThread().getContextClassLoader() 就像这里描述的 https://manual.docs.microstream.one/data-store/customizing/custom-class-loader 和这里的 https://quarkus.io/guides/class-loading-reference 没有解决问题。

如果有人知道如何解决这个问题,那就太好了。

我在 github 上有一个示例存储库:https://github.com/fleigm/quarkus-microstream-test

解决方法

MicroStream 使用反射。要使其与 GraalVM 本机一起使用,您必须将所有将与 MicroStream 一起存储的类列入白名单。

https://www.graalvm.org/reference-manual/native-image/Reflection/#manual-configuration

这是一个例子:

https://github.com/microstream-one/example-graalvm-native/tree/master/graalvm-native