Doszi89
Doszi89

Reputation: 357

Adding new class to project programmatically

I read files from disc in my Java project. I find my hohoho.java file on D:/ and it's in File format, then I would like to add it as a class to existing package with my main class (Up.java). It should look like this - package -> Up.java, Hohoho.java.

And it should be done programmatically of course. I will use this .java file and it's functions in my Up.java.

Do you know any easy way to do this?

import org.apache.commons.io.FileUtils;
import java.io.File;
import java.lang.reflect.Array;
import java.util.Collection;
import java.util.Iterator;

public class Up{

public static void main(String[] args) {

    File root = new File("..\\.");
    File myfile = null;

    try {

        String[] extensions = {"java"};
        boolean recursive = true;

        Collection files = FileUtils.listFiles(root, extensions, recursive);

        for (Iterator iterator = files.iterator(); iterator.hasNext();) {
            File file = (File) iterator.next();
            String path = file.getAbsolutePath();
            System.out.println("File = " + path);

            String[] tokens = path.split("\\\\");

            for (String t : tokens)
              if (t.equals("Hohoho.java")){
                  myfile = file;
              }
            }

        System.out.println("Client class: " + myfile.getAbsolutePath());

    } catch (Exception e) {
        e.printStackTrace();
    }     

   }
}

Upvotes: 0

Views: 394

Answers (2)

Brian Henry
Brian Henry

Reputation: 3171

If you only need to load a .class file, per your comment, you should be able to just use something like the following (assuming no security issues in your setup):

    String path = "/path/to/your/classfiles/root/"; //not including the package structure
    ClassLoader loader = new URLClassLoader(new URL[]{new URL("file://" + path)}, Up.class.getClassLoader());

    Class clazz = loader.loadClass("foo.Hohoho"); //assuming a package "foo" for that class
    Object loadable = clazz.newInstance();
    Field field = loadable.getClass().getField("someField");  //or whatever - (this assumes you have someField on foo.Hohoho)

    System.out.println(field.get(loadable));

(I dropped all exception handling in the above). As @stemm pointed out, this is going to be painful to work with, just using pure Reflection.

Also, a quick test of invoking the java compiler, in the least complicated way possible, from within the VM follows. So, if case you do need to go from source, you can build off this:

    String sourcePath = "/path/to/your/javafiles/root/"; 
    JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
    int success = compiler.run(null, null, null,  sourcePath + "foo/Loadable.java");//can't get "-sourcepath","path" to go, for some reason.

    System.out.println("success = " + success); //should be 0; Sys err should have details, otherwise

Upvotes: 1

stemm
stemm

Reputation: 6040

Use Java Compiler API to compile source code into bytecode.

After that use ClassLoader to load compiled class into jvm and you're be able to execute methods of that class.

If you sure, that compiled class implements specific interface - you can cast it to target interface and call methods directly, otherwise - you're need to use Reflection

Upvotes: 1

Related Questions