gpt4 book ai didi

java - Java 代码中 JRuby 对象的序列化

转载 作者:太空宇宙 更新时间:2023-11-04 07:11:59 25 4
gpt4 key购买 nike

我正在 JRuby 中为 Java 库编写简单的 DSL。在 JRuby 中创建的一些对象会传递给 Java 代码,进行处理并返回给 JRuby。我正在使用 JRuby 1.7.8。

在处理 JRuby 中创建的对象时,有时需要由 Java 库进行序列化和反序列化(以执行深度克隆)。这就是问题发生的地方。除了 String 和普通 Object 之外,在 JRuby 中创建的 Java 对象中似乎无法序列化。

例如,在序列化到空哈希对象时,我得到:

IOError: org.jruby.RubyHash$RubyHashEntry
load at org/jruby/RubyKernel.java:1103
at /usr/local/rvm/gems/jruby-1.7.8/bin/pry:23
eval at org/jruby/RubyKernel.java:1123
(root) at /usr/local/rvm/gems/jruby-1.7.8/bin/jruby_executable_hooks:15

对于[“asd”]我得到:

IOError: org.jcodings.specific.UTF8Encoding
load at org/jruby/RubyKernel.java:1103
at /usr/local/rvm/gems/jruby-1.7.8/bin/pry:23
eval at org/jruby/RubyKernel.java:1123
(root) at /usr/local/rvm/gems/jruby-1.7.8/bin/jruby_executable_hooks:15

我找到了一些关于它的帖子(例如 herehere ),但它们都很旧,并且没有解释任何有关 future 计划的信息。在我看来,在考虑 Ruby 和 Java 的集成时,这似乎是一个重要的限制。

现在,我在 Ruby 端将对象序列化为 JSON,并在返回时将它们从 JSON 反序列化。它确实有效,但这会带来显着的效率损失。

所以问题是:

  1. 是否有可能以某种方式使 Ruby 对象在 Java 中可序列化?如果没有的话,不久的将来会有可能吗?
  2. 现在有人有比我上面描述的 JSON 解决方案更好(更快)的解决方法吗?

编辑:

This JRuby 存储库中的规范表明存在与序列化有关的问题。然而,它仍然有 2 年历史,并且没有解释其他对象的序列化策略。

最佳答案

深度克隆 JRuby 对象的问题在于它们包含一直到 Ruby 解释器的递归引用。因此,如果您尝试递归克隆一个对象,您最终会克隆整个 Ruby 世界,这必定会成为一场灾难……至少 2013 年是这样。

根据@tilpner的建议,我放弃了通过序列化进行克隆并开始使用这个:https://github.com/kostaskougios/cloning 。第一个优点是效率——它比序列化快得多。其次,也是更重要的是,您可以更好地控制要克隆的内容和省略的内容。因此,通过反复试验,我得到了以下配置,可以正确克隆 Ruby 对象。我现在不记得所有细节,所以我还包含了今天在此代码中找到的所有注释。希望对您有所帮助。

        // prevent from cloning whole JRuby mess
cloner.dontClone(Class.forName("org.jruby.RubyClass"));
cloner.registerImmutable(Class.forName("org.jruby.RubySymbol"));

// WRz 2014-10-27
// prevent cloning the whole mess with JRuby Proc object
// FIXME: this does not copy bock's binding! That means that
// the cloned Procs share the same closure! Unfortunatelly
// the struggling to do it better (see below) gave no solution...
// Deep cloning the Block pulls an awful lot of stuff! I cannot handle this
// and this or the other way whole JRuby, java.reflection and more gets cloned...
cloner.dontClone(Class.forName("org.jruby.runtime.Block"));
// JRuby's active Enumerator caused cloning of whole mess without this:
cloner.dontClone(Class.forName("org.jruby.Ruby"));

/*
cloner.dontClone(Class.forName("org.jruby.MetaClass")); // singleton!?
cloner.dontClone(Class.forName("org.jruby.parser.LocalStaticScope"));
cloner.dontClone(Class.forName("org.jruby.ast.executable.RuntimeCache"));
cloner.dontClone(Class.forName("org.jruby.Ruby"));
cloner.dontClone(Class.forName("java.lang.reflect.Constructor"));
cloner.dontClone(Class.forName("org.jruby.javasupport.proxy.JavaProxyConstructor"));
*/

正如您所见,大约一年前就是这样。后来我把所有的实现都转移到了 Ruby 上,并且速度更快了,所以我忘记了这个问题。

关于java - Java 代码中 JRuby 对象的序列化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20518463/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com