Компиляция Java 7 в Java 6 - PullRequest
       52

Компиляция Java 7 в Java 6

28 голосов
/ 05 октября 2011

Мне известно, что функции времени выполнения Java 7 недоступны в Java 6, но, поскольку новый байт-код не был добавлен новый байт-код invokedynamic относится только к не-Java языкам Мне было интересно, как трудно было бы преобразовать исходный код Java 7 (новый оператор switch, оператор diamond) в чистую Java 6 (то есть, чтобы иметь возможность начать преобразование исходного кода в Java 7 без потери совместимости с Java 6).

Есть указатели?

Ответы [ 4 ]

11 голосов
/ 05 октября 2011

Насколько я знаю, на данный момент нет решения этой проблемы.Лучше всего было бы расширить ретротранслятор для работы с конструкциями Java 1.7.Оператор diamond должен быть очень простым, поскольку он вообще не требует модификации байт-кода.

Ваше утверждение «новый байт-код не был добавлен» неверно: существует новый вызываемый динамический байт-код и, что более важно,В некоторых случаях сгенерированный байт-код не будет действителен для 1.6 JRE, поэтому ретротранслятор должен будет это исправить.

7 голосов
/ 22 августа 2013

Пометить вывод файла .class с помощью Java 7 javac с версией 1.6.0 (т.е. 0x32)

printf "\x00\x00\x00\x32" |dd of=Example.class seek=4 bs=1 count=4 conv=notrunc

(согласно http://en.wikipedia.org/wiki/Java_class_file#General_layout)

Если вы поместите это (используя $ 1 в качестве имени файла) в j6patch, вы можете сделать все файлы классов с помощью:

find . -name \*.class |xargs -I {} ./j6patch {}

Я использовал это для большой (~ 4,8 МБ jar) базы кода и даже использовал RetroTranslator для java 6 jar, так что возможности языка Java 7 можно использовать в приложении, работающем в Java 5. Также компилятор Java 7 (javac) выполняет много дополнительных оптимизаций (например, escape-анализ), что очень заметно повышает производительность.

Использование RetroTranslator с jar-файлами времени выполнения -verify -target 1.5 и JRE 1.6 позволяет проверить, что функции времени выполнения Java 7 не используются.

3 голосов
/ 06 октября 2011

Вы правы в том, что инструкция invokedynamic не используется Java, однако есть некоторые другие связанные изменения, которые могут быть использованы в Java.Invokedynamic опирается на новый «механизм динамического связывания - дескрипторы методов», для которого также есть некоторые изменения в инструкции invokevirtual.Вы можете найти более подробную информацию в этой статье в разделе «Новый механизм динамического связывания: дескрипторы метода».

Дескрипторы метода также обеспечивают более быструю альтернативу отражению и, следовательно, полезны в Java,Преобразование кода с использованием дескрипторов методов в Java 6 будет невозможно, так как эта функция использует виртуальную машину Java 7.

2 голосов
/ 05 апреля 2012

Это, вероятно, некоторая работа, но попробуйте это:

Добавьте компилятор Java Eclipse к вашему пути к классам.Он находится в плагине org.eclipse.jdt.core (ищите org.eclipse.jdt.core_*.jar в папке plugins).

Этот JAR-файл содержит компилятор и анализатор.Вы можете вызвать синтаксический анализатор самостоятельно, а затем использовать ASTVisitor для обхода дерева разбора.

Затем вы можете изменить дерево и создать из него новый исходный код, который можно скомпилировать какобычно.

Может даже оказаться возможным "предварительно обработать" дерево AST до того, как компилятор сгенерирует байт-код;это избавит вас от шага «записать исходники обратно на диск и скомпилировать их оттуда».

...