画面にバイトコードを表示できません。helloWorld用のJavapコマンドと同様の出力を生成したいと思います。
次のクラスとhelloworldクラスを作成しました。バイトコードを生成するために私がしなければならないことと、私が間違っていることを誰かに教えてもらえますか?
**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());
}
}
}