In my Application a User can tell the fields he wants for a CLASS. Those parameters are then concatenated using StringBuilder and I have something like this at the end.
String classname = "MyTestClassTest";
StringBuilder sourceCode = new StringBuilder();
String classname = "MyTestClassTest";
sourceCode.append("public class ");
sourceCode.append(classname);
sourceCode.append(" implements java.io.Serializable {");
sourceCode.append("public String testName");
sourceCode.append(";");
sourceCode.append("public int testNumber");
sourceCode.append(";");
sourceCode.append("public String toString() { return ");
sourceCode.append("\"NAME: \"");
sourceCode.append("+");
sourceCode.append("testName");
sourceCode.append(";");
sourceCode.append("}");
sourceCode.append("}");
CreateRuntimeClass codeExecuted = new CreateRuntimeClass(classname ,codeToExecute.toString() );
codeExecuted.createFileAndUpdateClassPath();
Then I use JavaCompiler to execute this code and a new CLASS is created.
Is there any better way to create new classes at runtime?
And does my way contains any issues?
Or any suggestion how I can improve my logic?
And does the byte code generated from compiling the code, is appended to the classpath, or how does it work?
What I have tried:
I am using the following code to generate classes at run time.
public class CreateRuntimeClass {
private String className;
private String sourceCode;
private String fileLocation = "C://Users//UserName//workspace//JavaDataStructures//bin//";
public CreateRuntimeClass (String className, String sourceCode) throws IOException, ClassNotFoundException, NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, InstantiationException {
this.className = className;
this.sourceCode = sourceCode;
}
public void createFileAndUpdateClassPath() throws IOException, ClassNotFoundException, NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, InstantiationException{
String fileName = this.fileLocation + className + ".java";
File myFile = new File(fileName);
FileWriter writer = new FileWriter(myFile);
writer.write("package datastructure; "+ sourceCode);
writer.close();
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null);
File parentDirectory = myFile.getParentFile();
fileManager.setLocation(StandardLocation.CLASS_OUTPUT, Arrays.asList(parentDirectory));
Iterable<? extends JavaFileObject> compilationUnits = fileManager.getJavaFileObjectsFromFiles(Arrays.asList(myFile));
compiler.getTask(null, fileManager, null, null, null, compilationUnits).call();
fileManager.close();
System.out.println(parentDirectory.toURI().toURL());
URLClassLoader classLoader = URLClassLoader.newInstance(new URL[] { parentDirectory.toURI().toURL() });
Class<?> helloClass = classLoader.loadClass("datastructure."+this.className);
}
}