AllainLG
AllainLG

Reputation: 108

Getting methods from a chosen file's class in java

I'd like to get all the methods from a file (.text or .java), but I don't know the file's name yet (the user can choose it with jFileChooser). So I don't know the class's name. I have this code:

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import javax.swing.JFileChooser;


public class Test {

   public static void main(String[] args) throws Throwable {

        JFileChooser fc = new JFileChooser();
        File f = null;
        if (fc.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) {
            f = fc.getSelectedFile();
        }
        int errorCode = com.sun.tools.javac.Main.compile(new String[]{
                    "-classpath", "bin",
                    "-d", "../Tmp",
                    f.getAbsolutePath()});


        System.out.println("errorCode:" + errorCode);
        File classesDir = new File("../Tmp");


        ClassLoader parentLoader = Test.class.getClassLoader();

        URLClassLoader loader1 = new URLClassLoader(
                new URL[]{classesDir.toURL()}, parentLoader);

        BufferedReader br = new BufferedReader(new FileReader(f));
        String load = "";
        while ((load = br.readLine()) != null) {
            if (load.startsWith("package")) {
                load = load.replaceAll("package", "") + "." + f.getName().substring(0, f.getName().indexOf("."));
                load = load.replace(";", "").trim();
                break;
            }
        }
        Class cls1 = loader1.loadClass(load);
        Method[] methods = cls1.getDeclaredMethods();
        for (Method m : methods) {      
            System.out.println(m.getName());
        }
    }
}

It works, if the class doesn't contains "extends", or uses another class's methods, but if it do, I get errors. What should I do to fix these problems? I think it has to do something with "classpath" and "bin"

Upvotes: 1

Views: 467

Answers (1)

erickson
erickson

Reputation: 269817

It does have to do with the -classpath bin option. The compiler needs to have access to all of the classes that the target class depends on. If you want to keep using this approach, you'll have to give the user some way to define their own classpath, to include something other than "bin".

It's not clear what your goal is, but other options include:

  • Working with classes the user has already compiled
  • Simply parsing the file, rather than compiling it into a Java class

Elaborating on the second option, you could use a Java parser to analyze the text. Usually the parser will create a tree structure, an abstract syntax tree, which the compiler traverses, often several times doing different compilation steps. However, parsing doesn't have to be followed by compilation; you can do whatever analysis you like on the AST.

I have used the ANTLR Java grammar. It produces an AST, and the ANTLR toolkit provides a grammar that you can use to write a "tree parser" that performs the actions you write when it finds certain structures in the AST. This "tree parser" concept is unique to ANTLR; most grammars will just stop with the AST.

Upvotes: 3

Related Questions