Det her eksempel virker hos mig:
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.net.URI;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import javax.tools.Diagnostic;
import javax.tools.DiagnosticCollector;
import javax.tools.FileObject;
import javax.tools.ForwardingJavaFileManager;
import javax.tools.JavaCompiler;
import javax.tools.JavaFileObject;
import javax.tools.SimpleJavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;
import javax.tools.JavaCompiler.CompilationTask;
public class JC16 {
public static void main(String[] args) throws Exception {
testFileFile();
testMemoryFile();
testFileMemory();
testMemoryMemory();
}
public static void testFileFile() throws Exception {
PrintWriter pw = new PrintWriter(new FileWriter("Temp2.java"));
pw.println("public class Temp2 {");
pw.println(" public void test() {");
pw.println(" System.out.println(\"Temp2 OK\");");
pw.println(" }");
pw.println("}");
pw.close();
compileFileFile("Temp2.java", System.err);
Class<?> c = Class.forName("Temp2");
Object o = c.newInstance();
c.getMethod("test", new Class[] { }).invoke(o, new Object[] { });
}
public static void compileFileFile(String fnm, PrintStream err) {
JavaCompiler javac = ToolProvider.getSystemJavaCompiler();
DiagnosticCollector<JavaFileObject> diacol = new DiagnosticCollector<JavaFileObject>();
StandardJavaFileManager sjfm = javac.getStandardFileManager(diacol, null, null);
CompilationTask compile = javac.getTask(null, sjfm, diacol, Arrays.asList(new String[] { }), null,
sjfm.getJavaFileObjects(new String[] { fnm }));
boolean status = compile.call();
if(err != null) {
err.println("Compile status: " + status);
for(Diagnostic<? extends JavaFileObject> dia : diacol.getDiagnostics()) {
err.println(dia);
}
}
}
public static void testMemoryFile() throws Exception {
String src = "public class Temp3 { public void test() { System.out.println(\"Temp3 OK\"); } }";
compileMemoryFile(src, "Temp3", System.err);
Class<?> c = Class.forName("Temp3");
Object o = c.newInstance();
c.getMethod("test", new Class[] { }).invoke(o, new Object[] { });
}
public static void compileMemoryFile(String src, String name, PrintStream err) {
JavaCompiler javac = ToolProvider.getSystemJavaCompiler();
DiagnosticCollector<JavaFileObject> diacol = new DiagnosticCollector<JavaFileObject>();
StandardJavaFileManager sjfm = javac.getStandardFileManager(diacol, null, null);
CompilationTask compile = javac.getTask(null, sjfm, diacol, Arrays.asList(new String[] { }), null,
Arrays.asList(new JavaFileObject[] { new MemorySource(name, src) }));
boolean status = compile.call();
if(err != null) {
err.println("Compile status: " + status);
for(Diagnostic<? extends JavaFileObject> dia : diacol.getDiagnostics()) {
err.println(dia);
}
}
}
public static void testFileMemory() throws Exception {
PrintWriter pw = new PrintWriter(new FileWriter("Temp4.java"));
pw.println("public class Temp4 {");
pw.println(" public void test() {");
pw.println(" System.out.println(\"Temp4 OK\");");
pw.println(" }");
pw.println("}");
pw.close();
SpecialClassLoader xcl = new SpecialClassLoader();
compileFileMemory("Temp4.java", xcl, System.err);
Class<?> c = Class.forName("Temp4", true, xcl);
Object o = c.newInstance();
c.getMethod("test", new Class[] { }).invoke(o, new Object[] { });
}
public static void compileFileMemory(String fnm, SpecialClassLoader xcl, PrintStream err) {
JavaCompiler javac = ToolProvider.getSystemJavaCompiler();
DiagnosticCollector<JavaFileObject> diacol = new DiagnosticCollector<JavaFileObject>();
StandardJavaFileManager sjfm = javac.getStandardFileManager(diacol, null, null);
SpecialJavaFileManager xfm = new SpecialJavaFileManager(sjfm, xcl);
CompilationTask compile = javac.getTask(null, xfm, diacol, Arrays.asList(new String[] { }), null,
sjfm.getJavaFileObjects(new String[] { fnm }));
boolean status = compile.call();
if(err != null) {
err.println("Compile status: " + status);
for(Diagnostic<? extends JavaFileObject> dia : diacol.getDiagnostics()) {
err.println(dia);
}
}
}
public static void testMemoryMemory() throws Exception {
String src = "public class Temp5 { public void test() { System.out.println(\"Temp5 OK\"); } }";
SpecialClassLoader xcl = new SpecialClassLoader();
compileMemoryMemory(src, "Temp5", xcl, System.err);
Class<?> c = Class.forName("Temp5", true, xcl);
Object o = c.newInstance();
c.getMethod("test", new Class[] { }).invoke(o, new Object[] { });
}
public static void compileMemoryMemory(String src, String name, SpecialClassLoader xcl, PrintStream err) {
JavaCompiler javac = ToolProvider.getSystemJavaCompiler();
DiagnosticCollector<JavaFileObject> diacol = new DiagnosticCollector<JavaFileObject>();
StandardJavaFileManager sjfm = javac.getStandardFileManager(diacol, null, null);
SpecialJavaFileManager xfm = new SpecialJavaFileManager(sjfm, xcl);
CompilationTask compile = javac.getTask(null, xfm, diacol, Arrays.asList(new String[] { }), null,
Arrays.asList(new JavaFileObject[] { new MemorySource(name, src) }));
boolean status = compile.call();
if(err != null) {
err.println("Compile status: " + status);
for(Diagnostic<? extends JavaFileObject> dia : diacol.getDiagnostics()) {
err.println(dia);
}
}
}
}
class MemorySource extends SimpleJavaFileObject {
private String src;
public MemorySource(String name, String src) {
super(URI.create("
string:///" + name + ".java"), Kind.SOURCE);
this.src = src;
}
public CharSequence getCharContent(boolean ignoreEncodingErrors) {
return src;
}
public OutputStream openOutputStream() {
throw new IllegalStateException();
}
public InputStream openInputStream() {
return new ByteArrayInputStream(src.getBytes());
}
}
class MemoryByteCode extends SimpleJavaFileObject {
private ByteArrayOutputStream baos;
public MemoryByteCode(String name) {
super(URI.create("
byte:///" + name + ".class"), Kind.CLASS);
}
public CharSequence getCharContent(boolean ignoreEncodingErrors) {
throw new IllegalStateException();
}
public OutputStream openOutputStream() {
baos = new ByteArrayOutputStream();
return baos;
}
public InputStream openInputStream() {
throw new IllegalStateException();
}
public byte[] getBytes() {
return baos.toByteArray();
}
}
class SpecialJavaFileManager extends ForwardingJavaFileManager<StandardJavaFileManager> {
private SpecialClassLoader xcl;
public SpecialJavaFileManager(StandardJavaFileManager sjfm, SpecialClassLoader xcl) {
super(sjfm);
this.xcl = xcl;
}
public JavaFileObject getJavaFileForOutput(Location location, String name, JavaFileObject.Kind kind, FileObject sibling) throws IOException {
MemoryByteCode mbc = new MemoryByteCode(name);
xcl.addClass(name, mbc);
return mbc;
}
}
class SpecialClassLoader extends ClassLoader {
private Map<String,MemoryByteCode> m;
public SpecialClassLoader() {
m = new HashMap<String, MemoryByteCode>();
}
protected Class<?> findClass(String name) {
MemoryByteCode mbc = m.get(name);
return defineClass(name, mbc.getBytes(), 0, mbc.getBytes().length);
}
public void addClass(String name, MemoryByteCode mbc) {
m.put(name, mbc);
}
}