|
1 | 1 | package org.mdkt.compiler; |
2 | 2 |
|
| 3 | +import java.io.IOException; |
| 4 | +import java.util.Collection; |
| 5 | +import java.util.HashMap; |
| 6 | +import java.util.Iterator; |
| 7 | +import java.util.Map; |
| 8 | + |
| 9 | +import javax.tools.Diagnostic; |
| 10 | +import javax.tools.DiagnosticListener; |
3 | 11 | import javax.tools.JavaCompiler; |
4 | 12 | import javax.tools.JavaFileObject; |
5 | 13 | import javax.tools.ToolProvider; |
6 | | -import java.util.Arrays; |
7 | 14 |
|
8 | 15 | /** |
9 | 16 | * Created by trung on 5/3/15. |
| 17 | + * Edited by turpid-monkey on 9/25/15, added support for multiple, dependent compile units. |
10 | 18 | */ |
11 | 19 | public class InMemoryJavaCompiler { |
12 | | - static JavaCompiler javac = ToolProvider.getSystemJavaCompiler(); |
13 | | - |
14 | | - public static Class<?> compile(String className, String sourceCodeInText) throws Exception { |
15 | | - SourceCode sourceCode = new SourceCode(className, sourceCodeInText); |
16 | | - CompiledCode compiledCode = new CompiledCode(className); |
17 | | - Iterable<? extends JavaFileObject> compilationUnits = Arrays.asList(sourceCode); |
18 | | - DynamicClassLoader cl = new DynamicClassLoader(ClassLoader.getSystemClassLoader()); |
19 | | - ExtendedStandardJavaFileManager fileManager = new ExtendedStandardJavaFileManager(javac.getStandardFileManager(null, null, null), compiledCode, cl); |
20 | | - JavaCompiler.CompilationTask task = javac.getTask(null, fileManager, null, null, null, compilationUnits); |
21 | | - boolean result = task.call(); |
22 | | - return cl.loadClass(className); |
23 | | - } |
| 20 | + JavaCompiler javac; |
| 21 | + DynamicClassLoader classLoader; |
| 22 | + |
| 23 | + Map<String, SourceCode> clazzCode = new HashMap<String, SourceCode>(); |
| 24 | + |
| 25 | + public InMemoryJavaCompiler(ClassLoader parent) { |
| 26 | + this(ToolProvider.getSystemJavaCompiler(), parent); |
| 27 | + } |
| 28 | + |
| 29 | + public InMemoryJavaCompiler(JavaCompiler javac, ClassLoader parent) { |
| 30 | + this.javac = javac; |
| 31 | + this.classLoader = new DynamicClassLoader(parent); |
| 32 | + } |
| 33 | + |
| 34 | + public InMemoryJavaCompiler() { |
| 35 | + this(ToolProvider.getSystemJavaCompiler(), ClassLoader |
| 36 | + .getSystemClassLoader()); |
| 37 | + } |
| 38 | + |
| 39 | + public void addSource(String className, String sourceCodeInText) |
| 40 | + throws Exception { |
| 41 | + clazzCode.put(className, new SourceCode(className, sourceCodeInText)); |
| 42 | + } |
| 43 | + |
| 44 | + public Map<String, Class<?>> compileAll() throws Exception { |
| 45 | + Collection<SourceCode> compilationUnits = clazzCode.values(); |
| 46 | + CompiledCode[] code; |
| 47 | + |
| 48 | + code = new CompiledCode[compilationUnits.size()]; |
| 49 | + Iterator<SourceCode> iter = compilationUnits.iterator(); |
| 50 | + for (int i=0; i<code.length; i++) |
| 51 | + { |
| 52 | + code[i] = new CompiledCode(iter.next().getClassName()); |
| 53 | + } |
| 54 | + |
| 55 | + ExtendedStandardJavaFileManager fileManager = new ExtendedStandardJavaFileManager( |
| 56 | + javac.getStandardFileManager(null, null, null), classLoader); |
| 57 | + JavaCompiler.CompilationTask task = javac.getTask(null, fileManager, |
| 58 | + null, null, null, compilationUnits); |
| 59 | + boolean result = task.call(); |
| 60 | + if (!result) |
| 61 | + throw new RuntimeException("Unknown error during compilation."); |
| 62 | + Map<String, Class<?>> classes = new HashMap<String, Class<?>>(); |
| 63 | + for (String className : clazzCode.keySet()) { |
| 64 | + classes.put(className, classLoader.loadClass(className)); |
| 65 | + } |
| 66 | + return classes; |
| 67 | + } |
| 68 | + |
| 69 | + public static Class<?> compile(String className, String sourceCodeInText) |
| 70 | + throws Exception { |
| 71 | + InMemoryJavaCompiler comp = new InMemoryJavaCompiler(); |
| 72 | + comp.addSource(className, sourceCodeInText); |
| 73 | + Map<String, Class<?>> clzzes = comp.compileAll(); |
| 74 | + Class<?> result = clzzes.get(className); |
| 75 | + return result; |
| 76 | + } |
| 77 | + |
| 78 | + public DynamicClassLoader getClassLoader() { |
| 79 | + return classLoader; |
| 80 | + } |
24 | 81 | } |
0 commit comments