如何使用 Scala (50.0/51.0) 发出更新的类文件版本?
我想使用 scalac 创建的类来测试新的类型检查字节码验证器。
scalac 当前输出 49.0 版本的类文件,但新的类型检查验证器仅从 51.0 版本开始是强制性的。
我尝试使用 ProGuard 来“预验证”这些类(实际上将它们转换为版本 50.0),但我不确定新验证器是否会自动回退到旧的类型推断验证器。
如何将类文件转换为 51.0 版本(或者如何找出加载 50.0 版本类文件时使用的验证程序)?
I want to test the new type-checking bytecode verifier with classes created by scalac
.
scalac
currently outputs version 49.0 class files, but the new type-checking verifier is only mandatory since version 51.0.
I tried to "preverify" the classes with ProGuard (which in fact converted them to version 50.0), but I' not sure if the new verifier just fell back to the old type-inferencing verifier automatically.
How can I convert class files to version 51.0 (or how can I find out which verifier is used when loading version 50.0 class files)?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
看起来 FJBG(NSC 用于生成字节码的库)已经在支持StackMap 但我不知道它有多远。
如果你询问 scala-internals,Stephane Michelou 可能会出现。他就是那个致力于此工作的人。
It seems like FJBG (the library NSC uses to generate bytecode) has seen some effort at supporting StackMap but I have no idea how far along it is.
If you ask on scala-internals, Stephane Michelou might pop up. He's the guy who's been working on it.
我不确定,但我认为字节码格式从未发生过深刻的改变,并且它可能总是向后兼容。 (如果您对字节码有所了解,请记住常量池和操作数堆栈上的长整型和双精度,它们的设计有点疯狂。它尚未被修改,不是吗?)因此,更改主/次编号可能会起作用。
怎么做呢?有两种方法:
[1] http://java.sun.com/文档/books/jvms/second_edition/html/ClassFile.doc.html
I am not sure, but I think that bytecode format has not been ever changed deeply and that it is probably always backward compatible. (If you know something about bytecode, remember longs and doubles on constant pool and operand stack, which were designed a bit crazily. It hasn't been modified, has it?) So, changing major/minor number will probably work.
How to do it? There are two ways:
[1] http://java.sun.com/docs/books/jvms/second_edition/html/ClassFile.doc.html
我会使用 ASM 来解析字节码。我知道scala(和clojure)内部使用ASM,所以学习它所花费的精力不会浪费。您可能可以将 ClassReader 和EmptyVisitor 覆盖访问方法相当快地提供标题信息。
I would use ASM to parse the bytecode. I know that scala (and clojure) use ASM internally, so the effort spent to learn it won't be wasted. You can probably throw together a ClassReader and an EmptyVisitor that overrides the visit method that provides header information fairly quickly.
我想最简单的事情之一就是使用 java 反编译器(参见 JADClipse 对于 Eclipse插件),然后将源代码重新编译为您需要的任何版本。
I guess one of the easiest things to do would be to use a java decompiler (see JADClipse for an Eclipse plugin) and then recompile the source to whatever version you need.
我知道这可能是显而易见的,但在阅读您的问题后我不确定,所以我会问:
您使用的是测试版吗?就像在其中一个夜间构建中一样?或者您想修改当前版本?
编辑:好吧,有些东西我不明白。我刚刚尝试了夜间构建,是的,它们是版本 49.0。但据我所知,这是由编译器设置的。
您正在尝试更改版本以访问一些新的奇特功能。但这对我来说没有意义。如果编译器发布版本 49.0,您将其更改为任何较新的版本(重要的是 50.0、51.0 或 70.0)应该不会产生任何影响。据我所知,该版本是为了确保兼容性,这意味着您不会使用不支持您的语言的旧虚拟机运行较新的类。
因此,在您的情况下,添加新版本将意味着当前的虚拟机可能不想运行您的代码。即使它包含,它也可能不包含您提到的功能,如果该功能仅存在于您当前的编译器/VM 不支持的版本 51.0 中。
我的意思是,也许你想做的事情是完全正常的,只是我不知道这一点,而且我在这方面表现出我的无知:),但我认为那里缺少一些东西。
I know it may be obvious, but I'm not sure after reading your question so I'll ask:
Are you using a beta build? Like in one of the nightly builds? Or do you want to modify the current release?
EDIT: Ok, there is something I don't get here. I've just tried the nightly builds and yes, they are version 49.0. But as far as I know this is set by the compiler.
You are trying to change the version to get access to some new fancy functionality. But that doesn't make sense to me. If the compiler releases version 49.0, you changing it to any newer version (50.0, 51.0 or 70.0 for what matters) should not have any impact. As far as I know the version is to ensure compatibility, which means that you won't run a newer class with an older VM that won't support your language.
So, in you case, adding a new version will mean that, probably, the current VM won't want to run your code. And even if it does, it probably doesn't contain the functionality you mention, if that functionality is only in version 51.0 which your current compiler/VM doesn't support.
I mean, maybe what you are trying to do is completely normal and it's simply that I don't know about it and I'm showing my ignorance in this area :) , but I think there something missing there.