简体   繁体   中英

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

   }
}

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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM