2

I'm trying to get Microstream running with Quarkus but Microstream is not able to find my DataRoot class. Missing runtime type for required type handler for type: org.acme.getting.started.DataRoot

The problem only appears when using quarkus:dev. Test (with and without @QuarkusTest annotation) and running the app in Docker works fine.

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)

According to this thread: https://forum.microstream.one/?qa=99/still-not-loading-now-using-existing-root-instead its a problem with the classloader.

Setting ClassloaderProvide for Microstream to Thread.currentThread().getContextClassLoader() like described here https://manual.docs.microstream.one/data-store/customizing/custom-class-loader and here https://quarkus.io/guides/class-loading-reference did not solve the issue.

It would be really nice if someone has an idea how to tackle this issue.

I've an example repo on github: https://github.com/fleigm/quarkus-microstream-test

Fleigm
  • 53
  • 1
  • 4

2 Answers2

4

Had the same issue. By adding the following lines during the configuration, I don't get this error anymore:

// handle changing class definitions at runtime ("hot code replacement" by quarkus by running app in development mode)
foundation.onConnectionFoundation(connectionFoundation ->
                connectionFoundation.setClassLoaderProvider(ClassLoaderProvider.New(Thread.currentThread().getContextClassLoader()))); 

"foundation" is final EmbeddedStorageFoundation<?> foundation. Full example can be found in my GitHub-Repository

felix185
  • 41
  • 3
2

MicroStream uses reflection. To get it working with GraalVM native, you have to whitelist all classes which you will store with MicroStream.

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

Here's an example:

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

fh-ms
  • 21
  • 1
  • Hm, is this really a solution? It doesn't work for me and I thought quarkus:dev is not making use of GraalVM. – mainzelM Jul 26 '21 at 16:16
  • Maybe the problem is that quarkus is changing class definitions at runtime (see https://github.com/microstream-one/microstream/issues/189)? – mainzelM Jul 26 '21 at 16:27