Skip to content

Instantly share code, notes, and snippets.

@making
Created April 22, 2014 12:06
Show Gist options
  • Save making/11176223 to your computer and use it in GitHub Desktop.
Save making/11176223 to your computer and use it in GitHub Desktop.
import javax.tools.*;
import javax.tools.JavaCompiler.CompilationTask;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URI;
import java.security.SecureClassLoader;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;
import java.util.UUID;
public class CompileSourceInMemory {
public static void main(String args[]) throws IOException {
for (int i = 0; i < 2; i++) {
// コンパイラの取得
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
// コレクターの準備
DiagnosticCollector<JavaFileObject> collector =
new DiagnosticCollector<>();
try (
// 仮想ファイルマネージャの取得
StandardJavaFileManager fileManager
= compiler.getStandardFileManager(collector, null, null);
) {
String uuid = UUID.randomUUID().toString().replace("-", "");
String className = "HelloWorld_" + uuid;
// コンパイルするファイルの準備
String src =
"import java.util.concurrent.Callable;" +
"import java.util.Date;" +
"public class " + className + " {" +
"public static void main(String args[]) throws Exception {" +
"Callable<Date> callable = Date::new;" +
"System.out.println(callable.call());" +
"System.out.println(System.getProperties());" +
"Thread th = new Thread(() -> {System.out.println(\"hi!\");});th.run();" +
"System.out.println(\"This is in another java file\");" +
"}" +
"}";
JavaFileObject file = new StringFileObject(className, src);
Iterable<String> compileOptions = Arrays.asList("-d", "out\\production\\untitled2"/*, "-verbose"*/);
List<? extends JavaFileObject> fileObjects = Arrays.asList(file);
CompilationTask task = compiler.getTask(
null,
fileManager,
collector,
compileOptions,
null,
fileObjects
);
boolean success = task.call();
for (Diagnostic<?> diagnostic : collector.getDiagnostics()) {
System.out.println(diagnostic.getKind() + " " + diagnostic.getMessage(Locale.getDefault()));
String sourceCode = ((StringFileObject) diagnostic.getSource()).getCode();
String a = sourceCode.substring(0, (int) diagnostic.getStartPosition());
String b = sourceCode.substring((int) diagnostic.getStartPosition(), (int) diagnostic.getEndPosition());
String c = sourceCode.substring((int) diagnostic.getEndPosition());
System.out.println(a + " >>>> " + b + " <<<< " + c);
}
System.out.println("Success: " + success);
if (success) {
try {
ClassLoader classLoader = new MyClassLoader();
System.setSecurityManager(new SecurityManager());
Class<?> clazz = classLoader.loadClass(className);
Method method = clazz.getMethod("main", new Class[]{String[].class});
method.invoke(null, new Object[]{null});
} catch (ClassNotFoundException e) {
System.err.println("Class not found: " + e);
} catch (NoSuchMethodException e) {
System.err.println("No such method: " + e);
} catch (IllegalAccessException e) {
System.err.println("Illegal access: " + e);
} catch (InvocationTargetException e) {
System.err.println("Invocation target: " + e);
e.printStackTrace();
} finally {
System.setSecurityManager(null);
}
}
}
}
}
}
class MyClassLoader extends SecureClassLoader {
MyClassLoader() {
super();
}
}
class StringFileObject extends SimpleJavaFileObject {
private final String code;
StringFileObject(String name, String code) {
super(URI.create("string:///" + name.replace('.', '/') +
Kind.SOURCE.extension), Kind.SOURCE);
this.code = code;
}
@Override
public CharSequence getCharContent(boolean ignoreEncodingErrors) {
return code;
}
public String getCode() {
return code;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment