- 浏览: 3045839 次
- 性别:
- 来自: 海外
文章分类
- 全部博客 (430)
- Programming Languages (23)
- Compiler (20)
- Virtual Machine (57)
- Garbage Collection (4)
- HotSpot VM (26)
- Mono (2)
- SSCLI Rotor (1)
- Harmony (0)
- DLR (19)
- Ruby (28)
- C# (38)
- F# (3)
- Haskell (0)
- Scheme (1)
- Regular Expression (5)
- Python (4)
- ECMAScript (2)
- JavaScript (18)
- ActionScript (7)
- Squirrel (2)
- C (6)
- C++ (10)
- D (2)
- .NET (13)
- Java (86)
- Scala (1)
- Groovy (3)
- Optimization (6)
- Data Structure and Algorithm (3)
- Books (4)
- WPF (1)
- Game Engines (7)
- 吉里吉里 (12)
- UML (1)
- Reverse Engineering (11)
- NSIS (4)
- Utilities (3)
- Design Patterns (1)
- Visual Studio (9)
- Windows 7 (3)
- x86 Assembler (1)
- Android (2)
- School Assignment / Test (6)
- Anti-virus (1)
- REST (1)
- Profiling (1)
- misc (39)
- NetOA (12)
- rant (6)
- anime (5)
- Links (12)
- CLR (7)
- GC (1)
- OpenJDK (2)
- JVM (4)
- KVM (0)
- Rhino (1)
- LINQ (2)
- JScript (0)
- Nashorn (0)
- Dalvik (1)
- DTrace (0)
- LLVM (0)
- MSIL (0)
最新评论
-
mldxs:
虽然很多还是看不懂,写的很好!
虚拟机随谈(一):解释器,树遍历解释器,基于栈与基于寄存器,大杂烩 -
HanyuKing:
Java的多维数组 -
funnyone:
Java 8的default method与method resolution -
ljs_nogard:
Xamarin workbook - .Net Core 中不 ...
LINQ的恶搞…… -
txm119161336:
allocatestlye1 顺序为 // Fields o ...
最近做的两次Java/JVM分享的概要
一般我们写Java源码,用Java编译器编译出.class文件,是不会碰到校验失败的状况的,因为正常的Java编译器都会小心对待生成的代码。所以,想要看到校验失败的状况,很容易的一个办法就是自己生成不合法的字节码。
这里我用了ObjectWeb的ASM来生成字节码。可以从官网下载asm-3.1.jar,并保证其在编译和运行下面这个程序时在classpath上。
(本来是很想顺便试试Charles O. Nutter写的bitescript库,不过惰性上来了,懒得去下载……下次吧,下次)
运行该程序后,得到的是TestVerification.class文件,其内容是:
可以看到,foo()里代码先把float类型的常量0.0压到求值栈上(fconst_0),然后将它弹出并保存到局部存储区的第一格(fstore_0)。接下来从局部存储区的第一格取出一个int类型的值压到求值栈上(iload_0),再将其弹出并再次保存到局部存储区的第一格(istore_0)。
要是硬要用Java来表示这个.class文件里的逻辑,大概类似这样:
很明显这没办法用Java表达出来……
上面代码中,局部存储区的第一格就在同一个方法里前后用于保存了float和int类型的值,破坏了类型安全。JVM为了保证类型安全,要求局部存储区里每格在上一次store与下一次load之间只能保存固定类型的值,load/store与对应的格的类型必须匹配;上一次load与下一次store的类型则并不要求一致。
运行这个程序会导致校验错误:
于是JVM的类加载器先抱怨校验失败,然后拒绝加载这个main()方法,后面就连锁抱怨找不到main类。
用JDK8的话在通不过bytecode verification时JVM会报出更详细的错误。可以下载现在的试用版来试试
http://openjdk.java.net/jeps/136
好的,我试试。这样会很方便,哈哈!
用JDK8的话在通不过bytecode verification时JVM会报出更详细的错误。可以下载现在的试用版来试试
http://openjdk.java.net/jeps/136
这里我用了ObjectWeb的ASM来生成字节码。可以从官网下载asm-3.1.jar,并保证其在编译和运行下面这个程序时在classpath上。
(本来是很想顺便试试Charles O. Nutter写的bitescript库,不过惰性上来了,懒得去下载……下次吧,下次)
import java.io.FileOutputStream; import org.objectweb.asm.ClassWriter; import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.Opcodes; public class TestASM implements Opcodes { public static void main(String[] args) throws Exception { ClassWriter cw = new ClassWriter(0); cw.visit( V1_5, // class format version ACC_PUBLIC, // class modifiers "TestVerification", // class name fully qualified name null, // generic signature "java/lang/Object", // super class fully qualified name new String[] { } // implemented interfaces ); MethodVisitor mv = cw.visitMethod( ACC_PUBLIC, // access modifiers "foo", // method name "()V", // method descriptor null, // generic signature null // exceptions ); mv.visitCode(); mv.visitInsn(FCONST_0); mv.visitVarInsn(FSTORE, 1); mv.visitVarInsn(ILOAD, 1); mv.visitVarInsn(ISTORE, 1); mv.visitInsn(RETURN); mv.visitMaxs(1, 2); mv.visitEnd(); // end method cw.visitEnd(); // end class byte[] clz = cw.toByteArray(); FileOutputStream out = new FileOutputStream("TestVerification.class"); out.write(clz); out.close(); } }
运行该程序后,得到的是TestVerification.class文件,其内容是:
public class TestVerification extends java.lang.Object minor version: 0 major version: 49 Constant pool: const #1 = Asciz TestVerification; const #2 = class #1; // TestVerification const #3 = Asciz java/lang/Object; const #4 = class #3; // java/lang/Object const #5 = Asciz foo; const #6 = Asciz ()V; const #7 = Asciz Code; { public void foo(); Code: Stack=1, Locals=2, Args_size=1 0: fconst_0 1: fstore_0 2: iload_0 3: istore_0 4: return }
可以看到,foo()里代码先把float类型的常量0.0压到求值栈上(fconst_0),然后将它弹出并保存到局部存储区的第一格(fstore_0)。接下来从局部存储区的第一格取出一个int类型的值压到求值栈上(iload_0),再将其弹出并再次保存到局部存储区的第一格(istore_0)。
要是硬要用Java来表示这个.class文件里的逻辑,大概类似这样:
public class TestVerification { public void foo() { float a = 0; ((int) a) = a; } }
很明显这没办法用Java表达出来……
上面代码中,局部存储区的第一格就在同一个方法里前后用于保存了float和int类型的值,破坏了类型安全。JVM为了保证类型安全,要求局部存储区里每格在上一次store与下一次load之间只能保存固定类型的值,load/store与对应的格的类型必须匹配;上一次load与下一次store的类型则并不要求一致。
运行这个程序会导致校验错误:
D:\temp_code>java TestVerification Exception in thread "main" java.lang.VerifyError: (class: TestVerification, method: foo signature: ()V) Register 1 contains wrong type Could not find the main class: TestVerification. Program will exit.
于是JVM的类加载器先抱怨校验失败,然后拒绝加载这个main()方法,后面就连锁抱怨找不到main类。
评论
5 楼
changcheng
2013-05-31
RednaxelaFX 写道
changcheng 写道
问题找到了:
23: iload_1 应该使用 aload_1
23: iload_1 应该使用 aload_1
用JDK8的话在通不过bytecode verification时JVM会报出更详细的错误。可以下载现在的试用版来试试
http://openjdk.java.net/jeps/136
好的,我试试。这样会很方便,哈哈!
4 楼
RednaxelaFX
2013-05-23
changcheng 写道
问题找到了:
23: iload_1 应该使用 aload_1
23: iload_1 应该使用 aload_1
用JDK8的话在通不过bytecode verification时JVM会报出更详细的错误。可以下载现在的试用版来试试
http://openjdk.java.net/jeps/136
3 楼
changcheng
2013-05-23
问题找到了:
23: iload_1 应该使用 aload_1
23: iload_1 应该使用 aload_1
2 楼
changcheng
2013-05-23
//==== 补充 javap -c
public void setHSFContainer(java.lang.Object);
Code:
0: ldc #2; //class com/taobao/hsf/log/impl/CallbackComponent
2: ldc #51; //String setHSFContainer
4: ldc #52; //String (Ljava/lang/Object;)V
6: invokestatic #56; //Method com/tb/xman/common/hook/XManMethodCallBack.needHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;)Z
9: istore_2
10: iload_2
11: ifeq 29
14: ldc #57; //int 1
16: anewarray #4; //class java/lang/Object
19: astore_3
20: aload_3
21: ldc #58; //int 0
23: iload_1
24: aastore
25: aload_3
26: invokestatic #61; //Method com/tb/xman/common/hook/XManMethodCallBack.beforeMethod:([Ljava/lang/Object;)V
29: aload_0
30: aload_1
31: putfield #20; //Field container:Ljava/lang/Object;
34: invokestatic #23; //Method com/tb/xman/common/hook/XManMethodCallBack.beforeReturn:()V
37: return
public void setHSFContainer(java.lang.Object);
Code:
0: ldc #2; //class com/taobao/hsf/log/impl/CallbackComponent
2: ldc #51; //String setHSFContainer
4: ldc #52; //String (Ljava/lang/Object;)V
6: invokestatic #56; //Method com/tb/xman/common/hook/XManMethodCallBack.needHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;)Z
9: istore_2
10: iload_2
11: ifeq 29
14: ldc #57; //int 1
16: anewarray #4; //class java/lang/Object
19: astore_3
20: aload_3
21: ldc #58; //int 0
23: iload_1
24: aastore
25: aload_3
26: invokestatic #61; //Method com/tb/xman/common/hook/XManMethodCallBack.beforeMethod:([Ljava/lang/Object;)V
29: aload_0
30: aload_1
31: putfield #20; //Field container:Ljava/lang/Object;
34: invokestatic #23; //Method com/tb/xman/common/hook/XManMethodCallBack.beforeReturn:()V
37: return
1 楼
changcheng
2013-05-23
//====== asm 生成的代码
public void setHSFContainer(Object container)
{
boolean flag = XManMethodCallBack.needHook(com/tb/hsf/log/impl/CallbackComponent, "setHSFContainer", "(Ljava/lang/Object;)V");
if(flag)
{
Object aobj[] = new Object[1];
aobj[0] = container;
XManMethodCallBack.beforeMethod(aobj);
}
this.container = container;
XManMethodCallBack.beforeReturn();
}
//====== exception:
Exception in thread "main" java.lang.VerifyError: (class: com/tb/hsf/log/impl/CallbackComponent, method: setHSFContainer signature: (Ljava/lang/Object;)V) Register 1 contains wrong type
at java.lang.Class.getDeclaredConstructors0(Native Method)
at java.lang.Class.privateGetDeclaredConstructors(Class.java:2389)
at java.lang.Class.getConstructor0(Class.java:2699)
at java.lang.Class.newInstance0(Class.java:326)
at java.lang.Class.newInstance(Class.java:308)
at com.tb.hsf.container.HSFContainer.initCallbackService(HSFContainer.java:242)
at com.tb.hsf.container.HSFContainer.start(HSFContainer.java:208)
at runjettyrun.Bootstrap.main(Bootstrap.java:220)
这个是什么原因呢?
public void setHSFContainer(Object container)
{
boolean flag = XManMethodCallBack.needHook(com/tb/hsf/log/impl/CallbackComponent, "setHSFContainer", "(Ljava/lang/Object;)V");
if(flag)
{
Object aobj[] = new Object[1];
aobj[0] = container;
XManMethodCallBack.beforeMethod(aobj);
}
this.container = container;
XManMethodCallBack.beforeReturn();
}
//====== exception:
Exception in thread "main" java.lang.VerifyError: (class: com/tb/hsf/log/impl/CallbackComponent, method: setHSFContainer signature: (Ljava/lang/Object;)V) Register 1 contains wrong type
at java.lang.Class.getDeclaredConstructors0(Native Method)
at java.lang.Class.privateGetDeclaredConstructors(Class.java:2389)
at java.lang.Class.getConstructor0(Class.java:2699)
at java.lang.Class.newInstance0(Class.java:326)
at java.lang.Class.newInstance(Class.java:308)
at com.tb.hsf.container.HSFContainer.initCallbackService(HSFContainer.java:242)
at com.tb.hsf.container.HSFContainer.start(HSFContainer.java:208)
at runjettyrun.Bootstrap.main(Bootstrap.java:220)
这个是什么原因呢?
发表评论
-
The Prehistory of Java, HotSpot and Train
2014-06-02 08:18 0http://cs.gmu.edu/cne/itcore/vi ... -
MSJVM and Sun 1.0.x/1.1.x
2014-05-20 18:50 0当年的survey paper: http://www.sym ... -
Sun JDK1.4.2_28有TieredCompilation
2014-05-12 08:48 0原来以前Sun的JDK 1.4.2 update 28就已经有 ... -
IBM JVM notes (2014 ver)
2014-05-11 07:16 0Sovereign JIT http://publib.bou ... -
class data sharing by Apple
2014-03-28 05:17 0class data sharing is implement ... -
Java 8与静态工具类
2014-03-19 08:43 16259以前要在Java里实现所谓“静态工具类”(static uti ... -
Java 8的default method与method resolution
2014-03-19 02:23 10447先看看下面这个代码例子, interface IFoo { ... -
HotSpot Server VM与Server Class Machine
2014-02-18 13:21 0HotSpot VM历来有Client VM与Server V ... -
Java 8的lambda表达式在OpenJDK8中的实现
2014-02-04 12:08 0三月份JDK8就要发布首发了,现在JDK8 release c ... -
GC stack map与deopt stack map的异同
2014-01-08 09:56 0两者之间不并存在包含关系。它们有交集,但也各自有特别的地方。 ... -
HotSpot Server Compiler与data-flow analysis
2014-01-07 17:41 0http://en.wikipedia.org/wiki/Da ... -
字符串的一般封装方式的内存布局 (1): 元数据与字符串内容,整体还是分离?
2013-11-07 17:44 22379(Disclaimer:未经许可请 ... -
字符串的一般封装方式的内存布局
2013-11-01 12:55 0(Disclaimer:未经许可请 ... -
关于string,内存布局,C++ std::string,CoW
2013-10-30 20:45 0(Disclaimer:未经许可请 ... -
对C语义的for循环的基本代码生成模式
2013-10-19 23:12 21860之前有同学在做龙书(第二版)题目,做到8.4的练习,跟我对答案 ... -
Java的instanceof是如何实现的
2013-09-22 16:57 0Java语言规范,Java SE 7版 http://docs ... -
oop、klass、handle的关系
2013-07-30 17:34 0oopDesc及其子类的实例 oop : oopDesc* ... -
Nashorn各种笔记
2013-07-15 17:03 0http://bits.netbeans.org/netbea ... -
《深入理解Java虚拟机(第二版)》书评
2013-07-08 19:19 0值得推荐的中文Java虚拟机入门书 感谢作者赠与的样书,以下 ... -
豆列:从表到里学习JVM实现
2013-06-13 14:13 48335刚写了个学习JVM用的豆列跟大家分享。 豆列地址:http: ...
相关推荐
在这个例子中,`calculateCRC`方法接收一个字节数组作为输入,逐位进行CRC计算。`POLYNOMIAL`常量代表生成多项式,`crc`变量用于存储CRC寄存器的值。在`main`方法中,可以使用这个类来计算特定数据的CRC16校验码。 ...
其核心在于利用特定的数学方法(通常基于二进制多项式运算)来计算一个校验值,该值随后被附加到原始数据之后一同发送。接收端收到数据后,同样使用相同的算法计算接收到的数据的CRC校验值,并与接收到的CRC值进行...
CRC(Cyclic Redundancy Check,循环冗余校验)是一种广泛应用于数据通信领域中的错误检测技术,它通过计算一个固定长度的校验码并将其附加到原始数据之后,接收方通过对收到的数据执行相同的计算来验证数据传输过程...
在这个例子中,我们首先定义了一个字符串`inputString`,然后使用`getInstance("MD5")`创建了MD5哈希实例。接着,通过`digest()`方法计算出`inputString`的MD5摘要,这是一个字节数组。为了将字节转换成人类可读的...
= 保镖 = 字节码校验器 = ByteCode Verifier = 翻译 = 解释执行器 = Interfreter 2:安全 健壮 电力 电信 银行 都会有限考虑使用java实现 3:免费 开源 4:简单 语法简单:c++-- (取其精华 去其糟粕) ...
MD5码,全称为Message-Digest Algorithm 5,是一种广泛使用的加密散列函数,产生一个128位(16字节)的散列值,通常以32个十六进制数字的形式表示。在Java编程语言中,MD5被用作生成数据校验和,以验证文件或字符串...
下面将详细探讨Java如何实现这一功能。 在Java中,实现断点续传通常涉及到以下几个关键知识点: 1. **文件IO操作**:Java的`java.io`包提供了丰富的文件输入/输出流类,如`FileInputStream`、`FileOutputStream`、...
- **Java虚拟机**:是一种虚拟计算平台,能够在各种操作系统上运行Java字节码。它是Java实现跨平台的关键。 - **Java字节码**:是Java源代码编译后的中间代码,是一种与平台无关的格式,可以在任何安装了Java虚拟机...
Java邮件发送是一个常见的任务,尤其在企业级应用中,它经常用于发送通知、报告或附件。本教程将深入探讨如何使用纯Java流实现邮件发送功能,重点在于理解邮件协议和如何处理文件传输。 首先,我们需要了解JavaMail...
在Java中,MD5常用于密码加密、文件校验等方面,因为其不可逆性,可以有效防止原始数据被恢复,增加了数据的安全性。 本实例是关于如何在Java中使用MD5进行数据加密的实践。以下将详细介绍如何通过Java实现MD5加密...
标题《分享JavaScript与Java中MD5使用两个例子》中的知识点涉及了如何在JavaScript和Java语言中使用MD5加密算法,以及如何将字符串转换为MD5格式。MD5是一种广泛使用的密码散列函数,它可以产生一个128位的散列值...
Java的字节码校验器(A选项)确实加载了执行程序所需的类,但它不是安全相关的描述。正确的是,执行代码由运行时解释器完成(B选项),在运行时字节码被加载、验证并在解释器中运行(C选项)。类加载器(D选项)通过...
Java串口操作是Java编程中一个相对特殊但重要的领域,主要涉及到硬件通信和设备交互。在实际应用中,比如工业自动化、物联网设备控制等场景,Java串口编程扮演着关键角色。标题提到的问题是关于数据传输时遇到的一个...
1. **当遇到`new`、`getstatic`、`putstatic`或`invokestatic`这四条字节码指令时**,例如使用`new`关键字实例化对象、读取或设置一个类的静态字段(被`static`关键字修饰)、以及调用一个类的静态方法时。...
另一个例子是Java的反射API,它利用类装载机制在运行时动态访问和操作类的属性和方法。 总的来说,理解Java虚拟机的类装载机制对于深入掌握Java应用程序的运行机制至关重要。通过自定义ClassLoader,开发者可以实现...
在这个例子中,我们首先通过`getInstance("MD5")`获取一个MD5的MessageDigest实例。然后使用`update()`方法更新待加密的数据,接着调用`digest()`获取计算后的哈希值。最后,我们将得到的字节数组转换为16进制字符串...
以下是一个简单的示例,展示了如何使用Java调用MD5加密来计算一个字符串的摘要值: ```java import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; public class MD5Example { ...
在这个例子中,`getMD5`方法接收一个字符串,使用`MessageDigest.getInstance("MD5")`创建一个MD5实例,然后对输入字符串的字节进行哈希处理。得到的结果是一个字节数组,接着通过`String.format("%02x", 0xFF & b)`...
MD5(Message-Digest Algorithm 5)是一种...总的来说,Java中的MD5加密是一个简单但重要的概念,对于理解和实现数据安全的初级阶段至关重要。然而,随着安全需求的提高,开发者应当考虑使用更先进的加密算法和实践。