quarkusio / quarkus

Quarkus: Supersonic Subatomic Java.
https://quarkus.io
Apache License 2.0
13.57k stars 2.63k forks source link

com.oracle.svm.core.jdk.unsupportedfeatureerror: SerializationConstructorAccessor class not found for declaringClass: java.time.Ser #43088

Open crey93 opened 1 week ago

crey93 commented 1 week ago

Describe the bug

Hi there, hoping you're doing well. I'm encountering an issue when running my application using Quarkus/GraalVM native compilation. Specifically, I'm seeing the following error related to java.time.Ser when deserializing objects from a cache.

  1. I'm working with Quarkus and implementing Infinispan Cache, and for the marshalling processor i'm using the GenericJBossMarshaller

    • Note: The cache doesn't have the possibility to change for another marshalling process like protobuf.
  2. By the native compile i create the runner to run into a OCP cluster: ./mvnw clean package -Pnative -Dquarkus.native.container-build=trueMore details

  3. The application runs fine locally as a Quarkus project.

  4. The issue comes after run the native compiled artefact.

  5. The cache data, is a xml object where the LocalDateTime fields are stored as ("java.time.Ser").

I've tried everything around this: Collect data with the tracer agent and get the native-image files and put into the:

META-INF/native-image//

As mentioned here

The received exception:.

 com.oracle.svm.core.jdk.UnsupportedFeatureError: SerializationConstructorAccessor class not found for declaringClass: java.time.Ser (targetConstructorClass: java.lang.Object). Usually adding java.time.Ser to serialization-config.json fixes the problem.
    at org.graalvm.nativeimage.builder/com.oracle.svm.core.util.VMError.unsupportedFeature(VMError.java:121)
    at org.graalvm.nativeimage.builder/com.oracle.svm.core.reflect.serialize.SerializationSupport.getSerializationConstructorAccessor(SerializationSupport.java:163)
    at java.base@21.0.2/jdk.internal.reflect.MethodAccessorGenerator.generateSerializationConstructor(MethodAccessorGenerator.java:66)
    at java.base@21.0.2/jdk.internal.reflect.MethodAccessorGenerator.generateSerializationConstructor(MethodAccessorGenerator.java:54)
    at java.base@21.0.2/jdk.internal.reflect.ReflectionFactory.generateConstructor(ReflectionFactory.java:420)
    at java.base@21.0.2/jdk.internal.reflect.ReflectionFactory.newConstructorForSerialization(ReflectionFactory.java:333)
    at jdk.unsupported@21.0.2/sun.reflect.ReflectionFactory.newConstructorForSerialization(ReflectionFactory.java:100)
    at org.jboss.marshalling.reflect.JDKSpecific.newConstructorForSerialization(JDKSpecific.java:116)
    at org.jboss.marshalling.reflect.SerializableClass.<init>(SerializableClass.java:85)
    at org.jboss.marshalling.reflect.SerializableClassRegistry$1.computeValue(SerializableClassRegistry.java:62)
    at org.jboss.marshalling.reflect.SerializableClassRegistry$1.computeValue(SerializableClassRegistry.java:59)
    at java.base@21.0.2/java.lang.ClassValue.get(JavaLangSubstitutions.java:770)
    at org.jboss.marshalling.reflect.SerializableClassRegistry.lookup(SerializableClassRegistry.java:83)
    at org.jboss.marshalling.river.RiverUnmarshaller.doReadNewObject(RiverUnmarshaller.java:1432)
    at org.jboss.marshalling.river.RiverUnmarshaller.doReadObject(RiverUnmarshaller.java:298)
    at org.jboss.marshalling.river.RiverUnmarshaller.doReadObject(RiverUnmarshaller.java:246)
    at org.jboss.marshalling.river.RiverUnmarshaller.readFields(RiverUnmarshaller.java:1918)
    at org.jboss.marshalling.river.RiverUnmarshaller.doInitSerializable(RiverUnmarshaller.java:1831)
    at org.jboss.marshalling.river.RiverUnmarshaller.doInitSerializable(RiverUnmarshaller.java:1777)
    at org.jboss.marshalling.river.RiverUnmarshaller.doReadNewObject(RiverUnmarshaller.java:1421)
    at org.jboss.marshalling.river.RiverUnmarshaller.doReadObject(RiverUnmarshaller.java:298)
    at org.jboss.marshalling.river.RiverUnmarshaller.doReadObject(RiverUnmarshaller.java:246)
    at org.jboss.marshalling.river.RiverUnmarshaller.doReadCollectionObject(RiverUnmarshaller.java:202)
    at org.jboss.marshalling.river.RiverUnmarshaller.readCollectionData(RiverUnmarshaller.java:876)
    at org.jboss.marshalling.river.RiverUnmarshaller.doReadObject(RiverUnmarshaller.java:752)
    at org.jboss.marshalling.river.RiverUnmarshaller.doReadObject(RiverUnmarshaller.java:246)
    at org.jboss.marshalling.river.RiverUnmarshaller.readFields(RiverUnmarshaller.java:1918)
    at org.jboss.marshalling.river.RiverUnmarshaller.doInitSerializable(RiverUnmarshaller.java:1831)
    at org.jboss.marshalling.river.RiverUnmarshaller.doReadNewObject(RiverUnmarshaller.java:1421)
    at org.jboss.marshalling.river.RiverUnmarshaller.doReadObject(RiverUnmarshaller.java:298)
    at org.jboss.marshalling.river.RiverUnmarshaller.doReadObject(RiverUnmarshaller.java:231)
    at org.jboss.marshalling.AbstractObjectInput.readObject(AbstractObjectInput.java:41)
    at org.infinispan.jboss.marshalling.commons.AbstractJBossMarshaller.objectFromObjectStream(AbstractJBossMarshaller.java:135)
    at org.infinispan.jboss.marshalling.commons.AbstractJBossMarshaller.objectFromByteBuffer(AbstractJBossMarshaller.java:113)
    at org.infinispan.commons.marshall.AbstractMarshaller.objectFromByteBuffer(AbstractMarshaller.java:82)
    at org.infinispan.client.hotrod.marshall.MarshallerUtil.bytes2obj(MarshallerUtil.java:58)
    at org.infinispan.client.hotrod.DataFormat$DataFormatImpl.bytesToValue(DataFormat.java:104)
    at org.infinispan.client.hotrod.DataFormat.valueToObj(DataFormat.java:219)
    at org.infinispan.client.hotrod.impl.operations.GetOperation.acceptResponse(GetOperation.java:45)
    at org.infinispan.client.hotrod.impl.transport.netty.HeaderDecoder.decode(HeaderDecoder.java:153)
    at org.infinispan.client.hotrod.impl.transport.netty.HintedReplayingDecoder.callDecode(HintedReplayingDecoder.java:94)
    at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:290)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:444)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420)
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412)
    at io.netty.handler.timeout.IdleStateHandler.channelRead(IdleStateHandler.java:289)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:442)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420)
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412)
    at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:440)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420)
    at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919)
    at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:166)
    at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:788)
    at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:724)
    at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:650)
    at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:562)
    at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:997)
    at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
    at java.base@21.0.2/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
    at java.base@21.0.2/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
    at java.base@21.0.2/java.lang.Thread.runWith(Thread.java:1596)
    at java.base@21.0.2/java.lang.Thread.run(Thread.java:1583)
    at org.graalvm.nativeimage.builder/com.oracle.svm.core.thread.PlatformThreads.threadStartRoutine(PlatformThreads.java:833)
    at org.graalvm.nativeimage.builder/com.oracle.svm.core.posix.thread.PosixPlatformThreads.pthreadStartRoutine(PosixPlatformThreads.java:211)

Expected behavior

By the implementation of quarkus native tips Specially the RegisterForReflection

Should be enough to register the desired classes for the Quarkus native compilation. But it doesn't work.

Actual behavior

When i get a serialized data from the cache, there is an error deserializing an object of type java.time.Ser

Unless you add this block code at the Runtime (on any class):

import org.jboss.marshalling.reflect.SerializableClass;
import org.jboss.marshalling.reflect.SerializableClassRegistry;

class Scratch {
    public static final SerializableClass info;

    static {
        try {
            info = SerializableClassRegistry.getInstance().lookup(Class.forName("java.time.Ser"));
        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        }
    }
}

How to Reproduce?

No response

Output of uname -a or ver

No response

Output of java -version

21.0.4-graalce

Quarkus version or git rev

3.8.4 (LTS)

Build tool (ie. output of mvnw --version or gradlew --version)

No response

Additional information

You can find more information of the bug on this support chat

quarkus-bot[bot] commented 1 week ago

You added a link to a Zulip discussion, please make sure the description of the issue is comprehensive and doesn't require accessing Zulip

This message is automatically generated by a bot.

dmlloyd commented 1 week ago

The fix would be to have some generated class or Feature which reads the list of classes in the serialization config and the annotated-for-reflection classes, and keeps a strong reference to all of the org.jboss.marshalling.reflect.SerializableClass instances in its static initializer (by way of SerializableClassRegistry#lookup as shown in the workaround).