我知道 Java 7 的运行时特性不适用于 Java 6,但是由于没有添加新的字节码,新的字节码invokedynamic
只与非 Java 语言相关,我想知道转换 Java 会有多难7 源代码(新switch
语句,菱形运算符)到纯 Java 6(即能够开始将源代码转换为 Java 7 而不会失去 Java 6 兼容性)。
任何指针?
据我所知,目前还没有解决这个问题的办法。最好的办法是扩展逆向翻译器来处理 Java 1.7 结构。菱形运算符应该非常简单,因为它根本不需要修改字节码。
您的声明“没有添加新的字节码”是不正确的:有一个新的 invokedynamic 字节码,更重要的是,在某些情况下,生成的字节码对 1.6 JRE 无效,因此逆向翻译器必须解决这个问题。
使用版本 1.6.0(即 0x32)标记由 Java 7 javac 输出的 .class 文件
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 上使用了它,因此 Java 7 语言功能可以在运行于 Java 5 的应用程序上使用。Java 7 编译器(javac
)还有很多额外的功能显着提高性能的优化(例如逃逸分析)。
使用RetroTranslator
with-verify -target 1.5
和 JRE 1.6 运行时 jar 可以验证没有使用 Java 7 运行时特性。
没错,Java 不使用invokedynamic 指令,但是Java 中可以使用一些其他相关的更改。Invokedynamic 依赖于新的“动态链接机制 - 方法句柄”,invokevirtual 指令也对此进行了一些更改。您可以在本文的“新的动态链接机制:方法句柄”部分中找到更多详细信息。
方法句柄还提供了一种更快的反射替代方法,因此在 Java 中很有用。由于该功能依赖于 Java 7 VM,因此无法使用方法句柄将代码转换为 Java 6。
It's probably some work but try this:
Add Eclipse's Java Compiler to your classpath. It's in the plugin org.eclipse.jdt.core
(search for org.eclipse.jdt.core_*.jar
in the folder plugins
).
This JAR contains the compiler and the parser. You can invoke the parser yourself and then use the ASTVisitor
to traverse the parse tree.
You can then modify the tree and create the new source code from this that you can compile as usual.
It might even be possible to "preprocess" the AST tree before the compiler generates byte code; this would save you the "write sources back to disk and compile them from there" step.