Подтвердить что ты не робот

Компиляция Java 7 на Java 6

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

Любые указатели?

4b9b3361

Ответ 1

Отметьте выходной файл .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 MB jar) и даже использовал RetroTranslator на java 6 jar, поэтому возможности языка Java 7 можно использовать в приложении, которое работает на Java 5. Также компилятор Java 7 (javac) делает множество дополнительных оптимизаций (например, анализ побега), что очень заметно повышает производительность.

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

Ответ 2

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

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

Ответ 3

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

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

Ответ 4

Возможно, некоторые из них работают, но попробуйте следующее:

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

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

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

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