2

画面にバイトコードを表示できません。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());
                }
        }

    }
4

2 に答える 2

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を参照し、それに応じてコードを変更してください。

于 2013-01-28T04:43:32.043 に答える
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通常は、関心のあるバイトコードを持つクラスファイルの正確な絶対パスを指定すると機能します。相対パスで機能するかどうかを確認しようとしましたが、そうではないようです。

出力(バイトコード命令)は標準出力に出力されます。

また、私が使用するjarTextifierはですasm-util-4.0.jarので、ビルドパスに含めることを忘れないでください。

于 2013-01-28T09:52:24.433 に答える