我正在寻找一个故障安全的方式来一个JVM类文件和文本表示并再次之间往返。
一个严格的要求是,所产生的往返式操作JVM类文件是完全功能上等同于原有的JVM类文件,只要将文本表示将保持不变。
此外,文本表示必须是人类可读和可编辑。 它应该是可以使小的变化的文本表示(例如改变文本字符串或类名等),其反映在所得到的类文件表示。
最简单的解决方案将是使用Java反编译如JAD生成的文本表示,其在这种情况下,将简单地是重新创建的Java源代码。 然后使用javac生成字节码。 不过,考虑到免费的Java反编译这种方法并不能在所有情况下的工作状态。 这是比较容易产生混淆的字节码,不渡过了完整往返于类的文件/ Java的源/类文件(部分原因是因为我们确实没有一个1:JVM字节码和1之间的映射Java源代码)。
是否有故障安全的方式来实现JVM类文件/文本的表示/类文件往返鉴于上述要求?
更新:在回答-节省时间和精力,通过阅读上述所有要求,特别注意:
- “JVM字节的文本的表示”并不一定意味着“Java源代码”。
该BCEL项目提供了一个JasminVisitor将类文件转换成茉莉花集会。
这可以被修改,然后重新组装成class文件。 如果没有编辑时与版本保持兼容往返应导致相同的类文件,除了行号映射可能会丢失。 如果你需要一点对于往返的情况下位相同的副本,你可能需要改变采取哪些是纯粹的元数据以及代码方面的工具。
茉莉是相当老的设计不容易的实际编写汇编完全成熟的方案,但修改字符串常量表和常量应该是绰绰有余。
貌似ASM做到这一点。 (这是同一类的答案ShuggyCoUk的,但用不同的工具。) Jarjar说,它使用ASM进行准确的那种你正在谈论的事情。
我写它的设计正是这种工具。
该喀拉喀托拆装器和汇编程序的设计不管处理任何有效的类文件,怎么离奇。 它使用基于茉莉格式的汇编格式,而是扩大到支持所有的类文件的功能,茉莉无法处理。 它甚至支持一些热点的模糊或无证“特征”,如预45.3
使用较小宽度的代码属性字段的类文件。
它可以来回我所知道的任何类文件。 结果不会是相同的二进制明智的,但它具有相同的功能(常量池项可以重新设置为例)。
更新:喀拉喀托现在支持类文件的确切的二进制往返。 路过-roundtrip
标志将保持常量池项等的顺序
号存在着有效的字节码没有相应的Java程序。
烟灰项目有一个相当复杂的decompiler- http://www.sable.mcgill.ca/dava/ -这可能是由Java编译器来的字节码有用。 它是,但并不完美。
最好的办法是仍然得到了类文件的源代码。
文章来源: Fail-safe way of round-tripping JVM byte-code to text-representation and back