使用 Kryo 序列化任意 Java 对象(出现 IllegalAccessError)

2023-12-03

动机:

为了帮助远程调试 (Java),能够请求远程服务器将任意对象发送到我的本地计算机进行检查非常有用。然而,这意味着远程服务器必须能够序列化运行时事先未知的任意java对象。

于是我四处打听,偶然发现Kryo序列化库. From Kryo 的文档,一个主要特点是它在序列化任意 java 对象方面非常强大。对象不必实现Serializable,不需要无参数构造函数来反序列化,我什至不需要在序列化之前了解有关对象结构的任何信息。完美的!

Problem:

因此,为了测试 Kryo,我尝试看看是否可以序列化然后反序列化PrintWriter对象(即任意对象):

import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryo.io.Input;
import com.esotericsoftware.kryo.io.Output;
import java.io.*;

public class SerializationTest {

    private static final String ioFileName = "someIO.bin";

    public static void main(String[] args) {

        // Create a PrintWriter object that I will later attempt to serialize
        PrintWriter outObj = null;
        try {
            outObj = new PrintWriter("textfile.txt");
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }

        // Change the PrintWriter's state as a test for later to see if state is restored after serialization and deserialization
        outObj.println("Hello");   // "Hello" held in PrintWriter's buffer

        Kryo kryo = new Kryo();    // Initialize Kryo serialization
        writeObj(kryo, outObj);    // Save PrintWriter object to file with "Hello" still in its buffer

        // Read the previously saved Printwriter object (still with "Hello" in its buffer)
        PrintWriter inObj = (PrintWriter) readObj(kryo);

        inObj.close();    // commit "Hello" to disk (using deserialized object)
        outObj.close();   // commit "Hello" to disk (using original object)

        System.out.println(inObj);
    }

    public static Object readObj(Kryo kryo) {
        Object obj = null;
        try {
            Input input = new Input(new FileInputStream(ioFileName));
            obj = kryo.readClassAndObject(input);   // ERROR HERE!!
            input.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        return obj;
    }

    public static void writeObj(Kryo kryo, Object obj) {
        try {
            Output output = new Output(new FileOutputStream(ioFileName));
            kryo.writeClassAndObject(output, obj);
            output.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }
}

序列化工作正常,但反序列化时调用kryo.readClassAndObject(input)第 39 行给出以下内容IllegalAccessError:

Exception in thread "main" java.lang.IllegalAccessError: tried to access class sun.nio.cs.UTF_8 from class sun.nio.cs.UTF_8ConstructorAccess
    at sun.nio.cs.UTF_8ConstructorAccess.newInstance(Unknown Source)
    at com.esotericsoftware.kryo.Kryo$DefaultInstantiatorStrategy$1.newInstance(Kryo.java:1234)
    at com.esotericsoftware.kryo.Kryo.newInstance(Kryo.java:1086)
    at com.esotericsoftware.kryo.serializers.FieldSerializer.create(FieldSerializer.java:547)
    at com.esotericsoftware.kryo.serializers.FieldSerializer.read(FieldSerializer.java:523)
    at com.esotericsoftware.kryo.Kryo.readObject(Kryo.java:704)
    at com.esotericsoftware.kryo.serializers.ObjectField.read(ObjectField.java:106)
    at com.esotericsoftware.kryo.serializers.FieldSerializer.read(FieldSerializer.java:528)
    at com.esotericsoftware.kryo.Kryo.readObject(Kryo.java:704)
    at com.esotericsoftware.kryo.serializers.ObjectField.read(ObjectField.java:106)
    at com.esotericsoftware.kryo.serializers.FieldSerializer.read(FieldSerializer.java:528)
    at com.esotericsoftware.kryo.Kryo.readObject(Kryo.java:704)
    at com.esotericsoftware.kryo.serializers.ObjectField.read(ObjectField.java:106)
    at com.esotericsoftware.kryo.serializers.FieldSerializer.read(FieldSerializer.java:528)
    at com.esotericsoftware.kryo.Kryo.readObject(Kryo.java:704)
    at com.esotericsoftware.kryo.serializers.ObjectField.read(ObjectField.java:106)
    at com.esotericsoftware.kryo.serializers.FieldSerializer.read(FieldSerializer.java:528)
    at com.esotericsoftware.kryo.Kryo.readClassAndObject(Kryo.java:786)
    at SerializationTest.readObj(SerializationTest.java:39)
    at SerializationTest.main(SerializationTest.java:27)

我曾希望能够序列化和反序列化PrintWriter object outObj,并且对象的状态将保持不变,因此我仍然可以使用反序列化的对象来编写"Hello"它将被保存在缓冲区中。

有谁知道发生了什么事以及如何纠正此错误?


我想,你想要kryo.setInstantiatorStrategy(new StdInstantiatorStrategy());以避免构造函数调用。 更多信息here.

但是,如果我可以问的话,你到底为什么要序列化一个PrintWriter?这绝对是自找麻烦。 Kryo 不是“灵丹妙药”,但它的默认反序列化器可以与most类,这是实用的(即使如此,总是存在需要编写自定义插件的极端情况),您当然不能指望它能够处理您能想到的每一个奇异的东西(以及序列化由内部 jvm 特定代码,例如sun.*绝对有资格成为异国情调)。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 Kryo 序列化任意 Java 对象(出现 IllegalAccessError) 的相关文章

随机推荐

  • 如果我睡10毫秒。我需要增加什么才能获得第二个?

    即我正在使用std this thread sleep for std chrono milliseconds 10 在程序循环中 如果我有一个变量在此循环中递增以显示经过的秒数 我需要递增什么 i e float x 0 对于每个步骤 x
  • 使用shiny将server.R中读取的数据传递到ui.R中

    In ui R 我首先读取了固定的样本数据 datT2 lt fread paste0 data 30062019KRB csv header TRUE sep stringsAsFactors FALSE encoding UTF 8 提
  • ggplot2 为平淡的 altman 图中的每个面添加几何线

    我有以下数据框 structure list Lightbox c 84L 67L 80L 63L 76L 66L 79L 81L 77L 82L 84L 67L 80L 63L 76L 66L 79L 81L 77L 82L 84L 67
  • jQuery UI 对话框定位

    我正在尝试使用jQuery 对话框 UI库 以便在将鼠标悬停在某些文本上时将对话框放置在其旁边 jQuery 对话框采用一个位置参数 该参数是从当前视口的左上角开始测量的 换句话说 0 0 将始终将其放在浏览器窗口的左上角 无论您当前滚动到
  • 获取连接表列的不同总和

    我在这里遇到问题 我希望有一个简单的解决方案 我会尝试使这尽可能简单 门票属于与会者 Example 得到结果没有子查询 你必须求助于高级窗口函数技巧 SELECT sum count OVER AS tickets count sum m
  • 合并重叠区间的算法

    我一直在寻找一种有效的算法来合并动态间隔数组上的重叠间隔 例如 开始时间 结束时间 明智的 1 2 4 8 3 10 becomes 1 2 3 10 合并后 因为 4 8 和 3 10 重叠 重叠意味着两个间隔的任何部分共享相同的时刻 我
  • 将sourcesJar任务添加到自定义Gradle插件

    我的公司最近为普通配置 存储库 跨项目的常见依赖项等 编写了 gradle 插件 总的来说 这极大地简化了我们的构建过程 并发现了项目之间的一些不一致之处 我们最近尝试添加一个sourcesJar任务到插件 但它不起作用 这是损坏的插件 p
  • 同一内存地址有两个不同的值

    Code include
  • ts:“Props”可以用任意类型实例化,该类型可能与其他类型无关

    const withFirebase
  • 如何在AWS lex中从意图A调用意图B? [复制]

    这个问题在这里已经有答案了 我正在使用 aws lex 我有一个意图 A 我给它起了个名字welcomeMsg 我想打电话给另一个人intent B from intent A 欢迎msg intent A 它会说 gt Hi I am a
  • python 库中的“randrange() 的非整数参数 1”

    我使用随机数生成器生成 5 到 10 之间的随机数 能不能这么难 我之前在代码中使用过它 2000 行代码 对于这里来说太多了 并且没有发生编码错误 我的代码对于我的游戏来说只是复活节彩蛋 但它破坏了我的所有代码 def slowp t f
  • AngularJS 和 Express Routing 问题

    我正在使用 AngularJS 和 ExpressJS 并且遇到路由问题 我看到了很多其他帖子 但这些解决方案似乎都不起作用 这是我在 Express 中的路线 module exports function app auth Api ro
  • R 如何在不知道长度的情况下创建 for 循环?

    目前在这方面site我正在抓取镜头图表信息 为了抓取信息 我需要为有多少个镜头创建一个 for 循环 我通过单击 球队统计数据 并查找投篮尝试次数来查找投篮次数 我想做适当的for loop无需找出镜头的数量 我目前正在做的事情 shotc
  • 更新第一行mysql php

    我正在尝试更新数据库中的第一行 我用Limit 1仅更新第一行但什么也没有发生 肯定有匹配的行 但数据库中没有任何变化 这是代码 foreach player fromsite as match player in game querytw
  • loadNibNamed 方法太慢 - 如何使其更快?

    我有一个滚动视图 其中包含大约 40 50 个不同类型的对象 对象的类型是根据对象位置的函数定义的 例如 如果是滚动视图中的第 5 个对象 gt 是 Object1 如果是滚动视图中的第 11 个对象 gt 则是 Object2 类型等 使
  • Python Popen 无法在 Windows PowerShell 中使用正确的编码

    我正在 Windows PowerShell 中运行 Python 脚本 该脚本应使用 Popen 运行另一个程序 然后通过管道传输该程序 实际上是 Mercurial 的输出以在我的脚本中使用 当我尝试在 PowerShell 中执行脚本
  • 在 Java 中逐行读取大型 JSON 文件的快速高效方法

    我有 1 亿条记录JSON文件 需要一种高效且最快的方法来读取数组的数组JSON文件输入java JSON文件看起来像 XYZ ABC XYZ ABC XYZ ABC XYZ ABC XYZ ABC XYZ ABC XYZ ABC XYZ
  • 有使用 pywin32 createprocessasuser 并获取输出的好例子吗?

    我需要使用 pywin32 方法以不同的用户身份创建进程 然后从生成的进程中获取标准输出 标准错误和错误代码 并在进程运行时将输入输入到进程中 问题是 我似乎找不到 createprocess 函数的一个很好的例子 这个问题变得更加复杂 因
  • 如何在seaborn中检索错误栏

    我使用以下函数在seaborn中绘制了条形图 ax sns barplot x Year y Value data df 现在我想根据以下规则为每个条形着色 percentages for bar yerr in zip bars yerr
  • 使用 Kryo 序列化任意 Java 对象(出现 IllegalAccessError)

    动机 为了帮助远程调试 Java 能够请求远程服务器将任意对象发送到我的本地计算机进行检查非常有用 然而 这意味着远程服务器必须能够序列化运行时事先未知的任意java对象 于是我四处打听 偶然发现Kryo序列化库 From Kryo 的文档