我无法在屏幕上显示字节码。我想为hello World生成类似Javap Command的输出。
我创建了以下类和hello world类。任何人都可以让我知道我要做什么来生成字节码,我做错了什么?
**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,但我的代码现在没有编译,我得到像这样的例外; 线程“main”中的异常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());
}
}
}
答案 0 :(得分:2)
如果您希望将输出打印在屏幕上而不是打印到文件中,则替换
ClassWriter cw=new ClassWriter(0);
与
TraceClassVisitor cw = new TraceClassVisitor(new PrintWriter(System.out));
并替换
this.WriteClass(cw);
与
cw.print(new PrintWriter(System.out));
请参阅TreeClassVisitor javadoc并相应修改您的代码。
答案 1 :(得分:0)
import org.objectweb.asm.util.Textifier;
public class ByteCodeReader {
public static void main(String[] args) throws Exception {
String pathToClassFile = "<path to classfile of interest goes here>";
Textifier.main(pathToClassFile);
}
}
所以当你给出你感兴趣的字节码的类文件的确切绝对路径时,Textifier
通常会起作用。我试图看看它是否与相对路径一起工作,但似乎没有。
输出(字节代码指令)打印到标准输出。
另外,我用于Textifier
的jar是asm-util-4.0.jar
,所以不要忘记在构建路径中包含它。