Skip to content

Instantly share code, notes, and snippets.

@chrisvest
Created March 30, 2014 14:53
Show Gist options
  • Save chrisvest/9873843 to your computer and use it in GitHub Desktop.
Save chrisvest/9873843 to your computer and use it in GitHub Desktop.
Example showing how to generate, compile, load and run Java programs at run-time.
import javax.tools.*;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.lang.reflect.Method;
import java.net.URI;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
public class CodeGenMeta {
public static void main(String[] args) throws Exception {
String program = "" +
"public class CodeGenTest {\n" +
" public static void main(String[] args) {\n" +
" System.out.println(\"Hello World, from a generated program!\");\n" +
" }\n" +
"}\n";
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
JavaFileObject compilationUnit =
new StringJavaFileObject("CodeGenTest", program);
SimpleJavaFileManager fileManager =
new SimpleJavaFileManager(compiler.getStandardFileManager(null, null, null));
JavaCompiler.CompilationTask compilationTask = compiler.getTask(
null, fileManager, null, null, null, Arrays.asList(compilationUnit));
compilationTask.call();
CompiledClassLoader classLoader =
new CompiledClassLoader(fileManager.getGeneratedOutputFiles());
Class<?> codeGenTest = classLoader.loadClass("CodeGenTest");
Method main = codeGenTest.getMethod("main", String[].class);
main.invoke(null, new Object[]{null});
}
private static class StringJavaFileObject extends SimpleJavaFileObject {
private final String code;
public StringJavaFileObject(String name, String code) {
super(URI.create("string:///" + name.replace('.', '/') + Kind.SOURCE.extension),
Kind.SOURCE);
this.code = code;
}
@Override
public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException {
return code;
}
}
private static class ClassJavaFileObject extends SimpleJavaFileObject {
private final ByteArrayOutputStream outputStream;
private final String className;
protected ClassJavaFileObject(String className, Kind kind) {
super(URI.create("mem:///" + className.replace('.', '/') + kind.extension), kind);
this.className = className;
outputStream = new ByteArrayOutputStream();
}
@Override
public OutputStream openOutputStream() throws IOException {
return outputStream;
}
public byte[] getBytes() {
return outputStream.toByteArray();
}
public String getClassName() {
return className;
}
}
private static class SimpleJavaFileManager extends ForwardingJavaFileManager {
private final List<ClassJavaFileObject> outputFiles;
protected SimpleJavaFileManager(JavaFileManager fileManager) {
super(fileManager);
outputFiles = new ArrayList<ClassJavaFileObject>();
}
@Override
public JavaFileObject getJavaFileForOutput(Location location, String className, JavaFileObject.Kind kind, FileObject sibling) throws IOException {
ClassJavaFileObject file = new ClassJavaFileObject(className, kind);
outputFiles.add(file);
return file;
}
public List<ClassJavaFileObject> getGeneratedOutputFiles() {
return outputFiles;
}
}
private static class CompiledClassLoader extends ClassLoader {
private final List<ClassJavaFileObject> files;
private CompiledClassLoader(List<ClassJavaFileObject> files) {
this.files = files;
}
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
Iterator<ClassJavaFileObject> itr = files.iterator();
while (itr.hasNext()) {
ClassJavaFileObject file = itr.next();
if (file.getClassName().equals(name)) {
itr.remove();
byte[] bytes = file.getBytes();
return super.defineClass(name, bytes, 0, bytes.length);
}
}
return super.findClass(name);
}
}
}
@VishwasDhanwani1729
Copy link

what if the .java file consists of import statements.
when I tried it showed no such class found?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment