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}