当前位置: 首页 > 知识库问答 >
问题:

在Graal中运行时反序列化程序失败

章哲彦
2023-03-14

我有一个Micronaut应用程序,可以构建到GraalVM原生映像中。当我从正常的角度运行应用程序时(也就是说,不使用Graal),它运行得非常好。

但是,当我尝试从Graal运行时,在尝试将字符串反序列化到枚举中时,会出现以下运行时异常:

org.apache.kafka.common.errors.SerializationException: Error deserializing key/value for partition queue.mes.tm_email_processing_result-0 at offset 57. If needed, please seek past the record to continue consumption.
Caused by: io.micronaut.core.serialize.exceptions.SerializationException: Error deserializing object from JSON: Class fts.marketing.utils.deserializers.CampaignEmailStatusDeserializer has no default (no arg) constructor
 at [Source: (byte[])"{"merchant":"Lab6","customerId":729441,"campaignRunId":51,"status":"Sent","messageKey":"70bb5454-8e22-4b37-bba7-83c0dd0cb66f"}"; line: 1, column: 1]
    at io.micronaut.jackson.serialize.JacksonObjectSerializer.deserialize(JacksonObjectSerializer.java:70)
    at io.micronaut.configuration.kafka.serde.JsonSerde.deserialize(JsonSerde.java:79)
    at org.apache.kafka.common.serialization.Deserializer.deserialize(Deserializer.java:60)
    at org.apache.kafka.clients.consumer.internals.Fetcher.parseRecord(Fetcher.java:1264)
    at org.apache.kafka.clients.consumer.internals.Fetcher.access$3600(Fetcher.java:124)
    at org.apache.kafka.clients.consumer.internals.Fetcher$PartitionRecords.fetchRecords(Fetcher.java:1488)
    at org.apache.kafka.clients.consumer.internals.Fetcher$PartitionRecords.access$1600(Fetcher.java:1328)
    at org.apache.kafka.clients.consumer.internals.Fetcher.fetchRecords(Fetcher.java:641)
    at org.apache.kafka.clients.consumer.internals.Fetcher.fetchedRecords(Fetcher.java:602)
    at org.apache.kafka.clients.consumer.KafkaConsumer.pollForFetches(KafkaConsumer.java:1294)
    at org.apache.kafka.clients.consumer.KafkaConsumer.poll(KafkaConsumer.java:1225)
    at org.apache.kafka.clients.consumer.KafkaConsumer.poll(KafkaConsumer.java:1201)
    at io.micronaut.configuration.kafka.processor.KafkaConsumerProcessor.lambda$process$7(KafkaConsumerProcessor.java:393)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)
    at com.oracle.svm.core.thread.JavaThreads.threadStartRoutine(JavaThreads.java:460)
    at com.oracle.svm.core.posix.thread.PosixJavaThreads.pthreadStartRoutine(PosixJavaThreads.java:193)

作为参考,我的反序列化程序如下所示:

public class CampaignEmailStatusDeserializer extends JsonDeserializer<CampaignEmailStatus> {

    @Override
    public CampaignEmailStatus deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
        String readValue = p.getText();
        if (readValue == null) {
            return CampaignEmailStatus.UNKNOWN;
    }

        return Arrays.stream(CampaignEmailStatus.values())
        .filter(status -> status.getDisplayName().equals(readValue))
        .findAny()
        .orElse(CampaignEmailStatus.UNKNOWN);
    }

}

我想我可能需要为Graal添加一些自定义反射配置,但我不太确定。有人能在这里透露一些信息吗?

共有1个答案

易淳
2023-03-14

经过一点挖掘,问题似乎是由SubtrateVM不允许的反思性呼叫造成的。

我为反射调用添加了一个配置文件,其中包含以下条目:

{
    "name": "fts.marketing.utils.deserializers.CampaignEmailStatusDeserializer",
    "allDeclaredConstructors" : true,
    "allPublicConstructors" : true,
    "allDeclaredMethods" : true,
    "allPublicMethods" : true,
    "allDeclaredClasses" : true,
    "allPublicClasses" : true
  }

并配置要使用的本机映像。这解决了所有问题。

 类似资料:
  • 我正在使用Jackson的注释生成漂亮的对象图。 瞬态物体有解决方案吗?

  • 希, 我所拥有的: 公开课myPojo 我想要的是,如果Map中的一个字段不满足POJO,则使从Map到POJO的转换失败(抛出异常)。 它似乎不能使用DeserializationFeature进行任何类型的配置。我试图调整所有与空字段有关的配置

  • 问题内容: 我已经开始在我的第一个android应用程序上进行工作,并且具有处理多层图像的应用程序。我能够将项目文件的平面版本导出为PNG,但我希望能够保存分层图像以供以后编辑(包括应用于某些层的任何选项,例如基于文本的层)。 无论如何,我已经确保需要写入文件的类是“可序列化的”,但是由于android.graphics.Bitmap不可序列化这一事实而遇到了一些障碍。以下代码实质上将位图作为PN

  • 我使用的是JAVA 1.6和Jackson 1.9.9我有一个枚举 我添加了一个@jsonValue,这似乎完成了它将对象序列化为:

  • 我在序列化和反序列化同一JVM中的对象列表时遇到问题。确切地说,现在我的对象与对象具有相同的引用,它有以下规则: 现在在我的对象列表反序列化之后,在某个时候字母表引用不匹配。我用以下方法检查了一下: 得到了以下结果 现在看看VMId,既然它们是相同的,那么它不应该是相同的对象吗,就像上面的逻辑一样?谢谢你的帮助。

  • 我正在尝试使用kryo序列化和反序列化到二进制。我想我已经完成了序列化,但似乎无法反序列化。下面是我正在处理的代码,但最终我想存储一个字节[],然后再次读取它。文档只显示了如何使用文件。