Self
Self

Reputation: 147

How to access methods of inner classes using ASM?

I am trying to print out instructions of all methods in .class file. The code below prints out instructions of the outer class's method (main) only.

How can I access the inner classes' methods? I read that I can load the inner class as I do for the outer class. How can I do this?

import java.io.InputStream;
import java.io.FileInputStream;
import java.io.StringWriter;
import java.io.PrintWriter;
import java.util.List;
import org.objectweb.asm.*;
import org.objectweb.asm.tree.*;
import org.objectweb.asm.util.*;

public class ClassInfoReader {

    public static void main(String[] args) throws Exception{
        InputStream in = new FileInputStream("MyInfo.class");
        ClassReader reader = new ClassReader(in);
        ClassNode classNode = new ClassNode();
        reader.accept(classNode,0);
        @SuppressWarnings("unchecked")
        final List<MethodNode> methods = classNode.methods;
        for(MethodNode m: methods){
             InsnList inList = m.instructions;
             System.out.println(m.name);
             for(int i = 0; i< inList.size(); i++){
                 System.out.print(insnToString(inList.get(i)));
             }
        }

        final List<InnerClassNode> classes = classNode.innerClasses;
        System.out.println(classes);
        for(InnerClassNode c: classes){
             System.out.println(c.innerName);
        }
    }

    public static String insnToString(AbstractInsnNode insn){
        insn.accept(mp);
        StringWriter sw = new StringWriter();
        printer.print(new PrintWriter(sw));
        printer.getText().clear();
        return sw.toString();
    }

    private static Printer printer = new Textifier();
    private static TraceMethodVisitor mp = new TraceMethodVisitor(printer);

This part of the code only shows basic information about inner classes, e.g. name of inner classes, name of outer class and the access flags.

final List<InnerClassNode> classes = classNode.innerClasses;
        for(InnerClassNode c: classes){
             System.out.println(c.innerName);
        } 

Upvotes: 1

Views: 1504

Answers (1)

Antimony
Antimony

Reputation: 39441

Nested classes were not part of the original Java. They were only added in Java 1.1, and so they had to be retrofitted to the existing classfile format. Therefore, at the bytecode level, nested classes are just ordinary classes in separate classfiles. The only thing that distinguishes them are a couple of metadata attributes which hold information about the source level nested classes for purposes of reflection and compilation.

So the way to access a nested class is to load it and process it like any other class. You already figured out how to get the names of the nested classes, now you just need to create a new ClassFileReader and load each of them recursively.

Upvotes: 2

Related Questions