使用asmtools产生jasm文件遇到的问题
在学习郑雨迪的课程《深入拆解Java虚拟机》这门课,在模块一的第一讲,他留了一个作业,作业如下
echo '
public class Foo {
public static void main(String[] args) {
boolean flag = true;
if (flag) System.out.println("Hello, Java!");
if (flag == true) System.out.println("Hello, JVM!");
}
}' > Foo.java
javac Foo.java
java Foo
java -cp /path/to/asmtools.jar org.openjdk.asmtools.jdis.Main Foo.class > Foo.jasm.1
awk 'NR==1,/iconst_1/{sub(/iconst_1/, "iconst_2")} 1' Foo.jasm.1 > Foo.jasm
java -cp /path/to/asmtools.jar org.openjdk.asmtools.jasm.Main Foo.jasm
java Foo
第一次运行java Foo
的结果是
Hello, Java!
Hello, JVM!
。
我在使用java -cp /path/to/asmtools.jar org.openjdk.asmtools.jdis.Main Foo.class > Foo.jasm.1
的时候出了问题,具体原因如下:
我从网上下载的jar包里面缺少对应的方法,然后我改用下载源码然后build,得到jar包,另外java -cp
后面的jar包的路径不要弄错了,这样就不会出错。
得到的jasm文件内容如下:
super public class Foo
version 61:0
{
public Method "<init>":"()V"
stack 1 locals 1
{
aload_0;
invokespecial Method java/lang/Object."<init>":"()V";
return;
}
public static Method main:"([Ljava/lang/String;)V"
stack 2 locals 2
{
iconst_1;
istore_1;
iload_1;
ifeq L14;
getstatic Field java/lang/System.out:"Ljava/io/PrintStream;";
ldc String "Hello, Java!";
invokevirtual Method java/io/PrintStream.println:"(Ljava/lang/String;)V";
L14: stack_frame_type append;
locals_map int;
iload_1;
iconst_1;
if_icmpne L27;
getstatic Field java/lang/System.out:"Ljava/io/PrintStream;";
ldc String "Hello, JVM!";
invokevirtual Method java/io/PrintStream.println:"(Ljava/lang/String;)V";
L27: stack_frame_type same;
return;
}
} // end Class Foo
在执行awk 'NR==1,/iconst_1/{sub(/iconst_1/, "iconst_2")} 1' Foo.jasm.1 > Foo.jasm
java -cp ./asmtools.jar org.openjdk.asmtools.jasm.Main Foo.jasm
这两行命令之后,使用java Foo
运行,得到的结果是
Hello, Java!