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;
|
package org.springframework.cloud.function.compiler.java;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.net.URLClassLoader;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -32,15 +35,16 @@ import org.slf4j.Logger;
|
|||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A file manager that serves source code from in memory and ensures output results are kept in memory
|
* A file manager that serves source code from in memory and ensures output results are
|
||||||
* rather than being flushed out to disk. The JavaFileManager is also used as a lookup mechanism
|
* kept in memory rather than being flushed out to disk. The JavaFileManager is also used
|
||||||
* for resolving types.
|
* as a lookup mechanism for resolving types.
|
||||||
*
|
*
|
||||||
* @author Andy Clement
|
* @author Andy Clement
|
||||||
*/
|
*/
|
||||||
public class MemoryBasedJavaFileManager implements JavaFileManager {
|
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 CompilationOutputCollector outputCollector;
|
||||||
|
|
||||||
@@ -65,36 +69,64 @@ public class MemoryBasedJavaFileManager implements JavaFileManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Iterable<JavaFileObject> list(Location location, String packageName, Set<Kind> kinds, boolean recurse)
|
public Iterable<JavaFileObject> list(Location location, String packageName,
|
||||||
throws IOException {
|
Set<Kind> kinds, boolean recurse) throws IOException {
|
||||||
logger.debug("list({},{},{},{})", location, packageName, kinds, recurse);
|
logger.debug("list({},{},{},{})", location, packageName, kinds, recurse);
|
||||||
CloseableFilterableJavaFileObjectIterable resultIterable = null;
|
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");
|
String sunBootClassPath = System.getProperty("sun.boot.class.path");
|
||||||
logger.debug("Creating iterable for boot class path: {}", sunBootClassPath);
|
logger.debug("Creating iterable for boot class path: {}", sunBootClassPath);
|
||||||
resultIterable = new IterableClasspath(sunBootClassPath, packageName, recurse);
|
resultIterable = new IterableClasspath(sunBootClassPath, packageName,
|
||||||
|
recurse);
|
||||||
toClose.add(resultIterable);
|
toClose.add(resultIterable);
|
||||||
} else if (location == StandardLocation.CLASS_PATH && (kinds==null || kinds.contains(Kind.CLASS))) {
|
}
|
||||||
String javaClassPath = System.getProperty("java.class.path");
|
else if (location == StandardLocation.CLASS_PATH
|
||||||
|
&& (kinds == null || kinds.contains(Kind.CLASS))) {
|
||||||
|
String javaClassPath = getClassPath();
|
||||||
logger.debug("Creating iterable for class path: {}", javaClassPath);
|
logger.debug("Creating iterable for class path: {}", javaClassPath);
|
||||||
resultIterable = new IterableClasspath(javaClassPath, packageName, recurse);
|
resultIterable = new IterableClasspath(javaClassPath, packageName, recurse);
|
||||||
toClose.add(resultIterable);
|
toClose.add(resultIterable);
|
||||||
} else if (location == StandardLocation.SOURCE_PATH) {
|
}
|
||||||
|
else if (location == StandardLocation.SOURCE_PATH) {
|
||||||
// There are no 'extra sources'
|
// There are no 'extra sources'
|
||||||
resultIterable = EmptyIterable.instance;
|
resultIterable = EmptyIterable.instance;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
// Nothing to list
|
// Nothing to list
|
||||||
resultIterable = EmptyIterable.instance;
|
resultIterable = EmptyIterable.instance;
|
||||||
}
|
}
|
||||||
return resultIterable;
|
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
|
@Override
|
||||||
public boolean hasLocation(Location location) {
|
public boolean hasLocation(Location location) {
|
||||||
logger.debug("hasLocation({})", location);
|
logger.debug("hasLocation({})", location);
|
||||||
return (location == StandardLocation.SOURCE_PATH ||
|
return (location == StandardLocation.SOURCE_PATH
|
||||||
location == StandardLocation.CLASS_PATH ||
|
|| location == StandardLocation.CLASS_PATH
|
||||||
location == StandardLocation.PLATFORM_CLASS_PATH);
|
|| location == StandardLocation.PLATFORM_CLASS_PATH);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -120,34 +152,40 @@ public class MemoryBasedJavaFileManager implements JavaFileManager {
|
|||||||
return false; // This file manager does not manage any options
|
return false; // This file manager does not manage any options
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public JavaFileObject getJavaFileForInput(Location location, String className, Kind kind) throws IOException {
|
public JavaFileObject getJavaFileForInput(Location location, String className,
|
||||||
|
Kind kind) throws IOException {
|
||||||
logger.debug("getJavaFileForInput({},{},{})", location, className, kind);
|
logger.debug("getJavaFileForInput({},{},{})", location, className, kind);
|
||||||
throw new IllegalStateException("Not expected to be used in this context");
|
throw new IllegalStateException("Not expected to be used in this context");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public JavaFileObject getJavaFileForOutput(Location location, String className, Kind kind, FileObject sibling)
|
public JavaFileObject getJavaFileForOutput(Location location, String className,
|
||||||
throws IOException {
|
Kind kind, FileObject sibling) throws IOException {
|
||||||
logger.debug("getJavaFileForOutput({},{},{},{})",location,className,kind,sibling);
|
logger.debug("getJavaFileForOutput({},{},{},{})", location, className, kind,
|
||||||
// Example parameters: CLASS_OUTPUT, Foo, CLASS, StringBasedJavaSourceFileObject[string:///a/b/c/Foo.java]
|
sibling);
|
||||||
|
// Example parameters: CLASS_OUTPUT, Foo, CLASS,
|
||||||
|
// StringBasedJavaSourceFileObject[string:///a/b/c/Foo.java]
|
||||||
return outputCollector.getJavaFileForOutput(location, className, kind, sibling);
|
return outputCollector.getJavaFileForOutput(location, className, kind, sibling);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FileObject getFileForInput(Location location, String packageName, String relativeName) throws IOException {
|
public FileObject getFileForInput(Location location, String packageName,
|
||||||
|
String relativeName) throws IOException {
|
||||||
logger.debug("getFileForInput({},{},{})", location, packageName, relativeName);
|
logger.debug("getFileForInput({},{},{})", location, packageName, relativeName);
|
||||||
throw new IllegalStateException("Not expected to be used in this context");
|
throw new IllegalStateException("Not expected to be used in this context");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FileObject getFileForOutput(Location location, String packageName, String relativeName, FileObject sibling)
|
public FileObject getFileForOutput(Location location, String packageName,
|
||||||
throws IOException {
|
String relativeName, FileObject sibling) throws IOException {
|
||||||
logger.debug("getFileForOutput({},{},{},{})",location,packageName,relativeName,sibling);
|
logger.debug("getFileForOutput({},{},{},{})", location, packageName, relativeName,
|
||||||
|
sibling);
|
||||||
// This can be called when the annotation config processor runs
|
// This can be called when the annotation config processor runs
|
||||||
// Example parameters: CLASS_OUTPUT, , META-INF/spring-configuration-metadata.json, null
|
// Example parameters: CLASS_OUTPUT, ,
|
||||||
return outputCollector.getFileForOutput(location, packageName, relativeName, sibling);
|
// META-INF/spring-configuration-metadata.json, null
|
||||||
|
return outputCollector.getFileForOutput(location, packageName, relativeName,
|
||||||
|
sibling);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
Reference in New Issue
Block a user