How to Create Java class/es files dynamically?

2.2k Views Asked by At

I need a way to run a java method for ex. createModule("Login") and as an output to have:

  1. New folder named mod_login
  2. Inside on mod_login java classes files created from a template

If the template is

class Name extends Blah implement Blah {

    private createdInt;

    private int getCreatedInt() {
        return createdInt;
    }

}

In return I want to get a dynamically created class:

 class Login extends Blah implement Blah {

    private loginInt;

    private int getLoginInt() {
        return loginInt;
    }
}

Tried to look into groovy to do it, but could not find anything usefull.

P.S. it shouldn't happen on runtime, it's a more like a helper to instantiate these modules with just 1 button, instead of typing them

2

There are 2 best solutions below

0
On BEST ANSWER

Working example which will help you.

import java.io.File;
import java.io.FileWriter;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Arrays;

import javax.tools.JavaCompiler;
import javax.tools.JavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.StandardLocation;
import javax.tools.ToolProvider;

public class HelloWorld {

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

    // create an empty source file
    File sourceFile = File.createTempFile("Hello", ".java");
    sourceFile.deleteOnExit();

    // generate the source code, using the source filename as the class name
    String classname = sourceFile.getName().split("\\.")[0];
    String sourceCode = "public class " + classname + "{ public void hello() { System.out.print(\"Hello world\");}}";

    // write the source code into the source file
    FileWriter writer = new FileWriter(sourceFile);
    writer.write(sourceCode);
    writer.close();

    // compile the source file
    JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
    StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null);
    File parentDirectory = sourceFile.getParentFile();
    fileManager.setLocation(StandardLocation.CLASS_OUTPUT, Arrays.asList(parentDirectory));
    Iterable<? extends JavaFileObject> compilationUnits = fileManager.getJavaFileObjectsFromFiles(Arrays.asList(sourceFile));
    compiler.getTask(null, fileManager, null, null, null, compilationUnits).call();
    fileManager.close();

    // load the compiled class
    URLClassLoader classLoader = URLClassLoader.newInstance(new URL[] { parentDirectory.toURI().toURL() });
    Class<?> helloClass = classLoader.loadClass(classname);

    // call a method on the loaded class
    Method helloMethod = helloClass.getDeclaredMethod("hello");
    helloMethod.invoke(helloClass.newInstance());
 }
}
1
On

You just need 2 variables defined in a method which creates files dynamically.

className & propertyName

Now use these to create a file with .java extension and write the text from your template as is. For className and propertyName generation logic use the variables that you have above.

If you want to create more than one such files then take className & propertyName in a list and run a forloop.