javaclassclasspathbytecodebcel

Translate package+class name to .class filename


I'm writing a program which analyzes .class files. I want to attach package and class name to my output.

My plan is to write a function which takes the package and class name as input and finds the corresponding .class file (so the user doesn't have to enter that as well, and can't get it wrong), where 'find' should be read as 'give me some data I can use as arguments for BCEL's ClassParser constructor' (either a filename, or a name of a zip file and a name within the zip file).

How do I go about that? Does java come with something which does that? I understand name resolution to be done in the context of a CLASSPATH, so the user should probably supply one of those as well; that's fine.

Note: solutions should not execute any code from the .class file. Just the bytes, ma'm ;-)


Solution

  • Well, if you are using BCEL, everything is already there, see ClassPath:

    import java.io.IOException;
    import org.apache.bcel.classfile.ClassParser;
    import org.apache.bcel.classfile.JavaClass;
    import org.apache.bcel.util.ClassPath;
    
    public class BcelTest {
        public static void main(String[] args) throws IOException {
            String classPath=System.getProperty("java.class.path");
            // demonstrating with our own class path examplary for an arbitrary path String
            ClassPath cp=new ClassPath(classPath);
            ClassPath.ClassFile cf=cp.getClassFile(BcelTest.class.getName());
            ClassParser p=new ClassParser(cf.getInputStream(), cf.getPath());
            JavaClass jc = p.parse();
            System.out.println(jc);
    
            // or just using our own system path explicitly
            cf=ClassPath.SYSTEM_CLASS_PATH.getClassFile("java.lang.Object");
            p=new ClassParser(cf.getInputStream(), cf.getPath());
            jc = p.parse();
            System.out.println(jc);
        }
    }