Skip to content

Commit 9311b56

Browse files
committed
导包处理
1 parent 8961c47 commit 9311b56

8 files changed

Lines changed: 152 additions & 150 deletions

File tree

src/main/java/org/mdkt/compiler/CompilationException.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
package org.mdkt.compiler;
22

3+
/**
4+
* 编译异常类
5+
*/
36
public class CompilationException extends RuntimeException {
47
private static final long serialVersionUID = 5272588827551900536L;
58

src/main/java/org/mdkt/compiler/CompilationResult.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@
66
import javax.tools.Diagnostic;
77
import javax.tools.JavaFileObject;
88

9+
/**
10+
* 编译结果收集类
11+
*/
912
public interface CompilationResult {
1013
/**
1114
* Return the compiled classes

src/main/java/org/mdkt/compiler/CompiledCode.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package org.mdkt.compiler;
22

3+
import javax.tools.JavaFileObject;
34
import javax.tools.SimpleJavaFileObject;
45
import java.io.ByteArrayOutputStream;
56
import java.io.IOException;
@@ -10,11 +11,11 @@
1011
* Created by trung on 5/3/15.
1112
*/
1213
public class CompiledCode extends SimpleJavaFileObject {
13-
private ByteArrayOutputStream baos = new ByteArrayOutputStream();
14-
private String className;
14+
private final ByteArrayOutputStream baos = new ByteArrayOutputStream();
15+
private final String className;
1516

1617
public CompiledCode(String className) throws Exception {
17-
super(new URI(className), Kind.CLASS);
18+
super(new URI(className), JavaFileObject.Kind.CLASS);
1819
this.className = className;
1920
}
2021

src/main/java/org/mdkt/compiler/DynamicClassLoader.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@ public DynamicClassLoader(ClassLoader parent) {
1111
super(parent);
1212
}
1313

14+
public Map<String, CompiledCode> getCustomCompiledCode(){
15+
return this.customCompiledCode;
16+
}
17+
1418
public void addCode(CompiledCode cc) {
1519
customCompiledCode.put(cc.getName(), cc);
1620
}

src/main/java/org/mdkt/compiler/ExtendedStandardJavaFileManager.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@
1717
public class ExtendedStandardJavaFileManager extends
1818
ForwardingJavaFileManager<JavaFileManager> {
1919

20-
private Map<String, CompiledCode> compiledCode;
21-
private DynamicClassLoader cl;
20+
private final Map<String, CompiledCode> compiledCode;
21+
private final DynamicClassLoader cl;
2222

2323
/**
2424
* Creates a new instance of ForwardingJavaFileManager.
Lines changed: 123 additions & 135 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
package org.mdkt.compiler;
22

3+
4+
import javax.tools.Diagnostic;
5+
import javax.tools.DiagnosticCollector;
6+
import javax.tools.JavaCompiler;
7+
import javax.tools.JavaFileObject;
8+
import javax.tools.ToolProvider;
39
import java.util.Arrays;
410
import java.util.Collection;
511
import java.util.HashMap;
@@ -8,17 +14,11 @@
814
import java.util.Locale;
915
import java.util.Map;
1016

11-
import javax.tools.Diagnostic;
12-
import javax.tools.DiagnosticCollector;
13-
import javax.tools.JavaCompiler;
14-
import javax.tools.JavaFileObject;
15-
import javax.tools.ToolProvider;
16-
1717
/**
1818
* Compile Java sources in-memory
1919
*/
2020
public class InMemoryJavaCompiler {
21-
private JavaCompiler javac;
21+
private final JavaCompiler javac;
2222
private DynamicClassLoader classLoader;
2323
private Iterable<String> options;
2424
boolean ignoreWarnings = false;
@@ -68,135 +68,112 @@ public InMemoryJavaCompiler ignoreWarnings() {
6868
return this;
6969
}
7070

71-
/**
72-
* Compile all sources
73-
*
74-
* @return Map containing instances of all compiled classes
75-
* @throws Exception
76-
*/
77-
public Map<String, Class<?>> compileAll() throws Exception {
78-
return compile().checkNoErrors().classMap();
79-
}
80-
81-
public Class<?> loadCompiledBytes(String className, byte[] compiledClasses) throws ClassNotFoundException {
82-
Map<String, byte[]> map = new HashMap<>();
83-
map.put(className, compiledClasses);
84-
return loadCompiledBytes(map).get(className);
85-
}
86-
87-
public Map<String, Class<?>> loadCompiledBytes(Map<String, byte[]> compiledClasses) throws ClassNotFoundException {
88-
ClassLoader classLoader = new ClassLoader() {
89-
@Override
90-
protected Class<?> findClass(String name) {
91-
byte[] b = compiledClasses.get(name);
92-
return defineClass(name, b, 0, b.length);
93-
}
94-
};
95-
Map<String, Class<?>> classes = new HashMap<>();
96-
for (String className : compiledClasses.keySet()) {
97-
classes.put(className, classLoader.loadClass(className));
98-
}
99-
return classes;
100-
}
101-
102-
/**
103-
* Compile all sources added until now and return {@link CompilationResult},
104-
* providing access to the compiled classes and/or errors and warnings
105-
*/
106-
public CompilationResult compile() throws Exception {
107-
if (sourceCodes.size() == 0) {
108-
throw new CompilationException("No source code to compile");
109-
}
110-
Collection<SourceCode> compilationUnits = sourceCodes.values();
111-
CompiledCode[] code = new CompiledCode[compilationUnits.size()];
112-
Iterator<SourceCode> iter = compilationUnits.iterator();
113-
for (int i = 0; i < code.length; i++) {
114-
code[i] = new CompiledCode(iter.next().getClassName());
115-
}
116-
DiagnosticCollector<JavaFileObject> collector = new DiagnosticCollector<>();
117-
// ExtendedStandardJavaFileManager fileManager = new ExtendedStandardJavaFileManager(javac.getStandardFileManager(null, null, null), classLoader);
118-
ExtendedStandardJavaFileManager fileManager = new ExtendedStandardJavaFileManager(javac.getStandardFileManager(null, null, null), classLoader, code);
119-
JavaCompiler.CompilationTask task = javac.getTask(null, fileManager, collector, options, null,
120-
compilationUnits);
121-
task.call();
122-
boolean hasWarnings;
123-
boolean hasErrors;
124-
125-
{
126-
boolean hasWarningsTmp = false;
127-
boolean hasErrorsTmp = false;
128-
for (Diagnostic<? extends JavaFileObject> d : collector.getDiagnostics()) {
129-
switch (d.getKind()) {
130-
case NOTE:
131-
case MANDATORY_WARNING:
132-
case WARNING:
133-
hasWarningsTmp = true;
134-
break;
135-
case OTHER:
136-
case ERROR:
137-
default:
138-
hasErrorsTmp = true;
139-
break;
140-
}
141-
}
142-
hasWarnings = hasWarningsTmp;
143-
hasErrors = hasErrorsTmp;
144-
}
145-
146-
return new CompilationResult() {
147-
148-
@Override
149-
public Map<String, Class<?>> classMap() throws ClassNotFoundException {
150-
Map<String, Class<?>> classes = new HashMap<String, Class<?>>();
151-
for (String className : sourceCodes.keySet()) {
152-
// 由loadClass变更为findClass,优先获取新编译的同名类(如果使用loadClass则获取不到新编译的同名class)
153-
// 虽然支持多次加载同名类(指不同的ClassLoader,实际上同一个ClassLoader中Java仍然不允许重复会报错)
154-
// 但是还是不推荐这样做,因为这样违反了Java的基本原则,且容易出现混淆影响自己问题的处理
71+
/**
72+
* Compile all sources
73+
*
74+
* @return Map containing instances of all compiled classes
75+
* @throws Exception
76+
*/
77+
public Map<String, Class<?>> compileAll() throws Exception {
78+
return compile().checkNoErrors().classMap();
79+
}
80+
81+
/**
82+
* Compile all sources added until now and return {@link CompilationResult},
83+
* providing access to the compiled classes and/or errors and warnings
84+
*/
85+
public CompilationResult compile() throws Exception {
86+
if (sourceCodes.size() == 0) {
87+
throw new CompilationException("No source code to compile");
88+
}
89+
Collection<SourceCode> compilationUnits = sourceCodes.values();
90+
CompiledCode[] code = new CompiledCode[compilationUnits.size()];
91+
Iterator<SourceCode> iter = compilationUnits.iterator();
92+
for (int i = 0; i < code.length; i++) {
93+
code[i] = new CompiledCode(iter.next().getClassName());
94+
}
95+
DiagnosticCollector<JavaFileObject> collector = new DiagnosticCollector<>();
96+
ExtendedStandardJavaFileManager fileManager = new ExtendedStandardJavaFileManager(javac.getStandardFileManager(null, null, null), classLoader, code);
97+
JavaCompiler.CompilationTask task = javac.getTask(null, fileManager, collector, options, null, compilationUnits);
98+
task.call();
99+
boolean hasWarnings;
100+
boolean hasErrors;
101+
102+
{
103+
boolean hasWarningsTmp = false;
104+
boolean hasErrorsTmp = false;
105+
for (Diagnostic<? extends JavaFileObject> d : collector.getDiagnostics()) {
106+
switch (d.getKind()) {
107+
case NOTE:
108+
case MANDATORY_WARNING:
109+
case WARNING:
110+
hasWarningsTmp = true;
111+
break;
112+
case OTHER:
113+
case ERROR:
114+
default:
115+
hasErrorsTmp = true;
116+
break;
117+
}
118+
}
119+
hasWarnings = hasWarningsTmp;
120+
hasErrors = hasErrorsTmp;
121+
}
122+
123+
return new CompilationResult() {
124+
125+
@Override
126+
public Map<String, Class<?>> classMap() throws ClassNotFoundException {
127+
Map<String, Class<?>> classes = new HashMap<>();
128+
for (String className : sourceCodes.keySet()) {
129+
// 由loadClass变更为findClass,优先获取新编译的同名类(如果使用loadClass则获取不到新编译的同名class)
130+
// 虽然支持多次加载同名类(指不同的ClassLoader,实际上同一个ClassLoader中Java仍然不允许重复会报错)
131+
// 但是还是不推荐这样做,因为这样违反了Java的基本原则,且容易出现混淆影响自己问题的处理
155132
// classes.put(className, classLoader.loadClass(className));
156-
classes.put(className, classLoader.findClass(className));
157-
}
158-
return classes;
159-
}
160-
161-
@Override
162-
public boolean compilationSucceeded() {
163-
if (hasWarnings && !ignoreWarnings)
164-
return false;
165-
return !hasErrors;
166-
}
167-
168-
@Override
169-
public boolean hasWarnings() {
170-
return hasWarnings;
171-
}
172-
173-
@Override
174-
public boolean hasErrors() {
175-
return hasErrors;
176-
}
177-
178-
@Override
179-
public List<Diagnostic<? extends JavaFileObject>> getDiagnostics() {
180-
return collector.getDiagnostics();
181-
}
182-
183-
@Override
184-
public CompilationResult checkNoErrors() {
185-
if (!compilationSucceeded()) {
186-
StringBuffer exceptionMsg = new StringBuffer();
187-
exceptionMsg.append("Unable to compile the source");
188-
for (Diagnostic<? extends JavaFileObject> d : getDiagnostics()) {
189-
exceptionMsg.append("\n").append("[kind=").append(d.getKind());
190-
exceptionMsg.append(", ").append("line=").append(d.getLineNumber());
191-
exceptionMsg.append(", ").append("message=").append(d.getMessage(Locale.US)).append("]");
192-
}
193-
throw new CompilationException(exceptionMsg.toString());
194-
}
195-
return this;
196-
}
197-
198-
};
199-
}
133+
classes.put(className, classLoader.findClass(className));
134+
}
135+
return classes;
136+
}
137+
138+
@Override
139+
public boolean compilationSucceeded() {
140+
if (hasWarnings && !ignoreWarnings) return false;
141+
return !hasErrors;
142+
}
143+
144+
@Override
145+
public boolean hasWarnings() {
146+
return hasWarnings;
147+
}
148+
149+
@Override
150+
public boolean hasErrors() {
151+
return hasErrors;
152+
}
153+
154+
@Override
155+
public List<Diagnostic<? extends JavaFileObject>> getDiagnostics() {
156+
return collector.getDiagnostics();
157+
}
158+
159+
@Override
160+
public CompilationResult checkNoErrors() {
161+
if (!compilationSucceeded()) {
162+
StringBuilder exceptionMsg = new StringBuilder();
163+
exceptionMsg.append("Unable to compile the source");
164+
for (Diagnostic<? extends JavaFileObject> d : getDiagnostics()) {
165+
exceptionMsg.append("\n").append("[kind=").append(d.getKind());
166+
exceptionMsg.append(", ").append("line=").append(d.getLineNumber());
167+
exceptionMsg.append(", ").append("message=").append(d.getMessage(Locale.US)).append("]");
168+
}
169+
throw new CompilationException(exceptionMsg.toString());
170+
}
171+
return this;
172+
}
173+
174+
};
175+
}
176+
200177

201178
/**
202179
* Compile single source
@@ -224,4 +201,15 @@ public InMemoryJavaCompiler addSource(String className, String sourceCode) throw
224201
return this;
225202
}
226203

204+
/**
205+
* Add source code map to the compiler
206+
*
207+
* @param sourceCodeMap
208+
* @return
209+
* @throws Exception
210+
*/
211+
public InMemoryJavaCompiler addSources(Map<String, SourceCode> sourceCodeMap) throws Exception {
212+
sourceCodes.putAll(sourceCodeMap);
213+
return this;
214+
}
227215
}

src/main/java/org/mdkt/compiler/SourceCode.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package org.mdkt.compiler;
22

3+
import javax.tools.JavaFileObject;
34
import javax.tools.SimpleJavaFileObject;
45
import java.io.IOException;
56
import java.net.URI;
@@ -9,11 +10,11 @@
910
*/
1011
public class SourceCode extends SimpleJavaFileObject {
1112
private String contents = null;
12-
private String className;
13+
private final String className;
1314

1415
public SourceCode(String className, String contents) throws Exception {
1516
super(URI.create("string:///" + className.replace('.', '/')
16-
+ Kind.SOURCE.extension), Kind.SOURCE);
17+
+ JavaFileObject.Kind.SOURCE.extension), JavaFileObject.Kind.SOURCE);
1718
this.contents = contents;
1819
this.className = className;
1920
}
@@ -22,6 +23,7 @@ public String getClassName() {
2223
return className;
2324
}
2425

26+
@Override
2527
public CharSequence getCharContent(boolean ignoreEncodingErrors)
2628
throws IOException {
2729
return contents;

0 commit comments

Comments
 (0)