我无法在屏幕上显示字节码。我想为 hello World 生成类似 Javap 命令的输出。
我创建了以下课程和你好世界课程。谁能让我知道我必须做什么来生成字节码以及我做错了什么?
**package com.gannon.ASMInterpreterMain;**
import java.io.FileOutputStream;
import java.io.IOException;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.FieldVisitor;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
public class CodeGenerator {
public void generateClass()
{
ClassWriter cw=new ClassWriter(0);
FieldVisitor fv;
MethodVisitor mv;
cw.visit(Opcodes.V1_6, Opcodes.ACC_PUBLIC, "com/gannon/ASMInterpreterMain/HelloWorldOutPut", null, "java/lang/Object", null);
mv=cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "()V", null, null);
mv.visitVarInsn(Opcodes.ALOAD, 0);
mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", "<init>", "()V");
mv.visitInsn(Opcodes.RETURN);
mv.visitMaxs(1, 1);
mv.visitEnd();
mv=cw.visitMethod(Opcodes.ACC_PUBLIC+ Opcodes.ACC_STATIC, "Main", "([Ljava/lang/String;)V", null, null);
mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
mv.visitLdcInsn("Test");
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V");
mv.visitInsn(Opcodes.RETURN);
mv.visitMaxs(2, 1);
mv.visitEnd();
cw.visitEnd();
this.WriteClass(cw);
}
public void WriteClass(ClassWriter cw){
FileOutputStream fos;
try{
fos = new FileOutputStream("C:\\Users\\Anish\\workspace\\ASMProject\\Main.class");
fos.write(cw.toByteArray());
fos.close();
}
catch (IOException ex){
System.out.println("Error: "+ex.getMessage());
//Logger.getLogger(CodeGenerator.class.getName()).log(Level.SEVERE, null, ex);
}
}
public static void main (String [] args){
CodeGenerator CG = new CodeGenerator();
CG.generateClass();
}
}
我尝试使用 tracefilevisitor,但我的代码现在没有被编译,我得到了这样的异常;线程“主”java.lang.IncompatibleClassChangeError 中的异常:实现类可以请任何人帮助我
package com.gannon.ASMInterpreterMain;
import java.io.PrintWriter;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.util.TraceClassVisitor;
public class CodeGenerator {
public void generateClass() {
ClassWriter cw = new ClassWriter(0);
TraceClassVisitor tc = new TraceClassVisitor(
new PrintWriter(System.out));
MethodVisitor mv;
tc.visit(Opcodes.V1_6, Opcodes.ACC_PUBLIC,
"com/gannon/ASMInterpreterMain/HelloWorldOutPut", null,
"java/lang/Object", null);
mv = tc.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "()V", null, null);
mv.visitVarInsn(Opcodes.ALOAD, 0);
mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", "<init>",
"()V");
mv.visitInsn(Opcodes.RETURN);
mv.visitMaxs(1, 1);
mv.visitEnd();
mv = tc.visitMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC, "Main",
"([Ljava/lang/String;)V", null, null);
mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/System", "out",
"Ljava/io/PrintStream;");
mv.visitLdcInsn("Test");
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/io/PrintStream",
"println", "(Ljava/lang/String;)V");
mv.visitInsn(Opcodes.RETURN);
mv.visitMaxs(2, 1);
mv.visitEnd();
tc.visitEnd();
byte [] b = cw.toByteArray();
System.out.println(b.length);
for (int i = 1; i < b.length; i++) {
System.out.println(b[i]);
}
}
// public void WriteClass(ClassWriter cw) {
// FileOutputStream fos;
// try {
// fos = new FileOutputStream(
// "C:\\Users\\Anish\\workspace\\ASMProject\\Main.class");
// fos.write(cw.toByteArray());
// fos.close();
// } catch (IOException ex) {
//
// System.out.println("Error: " + ex.getMessage());
// //Logger.getLogger(CodeGenerator.class.getName()).log(Level.SEVERE, null, ex);
// }
// }
//public static void main (String [] args){
// CodeGenerator CG = new CodeGenerator();
// CG.generateClass();
//}
public static void main(String[] args) throws Exception {
// String pathToClassFile = "C:\\Users\\Anish\\workspace\\ASMProject\\Main.class";
// Textifier.main(pathToClassFile);
CodeGenerator CG = new CodeGenerator();
CG.generateClass();
}
}
嗨,我尝试实现您提出的概念,但我的代码仍然无法正常工作,我将我的代码附在此处,我想运行它以显示我的 helloworld 程序的操作码。你能帮我调试这段代码吗?我实现了 textifier 但它似乎在 main 方法中要求字符串数组对象。我尝试转换我的类文件路径,但没有成功。你能帮忙吗?
package com.gannon.ASMInterpreterMain;
import java.io.PrintWriter;
import org.objectweb.asm.util.Textifier;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.util.TraceClassVisitor;
public class CodeGenerator {
public void generateClass() {
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
TraceClassVisitor tc = new TraceClassVisitor( cw,
new PrintWriter(System.out));
MethodVisitor mv;
tc.visit(Opcodes.V1_6, Opcodes.ACC_PUBLIC,
"com/gannon/ASMInterpreterMain/HelloWorldOutPut", null,
"java/lang/Object", null);
mv = tc.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "()V", null, null);
mv.visitVarInsn(Opcodes.ALOAD, 0);
mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", "<init>",
"()V");
mv.visitInsn(Opcodes.RETURN);
mv.visitMaxs(1, 1);
mv.visitEnd();
mv = tc.visitMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC, "Main",
"([Ljava/lang/String;)V", null, null);
mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/System", "out",
"Ljava/io/PrintStream;");
mv.visitLdcInsn("Test");
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/io/PrintStream",
"println", "(Ljava/lang/String;)V");
mv.visitInsn(Opcodes.RETURN);
mv.visitMaxs(2, 1);
mv.visitEnd();
tc.visitEnd();
byte [] b = cw.toByteArray();
System.out.println(b.length);
for (int i = 1; i < b.length; i++) {
System.out.println(b[i]);
}
}
public static void main (String [] args){
String[] pathToClassFile = {"com/gannon/ASMInterpreterMain/HelloWorldOutPut"};
try {
Textifier.main(pathToClassFile);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.out.println("Excption thrown from main is "+e.getMessage());
}
}
}