问题标签 [jvm-bytecode]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
java - 长度超过 65535 字节的 Java 字符串文字的字节码
我一直在从各种文件中读取 Java 字节码,以帮助我理解一个项目的 .class 文件,在该项目中我需要与没有源代码和可用文档不足的第 3 方库集成。
为了我自己的乐趣,我通过我的 maven 存储库运行了 Apache BCEL 库,以查看在哪里使用了较少见的类和方法属性(例如类型注释)以及原因。
我偶然发现了一个特定 jar 的问题,该 jar 无法解码常量字段之一 - 特别是 CONSTANT_Utf8_info。库是icu4j-2.6.1.jar (com.ibm.icu:icu4j)
,特别是LocaleElements_zh__PINYIN.class
文件。Apache BCEL 失败(以及我自己在符合 JVMS 版本 8 和 9 的快速字节码阅读器上的尝试)偶然发现了同样的问题,他们误读了这个常量,然后读取了下一个字节,该字节被评估为不正确的常量标签 (0x3C/60) .
快速检查我是否可以在 IDE 中使用该类失败(无法解析符号)。使用十六进制编辑器研究实际字节码,显示该偏移量 ( 0x1AC
) 处的常量是长度为 的 Utf8 常量 (tag= 0x01
) 0x480E
。向前移动文件中的该数量确实0x3C
在该位置有一个字节。直观地查看文件,我可以看到有问题的常量在 location 结束,0x149BD
这使得字符串的实际长度0x1480E
(本质上是 location 的前三个字节0x1AC
)。根据 JVM 类文件规范,这当然不可能,因为0xFFFF
Utf8 常量的最大长度为 65535 或 65535。类文件相当旧 - 版本 46 或 Java 1.2。
我仔细研究了规范并尝试了不同的可能实现(越来越严格)来尝试解析这个常量,但它要么无法解析它,要么破坏了其他有效 Utf8 常量的读取。
那么我的问题是,我是否遗漏了什么,或者是编译器错误,在这种情况下,我的第二个问题是这首先是如何发生的 - 编译器往往经过相对彻底的检查。最后,Java 编译器通常如何管理长度超过 65535字节的字符串文字?
jvm - 如何区分 JVM ClassFile 中的 attribute_info?
我正在研究ClassFile
结构。
根据上面提到的文件,attribute_info
可以出现在各种位置。
我的问题是如何区分attribute_info
s 的类型?
我知道我可以constant_info
通过他们的 s 来区分tag
s。
以及如何区分attribute_info
s?
都是attribute_info
这个样子的。
Fields似乎有, attribute_info
,ConstantValue
等等Synthetic
。
如何区分它们的类型?
java - 计算方法的字节码大小
目前我正在使用ASM library实现自定义软件度量工具。通过这个库计算方法大小的唯一方法是在每次指令访问时手动增加一些大小变量,这在我看来有点不对劲。还有另一种计算方法字节码大小的常用方法吗?还是按指令大小计算是否足够合理?
java - Javap 输出:区别 static {} 和 public {}
我有两个示例类文件,一个来自示例 Java 应用程序,一个来自示例 C 应用程序(使用 LLJVM 编译为字节码)。
查看它们的输出,我可以通过 javap -c -p 看到对于初始化(静态)字段,Java 应用程序显示以下块:
<clinit>
如果我理解的话,这基本上是方法。或者被我正在使用的虚拟机检测到。
然而,C-app 有这个:
这是什么?我的虚拟机没有检测到它。
示例类文件。第一个来自 Java 应用程序,它打印一条消息并等待 20 秒,重复。第二个是一个大致相同的 C 应用程序。
http://www.fast-files.com/getfile.aspx?file=156962
http://www.fast-files.com/getfile.aspx?file=156961
很抱歉这样做 - 我不立即知道如何附加文件或有效地显示 .class 文件。
java - 如何使用 ASM 修改常量池?
我已经从这篇文章中了解了如何使用 ASM 在运行时操作类。
但我对如何修改常量池还有进一步的疑问。下面是我要修改的示例 java 程序
主jar文件:
我想将变量a
从修改"Hello World"
为"Multiply Of x*y is: "
我的代理班
控制台窗口上的结果应该是
java - java字节码总是向前兼容吗?
我了解版本 JDK X 生成的字节码保证可以在 JVM Y 上工作,前提是 Y >= X。
这适用于所有版本的 JDK/JVM 吗?即期望 JDK 1 生成的类文件在 JVM 11 上工作是否公平?
参考JVM 规范、JDK 8 兼容性指南和Java 11 JSR 无法找到准确的答案。
spring - 哪个是与 JDK 1.8 和 spring 3.x 同步使用的正确版本的 asm、spring-asm 和 cglib?
项目详情: X-project 使用 asm.asm-2.2 cglib 2.2 版本 Y-project 使用 spring-asm 2.x 和 cglib 2.2.0.b2 X-project 作为依赖包含在 Y-project 上面的项目使用 apache-ivy和 apache ant 1.7.0 JDK 1.8
背景:-
Y 项目最初是使用 JDK 1.6 编译的,X 项目最初是使用 JDK 1.5 编译的。现在需要在 JAVA 1.8 中编译和运行 Y 项目。Y项目使用JDK 1.8成功编译。Y 项目现在使用 X 项目,它是在 JDK 1.5 中编译的。不修改 asm 和 spring-asm jar 的版本
问题陈述:- 在运行 Y-project 的 junit (version-3.8.1) 测试时,发生字节码 mismtach 错误。即,分支目标68处的预期stackmapframe
造成这种情况的原因(在 stackoverflow 中搜索)如下:- asm.asm jar,它操作 X 项目的 stackmap 帧和字节码。
怀疑是 - Y 项目使用 spring-asm 帮助启动其中的 bean,进而访问 X 项目的类。由于 X 项目的类已经有 asm.asm 2.2 jar 定义的堆栈图帧,因此 Y 项目的 spring asm 创建的字节码与 X 项目的不匹配
我尝试了以下方法:- 1.在X项目中将asm.asm jar的版本更改为5.0.3,但没有更改X项目使用的cglib版本 2.没有更改Y项目使用的spring-asm版本3. 当使用Java 1.8 编译X 项目并尝试运行它的Junit 测试类时,X 项目的cglib 2.2 jar 抛出class not found 错误- 即,它试图在asm 5.0.3 版本中查找一个类
请告诉我上面提到的场景中X和Y项目中需要使用哪些版本的jar-asm、spring-asm和cglib
java - Java 字节码 - 每个语句一个标签
编译器将javac
行号标签添加到与源代码中的新行相对应的每条指令。因此,当在一行中列出多个语句时,它们都属于同一行标签(L1
在下面显示的情况下,同一行上有两个打印语句)。
是否可以让编译器为每个语句输出一个标签?对于字节码分析任务,我想按语句(而不是按行)对指令进行分组。
源代码
字节码
(使用 Oracle JDK 8 编译,启用调试输出)
java - ASM - 使用 LocalVariableSorter 中的 newLocal 的奇怪 localVar 索引
我正在通过newLocal
from添加新的本地人LocalVariableSorter
。我要添加局部变量的方法是一个带有长参数的实例方法。我要添加两个本地人;一长一物。示例代码中没有其他本地变量。
结果,我预计会有以下插槽/索引:
我得到的回报newLocal
是 3 和 7。为什么会有这么大的差距?
更奇怪的是,当我xSTORE
使用这些索引添加指令并使用 javap 检查结果时,它向我显示:
注意:不仅值与我传递给 xSTORE 指令的值不同,而且它们之间的差距现在是 3 而不是之前的 4。
生成的代码虽然有效。我只是想了解这里发生了什么魔法以及为什么。
谢谢
java - bipush 如何在 JVM 中工作?
我知道 iload 接受整数 -1 到 5,但是如何使用 bipush 指令扩展到更高的数字?特定整数如何与字节码一起存储?