如何使用Scala(50.0 / 51.0)发出更新的类文件版本?

时间:2011-02-27 20:56:05

标签: java class scala versioning bytecode

我想用scalac创建的类测试新的类型检查字节码验证器。

scalac当前输出版本49.0类文件,但新版本检查验证程序仅在版本51.0之后是必需的。

我试图用ProGuard“预验证”这些类(实际上将它们转换为版本50.0),但我不确定新的验证器是否会自动回退到旧的类型推理验证器。

如何将类文件转换为版本51.0(或者如何在加载版本50.0类文件时找出使用哪个验证器)?

5 个答案:

答案 0 :(得分:2)

似乎FJBG(NSC用来生成字节码的库)已经看到支持StackMap的一些努力,但我不知道它有多远。

如果你问scala-internals,Stephane Michelou可能会出现。他是那个曾经working on it的人。

答案 1 :(得分:1)

我不确定,但我认为字节码格式并没有经过深刻的改变,而且它可能总是向后兼容。 (如果您对字节码有所了解,请记住常量池和操作数堆栈上的long和double,这些设计有点疯狂。它没有被修改,有吗?)因此,更改主/次数可能会有效。

怎么做?有两种方法:

  • 使用hexa编辑器并手动修改。如果你知道字节的位置,那应该很简单。在那里[字节码规范] [1],它说,你应该跳过前四个字节,你会看到两个字节的次要版本和两个字节的主要版本(按此顺序)。
  • 使用库。我对BCEL有一些经验。它似乎不是我见过的最好的设计图书馆,但它应该对你的情况足够好。我在类中看到了setMinor和setMajor方法(看看ClassGen和“几乎不可变”的JavaClass)。

[1] http://java.sun.com/docs/books/jvms/second_edition/html/ClassFile.doc.html

答案 2 :(得分:1)

我会使用ASM来解析字节码。我知道scala(和clojure)在内部使用ASM,因此学习它所花费的精力不会浪费。您可以将ClassReaderEmptyVisitor放在一起,它会覆盖提供标头信息的访问方法。

答案 3 :(得分:0)

我知道这可能是显而易见的,但在阅读你的问题之后我不确定所以我会问:

您使用的是测试版吗?就像在夜间建筑之一?或者您想修改当前版本吗?

编辑:好的,有些东西我没有到达这里。我刚试过夜间版本,是的,它们是版本49.0。但据我所知,这是由编译器设置的。

您正在尝试更改版本以访问一些新的奇特功能。但这对我来说没有意义。如果编译器发布版本49.0,则将其更改为任何较新版本(50.0,51.0或70.0,对于重要事项)不应产生任何影响。据我所知,版本是为了确保兼容性,这意味着您不会使用不支持您的语言的旧VM运行较新的类。

因此,在这种情况下,添加新版本意味着当前的VM可能不希望运行您的代码。即使它确实如此,它可能不包含您提到的功能,如果该功能仅在您当前编译器/ VM不支持的版本51.0中。

我的意思是,也许你想要做的事情是完全正常的,只是我不知道它而且我在这方面表现出我的无知:),但我认为那里缺少一些东西。

答案 4 :(得分:0)

我想最简单的事情之一就是使用java反编译器(请参阅JADClipse获取Eclipse插件),然后将源重新编译为您需要的任何版本。