Hi I have requirement to create ,compile and load java classes run time. Using FTL i am creating java source files , and able to compile the source if there is no dynamic dependency.
To elaborate with an instance, I have two java source file, one interface and its implementation class. I am able to compile the interface using java compiler api as follows
String classpath=System.getProperty("java.class.path");
String testpath =classpath+";"+rootPath+"/lib/is_wls_client.jar;"+rootPath+"/rtds_wls_proxyclient.jar;.;";
File javaFile = new File(javaFileName+".java");
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
List<String> optionList = new ArrayList<String>();
optionList.addAll(Arrays.asList("-classpath",testpath));
StandardJavaFileManager sjfm = compiler.getStandardFileManager(null, null, null);
Iterable fileObjects = sjfm.getJavaFileObjects(javaFile);
JavaCompiler.CompilationTask task = compiler.getTask(null, null, null,optionList,null,fileObjects);
task.call();
sjfm.close();
I set class path for static classes which are already in the classpath , but this approach do not work for dynamically created classes? Any custom class loader will do the fix? My final implementation will be in web/app server
Any feedback will be highly appreciated
Satheesh
Type 'javac MyFirstJavaProgram. java' and press enter to compile your code. If there are no errors in your code, the command prompt will take you to the next line (Assumption: The path variable is set). Now, type ' java MyFirstJavaProgram ' to run your program.
The javac command reads source files that contain module, package and type declarations written in the Java programming language, and compiles them into class files that run on the Java Virtual Machine. The javac command can also process annotations in Java source files and classes.
In Java, programs are not compiled into executable files; they are compiled into bytecode (as discussed earlier), which the JVM (Java Virtual Machine) then executes at runtime. Java source code is compiled into bytecode when we use the javac compiler. The bytecode gets saved on the disk with the file extension .
I was able to solve this issue by compiling all the java files together. Using FTL I generate the java classes, and then compile it using java compiler api and load classes with custom class loader
Java Complier
private void compile(File[] files) throws IOException{
String classpath=System.getProperty("java.class.path");
String rootPath=getServletContext().getRealPath("/");
System.out.println("--> root Path "+rootPath);
String testpath=classpath+";.;xx.jar;yy.jar";
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
List<String> optionList = new ArrayList<String>();
optionList.addAll(Arrays.asList("-classpath",testpath));
// optionList.addAll(Arrays.asList("-d",rootPath+"/target"));
StandardJavaFileManager sjfm = compiler.getStandardFileManager(null, null, null);
Iterable fileObjects = sjfm.getJavaFileObjects(files);
JavaCompiler.CompilationTask task = compiler.getTask(null, null, null,optionList,null,fileObjects);
task.call();
sjfm.close();
}
Below code snippet shows how to use custom class loader
class CustomClassLoader extends ClassLoader {
public CustomClassLoader(ClassLoader parent) {
super(parent);
}
public Class findClass(String className,String path) {
byte[] classData = null;
try {
FileInputStream f = new FileInputStream(path);
int num = f.available();
classData = new byte[num];
f.read(classData);
} catch (IOException e) {
System.out.println(e);
}
Class x = defineClass(className, classData, 0, classData.length);
return x;
}
}
thanks Satheesh
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With