2

I am not able to display bytecodes on my screen. I want to generate output alike Javap Command for hello World.

I created following class and hello world class. Could any one please let me know what I have to do to generate bytecode and what am I doing wrong?

        **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();

                }
            }

I tried to use tracefilevisitor, but my code is not getting compiled now, I am getting Exceptions like this; Exception in thread "main" java.lang.IncompatibleClassChangeError: Implementing class can any body help me here please

      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();
            }
        }

Hi, I tried implementing the concept that you had ask but my code is still not working, I am attaching my code here that i want to run to display opcodes for my helloworld program. could you please help me in debugging this code? i implemented textifier but it seems it ask for string array object in main method. I tried converting my class file path but it didn't work. Could you please help here?

     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());
                }
        }

    }

2 Answers 2

2

if you want the output to be printed on screen rather than into a file then replace

ClassWriter cw=new ClassWriter(0);

with

TraceClassVisitor cw = new TraceClassVisitor(new PrintWriter(System.out));

and replace

this.WriteClass(cw);

with

cw.print(new PrintWriter(System.out));

see TreeClassVisitor javadoc and modify your code accordingly.

Sign up to request clarification or add additional context in comments.

1 Comment

hey, I posted my code. Could you help in debugging it please?
1
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);
    }
}

so the Textifier usually works when you give the exact absolute path of the class file whose bytecode you are interested in. i have tried to see if it works with a relative path,but it does not seem to.

The output (the byte code instructions) are printed to the standard out.

also, the jar i use for the Textifier is asm-util-4.0.jar, so do not forget to include that in your build path.

3 Comments

hey, so it usually works when you give the exact absolute path of the class file whose bytecode you are interested in. i have tried to see if it works with a relative path,but it does not. I have updated by answer to reflect this more clearly. Also, it would help if you could tell me exactly what isn't working. is it not giving you the output you desire or it just does not do anything?
I am not able to use Textifier. Is it specific to any jar??? can we use directly as you have used it? or we need to take an object or something??
yeah... so the jar i use is ... asm-util-4.0.jar. and the specific import statement is import org.objectweb.asm.util.Textifier; again, i have made the updates to the actual answer to reflect the same.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.