Java7のランタイム機能はJava6では使用できないことは承知していますが、新しいバイトコードが追加されていないため、新しいバイトコードinvokedynamic
はJava以外の言語にのみ関連するため、Javaを変換するのはどれほど難しいのでしょうか。 7ソースコード(新しいswitch
ステートメント、ダイヤモンド演算子)を純粋なJava 6に(つまり、Java6の互換性を失うことなくソースをJava7に変換し始めることができるようにするため)。
ポインタはありますか?
私の知る限り、現時点ではこの問題の解決策はありません。最善の策は、Java1.7コンストラクトを処理するためにretrotranslatorを拡張することです。ダイヤモンド演算子は、バイトコードの変更をまったく必要としないため、非常に簡単です。
「新しいバイトコードは追加されていません」という記述は正しくありません。新しいinvokedynamicバイトコードがあり、さらに重要なことに、生成されたバイトコードが1.6 JREで有効にならない場合があるため、レトロトランスレーターはそれを修正する必要があります。
Java 7 javacによって出力された.classファイルをバージョン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
すべてのクラスファイルを次のように実行できます。
探す 。-name\*。class|xargs -I {} ./j6patch {}
私はこれを大規模な(〜4.8 MB jar)コードベースで使用RetroTranslator
し、java 6 jarでも使用したため、Java5で実行されるアプリでJava7言語機能を使用できます。また、Java 7コンパイラ(javac
)は多くの追加機能を実行します。パフォーマンスを大幅に向上させる最適化(エスケープ分析など)。
RetroTranslator
with-verify -target 1.5
およびJRE1.6ランタイムjarを使用すると、Java7ランタイム機能が使用されていないことを確認できます。
あなたは、invokedynamic命令がJavaによって使用されていないことは正しいですが、Javaで使用できる他のいくつかの関連する変更があります。Invokedynamicは、invokevirtual命令にもいくつかの変更が加えられた新しい「動的リンケージメカニズム-メソッドハンドル」に依存しています。詳細については、この記事の「新しい動的リンケージメカニズム:メソッドハンドル」のセクションを参照してください。
メソッドハンドルは、リフレクションのより高速な代替手段も提供するため、Javaで役立ちます。この機能はJava7VMに依存しているため、メソッドハンドルを使用してコードをJava6に変換することはできません。
おそらくいくつかの作業ですが、これを試してください:
EclipseのJavaコンパイラをクラスパスに追加します。プラグインにあります(フォルダでorg.eclipse.jdt.core
検索してください)。org.eclipse.jdt.core_*.jar
plugins
このJARには、コンパイラーとパーサーが含まれています。自分でパーサーを呼び出してから、を使用しASTVisitor
て解析ツリーをトラバースできます。
次に、ツリーを変更し、これから新しいソースコードを作成して、通常どおりにコンパイルできます。
コンパイラがバイトコードを生成する前に、ASTツリーを「前処理」することさえ可能かもしれません。これにより、「ソースをディスクに書き戻し、そこからコンパイルする」手順を節約できます。