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

发布于 2024-10-19 17:51:51 字数 236 浏览 1 评论 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

花开柳相依 2024-10-26 17:51:51

看起来 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.

心奴独伤 2024-10-26 17:51:51

我不确定,但我认为字节码格式从未发生过深刻的改变,并且它可能总是向后兼容。 (如果您对字节码有所了解,请记住常量池和操作数堆栈上的长整型和双精度,它们的设计有点疯狂。它尚未被修改,不是吗?)因此,更改主/次编号可能会起作用。

怎么做呢?有两种方法:

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

[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:

  • Use hexa editor and modify it manually. It should be really simple if you know the position of the bytes. There it the [bytecode specification][1], which says, that you should skip the first four bytes and you will see two bytes of minor version and two bytes of major version (in this order).
  • Use an library. I've some experience with BCEL. It does not seem to be the best designed library which I've ever seen, but it should be good enough for your case. I've seen methods setMinor and setMajor in a class (look at ClassGen and the "almost-immutable" JavaClass).

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

初心 2024-10-26 17:51:51

我会使用 ASM 来解析字节码。我知道scala(和clojure)内部使用ASM,所以学习它所花费的精力不会浪费。您可能可以将 ClassReaderEmptyVisitor 覆盖访问方法相当快地提供标题信息。

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.

淡淡離愁欲言轉身 2024-10-26 17:51:51

我想最简单的事情之一就是使用 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.

雪化雨蝶 2024-10-26 17:51:51

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

您使用的是测试版吗?就像在其中一个夜间构建中一样?或者您想修改当前版本?

编辑:好吧,有些东西我不明白。我刚刚尝试了夜间构建,是的,它们是版本 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文