【问题标题】:Difference between jruby AOT classes with --java flag and without带 --java 标志和不带标志的 jruby AOT 类之间的区别
【发布时间】:2020-10-23 19:19:06
【问题描述】:

当我使用 jrubyc 将 ruby​​ 文件编译为 java 类时,仅使用 jrubycjrubyc --java(用于生成 java 文件)和 javac 进行编译时会得到不同的输出。为什么?

例子:

第一种方法:

jrubyc --java myscript.rb
javac -cp .:./jruby-complete.jar myscript.java

第二种方法:

jrubyc myscript.rb

我希望生成的类完全相同,但事实并非如此。 jrubyc 在幕后做什么?

谢谢!

【问题讨论】:

    标签: java jruby javac jruby-java-interop


    【解决方案1】:

    jrubyc myscript.rb 编译 Ruby 文件以供 JRuby 使用,不能从 Java 中使用,因此名称为 AOT。用于编译它的代码是用于转换为字节码的普通 JRuby 编译器。您只能在 JRuby 脚本中使用生成的 myscript.class,例如使用 require 'myscript'。使用javap时:

    ubuntu@ubuntu:/tmp$ javap myscript
    Compiled from "myscript.rb"
    public class myscript extends org.jruby.ast.executable.AbstractScript {
      public myscript();
      public static org.jruby.runtime.builtin.IRubyObject __file__(myscript, org.jruby.runtime.ThreadContext, org.jruby.runtime.builtin.IRubyObject, org.jruby.runtime.builtin.IRubyObject[], org.jruby.runtime.Block);
      public org.jruby.runtime.builtin.IRubyObject __file__(org.jruby.runtime.ThreadContext, org.jruby.runtime.builtin.IRubyObject, org.jruby.runtime.builtin.IRubyObject[], org.jruby.runtime.Block);
      public static org.jruby.runtime.builtin.IRubyObject class_0$RUBY$MyScript(myscript, org.jruby.runtime.ThreadContext, org.jruby.runtime.builtin.IRubyObject, org.jruby.runtime.Block);
      public static org.jruby.runtime.builtin.IRubyObject method__1$RUBY$run(myscript, org.jruby.runtime.ThreadContext, org.jruby.runtime.builtin.IRubyObject, org.jruby.runtime.Block);
      public static org.jruby.runtime.builtin.IRubyObject method__1$RUBY$run(myscript, org.jruby.runtime.ThreadContext, org.jruby.runtime.builtin.IRubyObject, org.jruby.runtime.builtin.IRubyObject[], org.jruby.runtime.Block);
      public static org.jruby.runtime.builtin.IRubyObject class_0$RUBY$MyScript(myscript, org.jruby.runtime.ThreadContext, org.jruby.runtime.builtin.IRubyObject, org.jruby.runtime.builtin.IRubyObject[], org.jruby.runtime.Block);
      public org.jruby.runtime.builtin.IRubyObject load(org.jruby.runtime.ThreadContext, org.jruby.runtime.builtin.IRubyObject, boolean);
      public static void main(java.lang.String[]);
    }
    

    我们看到扩展类继承了org.jruby.ast.executable.AbstractScript并定义了很多内部方法,所以很明显这段代码是供JRuby的AST使用的。

    这就是jrubyc 提供两个额外选项的原因:--java--javac:第一个选项生成 Java 源代码,该代码使用 ScriptingContainer 将代码包装到 JRuby 脚本中,就像您通常使用原始代码一样脚本;第二种直接产生编译后的Java类。此代码使用特定的 Java 生成器代码,该代码使用诸如 java_signature 之类的指令来为 Java 方法提供 Java 所期望的正确签名。再次使用javap时:

    ubuntu@ubuntu:/tmp$ jrubyc --javac myscript.rb
    ubuntu@ubuntu:/tmp$ javap MyScript
    Compiled from "MyScript.java"
    public class MyScript extends org.jruby.RubyObject {
      public static org.jruby.runtime.builtin.IRubyObject __allocate__(org.jruby.Ruby, org.jruby.RubyClass);
      public MyScript();
      public java.lang.Object run();
      static {};
    }
    

    该类以大写 M 开头,并继承 RubyObject。类中定义的方法将公开供 Java 使用。

    Using JRuby: Bringing Ruby to Java 在第 4 章JRuby 编译器中有很好的描述这两种形式。

    【讨论】:

      猜你喜欢
      • 2020-09-10
      • 2013-01-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-09-09
      • 2012-02-27
      • 1970-01-01
      相关资源
      最近更新 更多