Use classpath URLs from class loader instead of system property
The system property doesn't work for a bootiful jar. With this change there is no need to scan the jar for nested jars either.
This commit is contained in:
@@ -16,7 +16,10 @@
|
||||
|
||||
package org.springframework.cloud.function.compiler.java;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
@@ -32,16 +35,17 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* A file manager that serves source code from in memory and ensures output results are kept in memory
|
||||
* rather than being flushed out to disk. The JavaFileManager is also used as a lookup mechanism
|
||||
* for resolving types.
|
||||
* A file manager that serves source code from in memory and ensures output results are
|
||||
* kept in memory rather than being flushed out to disk. The JavaFileManager is also used
|
||||
* as a lookup mechanism for resolving types.
|
||||
*
|
||||
* @author Andy Clement
|
||||
*/
|
||||
public class MemoryBasedJavaFileManager implements JavaFileManager {
|
||||
|
||||
private static Logger logger = LoggerFactory.getLogger(MemoryBasedJavaFileManager.class);
|
||||
|
||||
private static Logger logger = LoggerFactory
|
||||
.getLogger(MemoryBasedJavaFileManager.class);
|
||||
|
||||
private CompilationOutputCollector outputCollector;
|
||||
|
||||
private List<CloseableFilterableJavaFileObjectIterable> toClose = new ArrayList<>();
|
||||
@@ -52,7 +56,7 @@ public class MemoryBasedJavaFileManager implements JavaFileManager {
|
||||
|
||||
@Override
|
||||
public int isSupportedOption(String option) {
|
||||
logger.debug("isSupportedOption({})",option);
|
||||
logger.debug("isSupportedOption({})", option);
|
||||
return -1; // Not yet supporting options
|
||||
}
|
||||
|
||||
@@ -60,41 +64,69 @@ public class MemoryBasedJavaFileManager implements JavaFileManager {
|
||||
public ClassLoader getClassLoader(Location location) {
|
||||
// Do not simply return the context classloader as it may get closed and then
|
||||
// be unusable for loading any further classes
|
||||
logger.debug("getClassLoader({})",location);
|
||||
logger.debug("getClassLoader({})", location);
|
||||
return null; // Do not currently need to load plugins
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<JavaFileObject> list(Location location, String packageName, Set<Kind> kinds, boolean recurse)
|
||||
throws IOException {
|
||||
logger.debug("list({},{},{},{})",location,packageName,kinds,recurse);
|
||||
public Iterable<JavaFileObject> list(Location location, String packageName,
|
||||
Set<Kind> kinds, boolean recurse) throws IOException {
|
||||
logger.debug("list({},{},{},{})", location, packageName, kinds, recurse);
|
||||
CloseableFilterableJavaFileObjectIterable resultIterable = null;
|
||||
if (location == StandardLocation.PLATFORM_CLASS_PATH && (kinds==null || kinds.contains(Kind.CLASS))) {
|
||||
if (location == StandardLocation.PLATFORM_CLASS_PATH
|
||||
&& (kinds == null || kinds.contains(Kind.CLASS))) {
|
||||
String sunBootClassPath = System.getProperty("sun.boot.class.path");
|
||||
logger.debug("Creating iterable for boot class path: {}",sunBootClassPath);
|
||||
resultIterable = new IterableClasspath(sunBootClassPath, packageName, recurse);
|
||||
logger.debug("Creating iterable for boot class path: {}", sunBootClassPath);
|
||||
resultIterable = new IterableClasspath(sunBootClassPath, packageName,
|
||||
recurse);
|
||||
toClose.add(resultIterable);
|
||||
} else if (location == StandardLocation.CLASS_PATH && (kinds==null || kinds.contains(Kind.CLASS))) {
|
||||
String javaClassPath = System.getProperty("java.class.path");
|
||||
logger.debug("Creating iterable for class path: {}",javaClassPath);
|
||||
}
|
||||
else if (location == StandardLocation.CLASS_PATH
|
||||
&& (kinds == null || kinds.contains(Kind.CLASS))) {
|
||||
String javaClassPath = getClassPath();
|
||||
logger.debug("Creating iterable for class path: {}", javaClassPath);
|
||||
resultIterable = new IterableClasspath(javaClassPath, packageName, recurse);
|
||||
toClose.add(resultIterable);
|
||||
} else if (location == StandardLocation.SOURCE_PATH) {
|
||||
}
|
||||
else if (location == StandardLocation.SOURCE_PATH) {
|
||||
// There are no 'extra sources'
|
||||
resultIterable = EmptyIterable.instance;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
// Nothing to list
|
||||
resultIterable = EmptyIterable.instance;
|
||||
}
|
||||
return resultIterable;
|
||||
}
|
||||
|
||||
private String getClassPath() {
|
||||
ClassLoader loader = InMemoryJavaFileObject.class.getClassLoader();
|
||||
if (loader instanceof URLClassLoader) {
|
||||
URL[] urls = ((URLClassLoader) loader).getURLs();
|
||||
if (urls.length > 1) { // heuristic that catches Maven surefire tests
|
||||
StringBuilder builder = new StringBuilder();
|
||||
for (URL url : urls) {
|
||||
if (builder.length() > 0) {
|
||||
builder.append(File.pathSeparator);
|
||||
}
|
||||
String path = url.toString();
|
||||
if (path.startsWith("file:")) {
|
||||
path = path.substring("file:".length());
|
||||
}
|
||||
builder.append(url);
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
}
|
||||
return System.getProperty("java.class.path");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasLocation(Location location) {
|
||||
logger.debug("hasLocation({})",location);
|
||||
return (location == StandardLocation.SOURCE_PATH ||
|
||||
location == StandardLocation.CLASS_PATH ||
|
||||
location == StandardLocation.PLATFORM_CLASS_PATH);
|
||||
logger.debug("hasLocation({})", location);
|
||||
return (location == StandardLocation.SOURCE_PATH
|
||||
|| location == StandardLocation.CLASS_PATH
|
||||
|| location == StandardLocation.PLATFORM_CLASS_PATH);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -110,44 +142,50 @@ public class MemoryBasedJavaFileManager implements JavaFileManager {
|
||||
|
||||
@Override
|
||||
public boolean isSameFile(FileObject a, FileObject b) {
|
||||
logger.debug("isSameFile({},{})",a,b);
|
||||
logger.debug("isSameFile({},{})", a, b);
|
||||
return a.equals(b);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handleOption(String current, Iterator<String> remaining) {
|
||||
logger.debug("handleOption({},{})",current,remaining);
|
||||
logger.debug("handleOption({},{})", current, remaining);
|
||||
return false; // This file manager does not manage any options
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public JavaFileObject getJavaFileForInput(Location location, String className, Kind kind) throws IOException {
|
||||
logger.debug("getJavaFileForInput({},{},{})",location,className,kind);
|
||||
public JavaFileObject getJavaFileForInput(Location location, String className,
|
||||
Kind kind) throws IOException {
|
||||
logger.debug("getJavaFileForInput({},{},{})", location, className, kind);
|
||||
throw new IllegalStateException("Not expected to be used in this context");
|
||||
}
|
||||
|
||||
@Override
|
||||
public JavaFileObject getJavaFileForOutput(Location location, String className, Kind kind, FileObject sibling)
|
||||
throws IOException {
|
||||
logger.debug("getJavaFileForOutput({},{},{},{})",location,className,kind,sibling);
|
||||
// Example parameters: CLASS_OUTPUT, Foo, CLASS, StringBasedJavaSourceFileObject[string:///a/b/c/Foo.java]
|
||||
public JavaFileObject getJavaFileForOutput(Location location, String className,
|
||||
Kind kind, FileObject sibling) throws IOException {
|
||||
logger.debug("getJavaFileForOutput({},{},{},{})", location, className, kind,
|
||||
sibling);
|
||||
// Example parameters: CLASS_OUTPUT, Foo, CLASS,
|
||||
// StringBasedJavaSourceFileObject[string:///a/b/c/Foo.java]
|
||||
return outputCollector.getJavaFileForOutput(location, className, kind, sibling);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FileObject getFileForInput(Location location, String packageName, String relativeName) throws IOException {
|
||||
logger.debug("getFileForInput({},{},{})",location,packageName,relativeName);
|
||||
public FileObject getFileForInput(Location location, String packageName,
|
||||
String relativeName) throws IOException {
|
||||
logger.debug("getFileForInput({},{},{})", location, packageName, relativeName);
|
||||
throw new IllegalStateException("Not expected to be used in this context");
|
||||
}
|
||||
|
||||
@Override
|
||||
public FileObject getFileForOutput(Location location, String packageName, String relativeName, FileObject sibling)
|
||||
throws IOException {
|
||||
logger.debug("getFileForOutput({},{},{},{})",location,packageName,relativeName,sibling);
|
||||
public FileObject getFileForOutput(Location location, String packageName,
|
||||
String relativeName, FileObject sibling) throws IOException {
|
||||
logger.debug("getFileForOutput({},{},{},{})", location, packageName, relativeName,
|
||||
sibling);
|
||||
// This can be called when the annotation config processor runs
|
||||
// Example parameters: CLASS_OUTPUT, , META-INF/spring-configuration-metadata.json, null
|
||||
return outputCollector.getFileForOutput(location, packageName, relativeName, sibling);
|
||||
// Example parameters: CLASS_OUTPUT, ,
|
||||
// META-INF/spring-configuration-metadata.json, null
|
||||
return outputCollector.getFileForOutput(location, packageName, relativeName,
|
||||
sibling);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -156,7 +194,7 @@ public class MemoryBasedJavaFileManager implements JavaFileManager {
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
for (CloseableFilterableJavaFileObjectIterable closeable: toClose) {
|
||||
for (CloseableFilterableJavaFileObjectIterable closeable : toClose) {
|
||||
closeable.close();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user