Разница между классами 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.