001package test; 002 003import java.io.File; 004import java.io.FileWriter; 005import java.io.IOException; 006import java.io.Writer; 007import java.net.URL; 008import java.net.URLClassLoader; 009import java.util.ArrayList; 010import java.util.Arrays; 011import java.util.List; 012import javax.tools.Diagnostic; 013import javax.tools.DiagnosticCollector; 014import javax.tools.JavaCompiler; 015import javax.tools.JavaFileObject; 016import javax.tools.StandardJavaFileManager; 017import javax.tools.ToolProvider; 018 019public class InlineCompiler { 020 021 public static void main(String[] args) { 022 StringBuilder sb = new StringBuilder(64); 023 sb.append("package testcompile;\n"); 024 sb.append("public class HelloWorld {\n"); 025 sb.append(" public void doStuff() {\n"); 026 sb.append(" System.out.println(\"Hello world\");\n"); 027 sb.append(" }\n"); 028 sb.append("}\n"); 029 030 File helloWorldJava = new File("/src/data/testcompile/HelloWorld.java"); 031 if (helloWorldJava.getParentFile().exists() || helloWorldJava.getParentFile().mkdirs()) { 032 033 try { 034 Writer writer = null; 035 try { 036 writer = new FileWriter(helloWorldJava); 037 writer.write(sb.toString()); 038 writer.flush(); 039 } finally { 040 try { 041 writer.close(); 042 } catch (Exception e) { 043 } 044 } 045 046 /** Compilation Requirements *********************************************************************************************/ 047 DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<JavaFileObject>(); 048 JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); 049 StandardJavaFileManager fileManager = compiler.getStandardFileManager(diagnostics, null, null); 050 051 // This sets up the class path that the compiler will use. 052 // I've added the .jar file that contains the DoStuff interface within in it... 053 List<String> optionList = new ArrayList<String>(); 054 optionList.add("-classpath"); 055 optionList.add(System.getProperty("java.class.path") + File.pathSeparator + "dist/InlineCompiler.jar"); 056 057 Iterable<? extends JavaFileObject> compilationUnit 058 = fileManager.getJavaFileObjectsFromFiles(Arrays.asList(helloWorldJava)); 059 JavaCompiler.CompilationTask task = compiler.getTask( 060 null, 061 fileManager, 062 diagnostics, 063 optionList, 064 null, 065 compilationUnit); 066 /********************************************************************************************* Compilation Requirements **/ 067 if (task.call()) { 068 /** Load and execute *************************************************************************************************/ 069 System.out.println("Yipe"); 070 // Create a new custom class loader, pointing to the directory that contains the compiled 071 // classes, this should point to the top of the package structure! 072 // URLClassLoader classLoader = new URLClassLoader(new URL[]{new File("/src/d/").toURI().toURL()}); 073 // // Load the class from the classloader by name.... 074 // Class<?> loadedClass = classLoader.loadClass("testcompile.HelloWorld"); 075 // // Create a new instance... 076 // Object obj = loadedClass.newInstance(); 077 // System.out.println("debug: " +obj); 078 // Santity check 079 // if (obj instanceof DoStuff) { 080 // // Cast to the DoStuff interface 081 // DoStuff stuffToDo = (DoStuff)obj; 082 // // Run it baby 083 // stuffToDo.doStuff(); 084 // } 085 /************************************************************************************************* Load and execute **/ 086 } else { 087 for (Diagnostic<? extends JavaFileObject> diagnostic : diagnostics.getDiagnostics()) { 088 System.out.format("Error on line %d in %s%n", 089 diagnostic.getLineNumber(), 090 diagnostic.getSource().toUri()); 091 } 092 } 093 fileManager.close(); 094 } catch (Exception exp) { 095 exp.printStackTrace(); 096 } 097 } 098 } 099}