带有--java标志和没有标志的jruby AOT类之间的区别

时间:2012-09-14 21:35:42

标签: java jruby javac jruby-java-interop

当我使用jrubyc将ruby文件编译到java类时,在使用jrubycjrubyc --java进行编译(生成java文件)时,我获得了不同的输出{1}}。为什么呢?

示例:

第一种方法:

javac

第二种方法:

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

我希望生成的类完全相同,但它们不是。什么是$ jrubyc myscript.rb 在幕后做什么?

谢谢!

1 个答案:

答案 0 :(得分:2)

jrubyc myscript.rb编译用于JRuby消费的Ruby文件,不能从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在第4章 JRuby编译器中对这两种形式有很好的描述。