Разница между классами AOT jruby с флагом --java и без

Когда я компилирую файл ruby ​​в класс Java, используя jrubycЯ получаю другой вывод при компиляции с просто jrubyc и с jrubyc --java (для создания файла Java) и просто javac, Зачем?

Пример:

Первый метод:

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

Второй метод:

$ jrubyc myscript.rb

Я ожидаю, что сгенерированные классы будут точно такими же, но это не так. какой jrubyc делать под одеялом?

Спасибо!

1 ответ

Решение

jrubyc myscript.rb компилирует файл Ruby для использования на JRuby и не может использоваться из Java, отсюда и название AOT. Код, используемый для компиляции, это обычный компилятор JRuby, который используется для преобразования в байт-код. Вы можете использовать только полученные myscript.class в сценарии JRuby, используя, например, 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 и определяет множество внутренних методов, поэтому ясно, что этот код предназначен для использования AST в JRuby.

Вот почему jrubyc предоставляет две дополнительные опции: --java а также --javac: первый генерирует исходный код Java, который оборачивает код в скрипт JRuby, используя ScriptingContainerтак же, как вы это обычно делаете с оригинальным скриптом; второй напрямую создает скомпилированный класс 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.

Использование JRuby имеет хорошее описание этих двух форм в Главе 4, Компилятор JRuby.

Другие вопросы по тегам