Skip to content

Commit 65ce5d2

Browse files
committed
Merge branch 'transparent' into 0.2.x
windows classpath with whitespaces bug fix, see issue: #28
2 parents dfbafc1 + be15d42 commit 65ce5d2

5 files changed

Lines changed: 108 additions & 11 deletions

File tree

src/main/java/com/github/pfmiles/dropincc/impl/hotcompile/HotCompileUtil.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,10 @@ public static CompilationResult compile(String qualifiedName, String sourceCode)
5151

5252
JavaFileManager fileManager = null;
5353
Map<String, JavaMemCls> clses = new HashMap<String, JavaMemCls>();
54+
Map<String, JavaStringSource> srcs = new HashMap<String, JavaStringSource>();
55+
srcs.put(source.getClsName(), source);
5456
try {
55-
fileManager = new MemClsFileManager(compiler.getStandardFileManager(null, null, null), clses);
57+
fileManager = new MemClsFileManager(compiler.getStandardFileManager(null, null, null), clses, srcs);
5658
DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<JavaFileObject>();
5759
StringWriter out = new StringWriter();
5860
CompilationTask task = compiler.getTask(out, fileManager, diagnostics, options, null, ss);

src/main/java/com/github/pfmiles/dropincc/impl/hotcompile/JavaMemCls.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
*/
1616
public class JavaMemCls extends SimpleJavaFileObject {
1717

18+
private String clsName;
1819
private ByteArrayOutputStream bos;
1920

2021
protected JavaMemCls(String name) {
@@ -29,4 +30,8 @@ public byte[] getClsBytes() {
2930
public OutputStream openOutputStream() throws IOException {
3031
return bos;
3132
}
33+
34+
public String getClsName() {
35+
return clsName;
36+
}
3237
}

src/main/java/com/github/pfmiles/dropincc/impl/hotcompile/JavaStringSource.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,22 +21,22 @@
2121
*/
2222
public class JavaStringSource extends SimpleJavaFileObject {
2323

24-
private String name;
24+
private String clsName;
2525
// source code
2626
private String source;
2727

2828
protected JavaStringSource(String name, String source) {
2929
super(URI.create("string:///" + name.replaceAll("\\.", "/") + Kind.SOURCE.extension), Kind.SOURCE);
30-
this.name = name;
30+
this.clsName = name;
3131
this.source = source;
3232
}
3333

3434
public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException {
3535
return this.source;
3636
}
3737

38-
public String getName() {
39-
return name;
38+
public String getClsName() {
39+
return clsName;
4040
}
4141

4242
public String getSource() {

src/main/java/com/github/pfmiles/dropincc/impl/hotcompile/MemClsFileManager.java

Lines changed: 73 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,57 @@
11
package com.github.pfmiles.dropincc.impl.hotcompile;
22

33
import java.io.IOException;
4+
import java.util.ArrayList;
5+
import java.util.List;
46
import java.util.Map;
7+
import java.util.Set;
58

69
import javax.tools.FileObject;
710
import javax.tools.ForwardingJavaFileManager;
811
import javax.tools.JavaFileObject;
912
import javax.tools.JavaFileObject.Kind;
1013
import javax.tools.StandardJavaFileManager;
14+
import javax.tools.StandardLocation;
1115

1216
/**
1317
* A forwarding file manager which is used to decouple the file system
1418
* dependency. That is, the compilation process write compiled class files into
1519
* memory instead of file system.
1620
*
21+
* <p>
22+
* These following methods would be invoked during the compilation progress, so
23+
* they should behave well for sure:
24+
* </p>
25+
*
26+
* <pre>
27+
* close
28+
* flush
29+
* getClassLoader
30+
* getJavaFileForOutput
31+
* handleOption
32+
* hasLocation
33+
* inferBinaryName
34+
* list
35+
* </pre>
36+
*
1737
* @author pf-miles
1838
*
1939
*/
2040
public class MemClsFileManager extends ForwardingJavaFileManager<StandardJavaFileManager> {
2141

2242
private Map<String, JavaMemCls> destFiles;
43+
private Map<String, JavaStringSource> srcFiles;
2344

24-
protected MemClsFileManager(StandardJavaFileManager fileManager, Map<String, JavaMemCls> destFiles) {
45+
protected MemClsFileManager(StandardJavaFileManager fileManager, Map<String, JavaMemCls> destFiles, Map<String, JavaStringSource> srcFiles) {
2546
super(fileManager);
2647
this.destFiles = destFiles;
48+
this.srcFiles = srcFiles;
2749
}
2850

51+
// redirects class file output to memory
2952
public JavaFileObject getJavaFileForOutput(Location location, String className, Kind kind, FileObject sibling) throws IOException {
53+
if (!(Kind.CLASS.equals(kind) && StandardLocation.CLASS_OUTPUT.equals(location)))
54+
return super.getJavaFileForOutput(location, className, kind, sibling);
3055
if (destFiles.containsKey(className)) {
3156
return destFiles.get(className);
3257
} else {
@@ -41,4 +66,51 @@ public void close() throws IOException {
4166
this.destFiles = null;
4267
}
4368

69+
public Iterable<JavaFileObject> list(Location location, String packageName, Set<Kind> kinds, boolean recurse) throws IOException {
70+
List<JavaFileObject> ret = new ArrayList<JavaFileObject>();
71+
if ((StandardLocation.CLASS_OUTPUT.equals(location) || StandardLocation.CLASS_PATH.equals(location)) && kinds.contains(Kind.CLASS)) {
72+
for (Map.Entry<String, JavaMemCls> e : destFiles.entrySet()) {
73+
String pkgName = resolvePkgName(e.getKey());
74+
if (recurse) {
75+
if (pkgName.contains(packageName))
76+
ret.add(e.getValue());
77+
} else {
78+
if (pkgName.equals(packageName))
79+
ret.add(e.getValue());
80+
}
81+
}
82+
} else if (StandardLocation.SOURCE_PATH.equals(location) && kinds.contains(Kind.SOURCE)) {
83+
for (Map.Entry<String, JavaStringSource> e : srcFiles.entrySet()) {
84+
String pkgName = resolvePkgName(e.getKey());
85+
if (recurse) {
86+
if (pkgName.contains(packageName))
87+
ret.add(e.getValue());
88+
} else {
89+
if (pkgName.equals(packageName))
90+
ret.add(e.getValue());
91+
}
92+
}
93+
}
94+
// 也包含super.list
95+
Iterable<JavaFileObject> superList = super.list(location, packageName, kinds, recurse);
96+
if (superList != null)
97+
for (JavaFileObject f : superList)
98+
ret.add(f);
99+
return ret;
100+
}
101+
102+
private String resolvePkgName(String fullQualifiedClsName) {
103+
return fullQualifiedClsName.substring(0, fullQualifiedClsName.lastIndexOf('.'));
104+
}
105+
106+
public String inferBinaryName(Location location, JavaFileObject file) {
107+
if (file instanceof JavaMemCls) {
108+
return ((JavaMemCls) file).getClsName();
109+
} else if (file instanceof JavaStringSource) {
110+
return ((JavaStringSource) file).getClsName();
111+
} else {
112+
return super.inferBinaryName(location, file);
113+
}
114+
}
115+
44116
}

src/main/java/com/github/pfmiles/dropincc/impl/util/Util.java

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
package com.github.pfmiles.dropincc.impl.util;
1212

1313
import java.io.File;
14+
import java.net.URISyntaxException;
1415
import java.net.URL;
1516
import java.net.URLClassLoader;
1617
import java.util.Collection;
@@ -244,7 +245,7 @@ public static String getClassPath() {
244245
ClassLoader loader = getParentClsLoader();
245246
if (loader instanceof URLClassLoader) {
246247
for (URL url : ((URLClassLoader) loader).getURLs()) {
247-
String dropinccPath = url.getPath();
248+
String dropinccPath = toFilePath(url);
248249
if (dropinccPath != null && !"".equals(dropinccPath) && sb.indexOf(dropinccPath) == -1) {
249250
if (sb.length() != 0)
250251
sb.append(File.pathSeparator);
@@ -258,12 +259,13 @@ public static String getClassPath() {
258259
if (url != null) {
259260
String dropinccPath = null;
260261
if ("jar".equalsIgnoreCase(url.getProtocol())) {
261-
String path = url.getPath();
262+
String path = toFilePath(url);
262263
// could not handle nested jars
263-
dropinccPath = path.substring(path.indexOf(":") + 1, path.indexOf("!"));
264+
dropinccPath = path != null ? path.substring(path.indexOf(":") + 1, path.indexOf("!")) : null;
264265
} else if ("file".equalsIgnoreCase(url.getProtocol())) {
265-
String path = url.getPath();
266-
dropinccPath = path.substring(0, path.lastIndexOf(PATH_SEP + Util.class.getName().replace(".", PATH_SEP) + ".class"));
266+
String path = toFilePath(url);
267+
dropinccPath = path != null ? path.substring(0, path.lastIndexOf(PATH_SEP + Util.class.getName().replace(".", PATH_SEP) + ".class"))
268+
: null;
267269
}
268270
if (dropinccPath != null && !"".equals(dropinccPath) && sb.indexOf(dropinccPath) == -1) {
269271
if (sb.length() != 0)
@@ -274,6 +276,22 @@ public static String getClassPath() {
274276
return sb.toString();
275277
}
276278

279+
private static String toFilePath(URL url) {
280+
String protocal = url.getProtocol();
281+
if (!("jar".equalsIgnoreCase(protocal) || "file".equalsIgnoreCase(protocal)))
282+
return null;
283+
try {
284+
File f = new File(url.toURI().getSchemeSpecificPart());
285+
if (f.exists()) {
286+
return f.getAbsolutePath();
287+
} else {
288+
return null;
289+
}
290+
} catch (URISyntaxException e) {
291+
throw new DropinccException(e);
292+
}
293+
}
294+
277295
/**
278296
* Get the proper parent class loader for hot compilation class loaders.
279297
*

0 commit comments

Comments
 (0)