11package org .mdkt .compiler ;
22
3- import java .util .Collection ;
4- import java .util .HashMap ;
5- import java .util .Iterator ;
6- import java .util .Map ;
3+ import java .util .*;
74
8- import javax .tools .DiagnosticCollector ;
9- import javax .tools .JavaCompiler ;
10- import javax .tools .JavaFileObject ;
11- import javax .tools .ToolProvider ;
5+ import javax .tools .*;
126
137/**
14- * Complile Java sources in-memory
8+ * Compile Java sources in-memory
159 */
1610public class InMemoryJavaCompiler {
1711 private JavaCompiler javac ;
1812 private DynamicClassLoader classLoader ;
13+ private Iterable <String > options ;
14+ boolean ignoreWarnings = false ;
1915
2016 private Map <String , SourceCode > sourceCodes = new HashMap <String , SourceCode >();
2117
@@ -34,14 +30,43 @@ public InMemoryJavaCompiler useParentClassLoader(ClassLoader parent) {
3430 }
3531
3632 /**
37- * Compile all sources
33+ * @return the class loader used internally by the compiler
34+ */
35+ public ClassLoader getClassloader () {
36+ return classLoader ;
37+ }
38+
39+ /**
40+ * Options used by the compiler, e.g. '-Xlint:unchecked'.
3841 *
42+ * @param options
3943 * @return
44+ */
45+ public InMemoryJavaCompiler useOptions (String ... options ) {
46+ this .options = Arrays .asList (options );
47+ return this ;
48+ }
49+
50+ /**
51+ * Ignore non-critical compiler output, like unchecked/unsafe operation
52+ * warnings.
53+ *
54+ * @return
55+ */
56+ public InMemoryJavaCompiler ignoreWarnings () {
57+ ignoreWarnings = true ;
58+ return this ;
59+ }
60+
61+ /**
62+ * Compile all sources
63+ *
64+ * @return Map containing instances of all compiled classes
4065 * @throws Exception
4166 */
4267 public Map <String , Class <?>> compileAll () throws Exception {
4368 if (sourceCodes .size () == 0 ) {
44- throw new Exception ("No source code to compile" );
69+ throw new CompilationException ("No source code to compile" );
4570 }
4671 Collection <SourceCode > compilationUnits = sourceCodes .values ();
4772 CompiledCode [] code ;
@@ -53,10 +78,33 @@ public Map<String, Class<?>> compileAll() throws Exception {
5378 }
5479 DiagnosticCollector <JavaFileObject > collector = new DiagnosticCollector <>();
5580 ExtendedStandardJavaFileManager fileManager = new ExtendedStandardJavaFileManager (javac .getStandardFileManager (null , null , null ), classLoader );
56- JavaCompiler .CompilationTask task = javac .getTask (null , fileManager , collector , null , null , compilationUnits );
81+ JavaCompiler .CompilationTask task = javac .getTask (null , fileManager , collector , options , null , compilationUnits );
5782 boolean result = task .call ();
5883 if (!result || collector .getDiagnostics ().size () > 0 ) {
59- throw new CompilationException (collector .getDiagnostics ());
84+ StringBuffer exceptionMsg = new StringBuffer ();
85+ exceptionMsg .append ("Unable to compile the source" );
86+ boolean hasWarnings = false ;
87+ boolean hasErrors = false ;
88+ for (Diagnostic <? extends JavaFileObject > d : collector .getDiagnostics ()) {
89+ switch (d .getKind ()) {
90+ case NOTE :
91+ case MANDATORY_WARNING :
92+ case WARNING :
93+ hasWarnings = true ;
94+ break ;
95+ case OTHER :
96+ case ERROR :
97+ default :
98+ hasErrors = true ;
99+ break ;
100+ }
101+ exceptionMsg .append ("\n " ).append ("[kind=" ).append (d .getKind ());
102+ exceptionMsg .append (", " ).append ("line=" ).append (d .getLineNumber ());
103+ exceptionMsg .append (", " ).append ("message=" ).append (d .getMessage (Locale .US )).append ("]" );
104+ }
105+ if (hasWarnings && !ignoreWarnings || hasErrors ) {
106+ throw new CompilationException (exceptionMsg .toString ());
107+ }
60108 }
61109
62110 Map <String , Class <?>> classes = new HashMap <String , Class <?>>();
0 commit comments