Code polishing and general cleanup
This commit is contained in:
@@ -1,12 +1,12 @@
|
||||
/*
|
||||
* Copyright 2016 the original author or authors.
|
||||
*
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@@ -18,7 +18,7 @@ package org.springframework.cloud.function.compiler.java;
|
||||
|
||||
/**
|
||||
* Encapsulates a name with the bytes for its class definition.
|
||||
*
|
||||
*
|
||||
* @author Andy Clement
|
||||
*/
|
||||
public class CompiledClassDefinition {
|
||||
@@ -34,9 +34,7 @@ public class CompiledClassDefinition {
|
||||
if (classname.startsWith("/")) {
|
||||
classname = classname.substring(1);
|
||||
}
|
||||
classname = classname.replace('/', '.').substring(0, classname.length() - 6); // strip
|
||||
// off
|
||||
// .class
|
||||
classname = classname.replace('/', '.').substring(0, classname.length() - 6); // strip off .class
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
@@ -57,4 +55,4 @@ public class CompiledClassDefinition {
|
||||
return this.classname;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
/*
|
||||
* Copyright 2016 the original author or authors.
|
||||
*
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@@ -24,21 +24,19 @@ import java.util.NoSuchElementException;
|
||||
|
||||
/**
|
||||
* Walks a directory hierarchy from some base directory discovering files.
|
||||
*
|
||||
*
|
||||
* @author Andy Clement
|
||||
*/
|
||||
public class DirEnumeration implements Enumeration<File> {
|
||||
|
||||
// private final static Logger logger = LoggerFactory.getLogger(DirEnumeration.class);
|
||||
|
||||
|
||||
// The starting point
|
||||
private File basedir;
|
||||
|
||||
private File basedir;
|
||||
|
||||
// Candidates collected so far
|
||||
private List<File> filesToReturn;
|
||||
private List<File> filesToReturn;
|
||||
|
||||
// Places still to explore for candidates
|
||||
private List<File> directoriesToExplore;
|
||||
private List<File> directoriesToExplore;
|
||||
|
||||
public DirEnumeration(File basedir) {
|
||||
this.basedir = basedir;
|
||||
@@ -58,7 +56,7 @@ public class DirEnumeration implements Enumeration<File> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean hasMoreElements() {
|
||||
computeValue();
|
||||
@@ -87,7 +85,6 @@ public class DirEnumeration implements Enumeration<File> {
|
||||
}
|
||||
}
|
||||
}
|
||||
// logger.debug("after visiting {} filesToReturn=#{} dirsToExplore=#{}",dir,filesToReturn.size(), directoriesToExplore.size());
|
||||
}
|
||||
|
||||
public File getDirectory() {
|
||||
@@ -97,7 +94,7 @@ public class DirEnumeration implements Enumeration<File> {
|
||||
/**
|
||||
* Return the relative path of this file to the base directory that the directory enumeration was
|
||||
* started for.
|
||||
* @param file a file discovered returned by this enumeration
|
||||
* @param file a file discovered returned by this enumeration
|
||||
* @return the relative path of the file (for example: a/b/c/D.class)
|
||||
*/
|
||||
public String getName(File file) {
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
/*
|
||||
* Copyright 2016 the original author or authors.
|
||||
*
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@@ -39,17 +39,17 @@ import org.springframework.cloud.function.compiler.java.MemoryBasedJavaFileManag
|
||||
/**
|
||||
* Iterable that will produce an iterator that returns classes found
|
||||
* on a specified classpath that meet specified criteria. For jars it finds, the
|
||||
* iterator will go into nested jars - this handles the situation with a
|
||||
* iterator will go into nested jars - this handles the situation with a
|
||||
* spring boot uberjar.
|
||||
*
|
||||
*
|
||||
* @author Andy Clement
|
||||
*/
|
||||
public class IterableClasspath extends CloseableFilterableJavaFileObjectIterable {
|
||||
|
||||
private static Logger logger = LoggerFactory.getLogger(IterableClasspath.class);
|
||||
|
||||
|
||||
private List<File> classpathEntries = new ArrayList<>();
|
||||
|
||||
|
||||
private List<ZipFile> openArchives = new ArrayList<>();
|
||||
|
||||
/**
|
||||
@@ -134,7 +134,7 @@ public class IterableClasspath extends CloseableFilterableJavaFileObjectIterable
|
||||
String entryName = entry.getName();
|
||||
if (accept(entryName)) {
|
||||
if (nestedZip!=null) {
|
||||
nextEntry = new NestedZipEntryJavaFileObject(openFile, openArchive,nestedZip, entry);
|
||||
nextEntry = new NestedZipEntryJavaFileObject(openFile, openArchive,nestedZip, entry);
|
||||
} else {
|
||||
nextEntry = new ZipEntryJavaFileObject(openFile, openArchive, entry);
|
||||
}
|
||||
@@ -143,7 +143,6 @@ public class IterableClasspath extends CloseableFilterableJavaFileObjectIterable
|
||||
// nested jar in uber jar
|
||||
logger.debug("opening nested archive {}",entry.getName());
|
||||
ZipInputStream zis = new ZipInputStream(openArchive.getInputStream(entry));
|
||||
// nextEntry = new NestedZipEntryJavaFileObject(openArchive.firstElement(),openArchive.peek(),entry);
|
||||
Enumeration<? extends ZipEntry> nestedZipEnumerator = new ZipEnumerator(zis);
|
||||
nestedZip = entry;
|
||||
openArchiveEnumeration.push(nestedZipEnumerator);
|
||||
@@ -217,10 +216,10 @@ public class IterableClasspath extends CloseableFilterableJavaFileObjectIterable
|
||||
nextEntry = null;
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,24 +62,22 @@ public class MemoryBasedJavaFileManager implements JavaFileManager {
|
||||
final static String BOOT_PACKAGING_PREFIX_FOR_CLASSES = "BOOT-INF/classes/";
|
||||
|
||||
final static String BOOT_PACKAGING_PREFIX_FOR_LIBRARIES = "BOOT-INF/lib/";
|
||||
|
||||
|
||||
private static Logger logger = LoggerFactory
|
||||
.getLogger(MemoryBasedJavaFileManager.class);
|
||||
|
||||
private CompilationOutputCollector outputCollector;
|
||||
|
||||
// private List<CloseableFilterableJavaFileObjectIterable> toClose = new ArrayList<>();
|
||||
|
||||
private Map<String, File> resolvedAdditionalDependencies = new LinkedHashMap<>();
|
||||
|
||||
|
||||
private String platformClasspath;
|
||||
|
||||
private String classpath;
|
||||
|
||||
private CompilationInfoCache compilationInfoCache;
|
||||
|
||||
|
||||
private Map<Key, IterableClasspath> iterables = new HashMap<>();
|
||||
|
||||
|
||||
public MemoryBasedJavaFileManager() {
|
||||
outputCollector = new CompilationOutputCollector();
|
||||
compilationInfoCache = new CompilationInfoCache();
|
||||
@@ -98,19 +96,19 @@ public class MemoryBasedJavaFileManager implements JavaFileManager {
|
||||
logger.debug("getClassLoader({})", location);
|
||||
return null; // Do not currently need to load plugins
|
||||
}
|
||||
|
||||
|
||||
// Holds information that may help speed up compilation
|
||||
static class CompilationInfoCache {
|
||||
|
||||
private Map<File, ArchiveInfo> archivePackageCache;
|
||||
|
||||
|
||||
static class ArchiveInfo {
|
||||
|
||||
|
||||
// The packages identified in a particular archive
|
||||
private List<String> packageNames;
|
||||
|
||||
|
||||
private boolean isBootJar = false;
|
||||
|
||||
|
||||
public ArchiveInfo(List<String> packageNames, boolean isBootJar) {
|
||||
this.packageNames = packageNames;
|
||||
Collections.sort(this.packageNames);
|
||||
@@ -140,7 +138,7 @@ public class MemoryBasedJavaFileManager implements JavaFileManager {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ArchiveInfo getArchiveInfoFor(File archive) {
|
||||
if (!archive.isFile() || !(archive.getName().endsWith(".zip") || archive.getName().endsWith(".jar"))) {
|
||||
// it is not an archive
|
||||
@@ -160,12 +158,12 @@ public class MemoryBasedJavaFileManager implements JavaFileManager {
|
||||
throw new IllegalStateException("Unexpected problem caching entries from "+archive.getName(), e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Walk the specified archive and collect up the package names of any .class files encountered. If
|
||||
* the archive contains nested jars packaged in a BOOT style way (under a BOOT-INF/lib folder) then
|
||||
* walk those too and include relevant packages.
|
||||
*
|
||||
*
|
||||
* @param file archive file to discover packages from
|
||||
* @return an ArchiveInfo encapsulating package info from the archive
|
||||
*/
|
||||
@@ -194,9 +192,6 @@ public class MemoryBasedJavaFileManager implements JavaFileManager {
|
||||
}
|
||||
} else {
|
||||
int idx = name.lastIndexOf('/') + 1;
|
||||
// if (name.contains("TestX")) {
|
||||
// System.out.println("For TestX: "+name+" "+idx+" "+BOOT_PACKAGING_PREFIX_FOR_CLASSES.length());
|
||||
// }
|
||||
if (idx != 0 ) {
|
||||
// Normalize to forward slashes
|
||||
name = name.replace('\\', '/');
|
||||
@@ -243,19 +238,19 @@ public class MemoryBasedJavaFileManager implements JavaFileManager {
|
||||
private String packageName;
|
||||
private Set<Kind> kinds;
|
||||
private boolean recurse;
|
||||
|
||||
|
||||
public Key(String classpath, String packageName, Set<Kind> kinds, boolean recurse) {
|
||||
this.classpath = classpath;
|
||||
this.packageName = packageName;
|
||||
this.kinds = kinds;
|
||||
this.recurse = recurse;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return ((classpath.hashCode()*37+(packageName==null?0:packageName.hashCode()))*37+kinds.hashCode())*37+(recurse?1:0);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (!(obj instanceof Key)) {
|
||||
@@ -270,12 +265,12 @@ public class MemoryBasedJavaFileManager implements JavaFileManager {
|
||||
}
|
||||
|
||||
private String getPlatformClassPath() {
|
||||
if (platformClasspath == null) {
|
||||
if (platformClasspath == null) {
|
||||
platformClasspath = System.getProperty("sun.boot.class.path");
|
||||
}
|
||||
return platformClasspath;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Iterable<JavaFileObject> list(Location location, String packageName,
|
||||
Set<Kind> kinds, boolean recurse) throws IOException {
|
||||
@@ -487,4 +482,4 @@ public class MemoryBasedJavaFileManager implements JavaFileManager {
|
||||
return resolvedAdditionalDependencies;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,15 +34,15 @@ import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Compile Java source at runtime and load it.
|
||||
*
|
||||
*
|
||||
* @author Andy Clement
|
||||
*/
|
||||
public class RuntimeJavaCompiler {
|
||||
|
||||
private JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
|
||||
|
||||
|
||||
private static Logger logger = LoggerFactory.getLogger(RuntimeJavaCompiler.class);
|
||||
|
||||
|
||||
/**
|
||||
* Compile the named class consisting of the supplied source code. If successful load the class
|
||||
* and return it. Multiple classes may get loaded if the source code included anonymous/inner/local
|
||||
@@ -54,18 +54,12 @@ public class RuntimeJavaCompiler {
|
||||
*/
|
||||
public CompilationResult compile(String className, String classSourceCode, String... dependencies) {
|
||||
logger.info("Compiling source for class {} using compiler {}",className,compiler.getClass().getName());
|
||||
|
||||
|
||||
DiagnosticCollector<JavaFileObject> diagnosticCollector = new DiagnosticCollector<JavaFileObject>();
|
||||
MemoryBasedJavaFileManager fileManager = new MemoryBasedJavaFileManager();
|
||||
List<CompilationMessage> resolutionMessages = fileManager.addAndResolveDependencies(dependencies);
|
||||
// JavaFileObject sourceFile = new StringBasedJavaSourceFileObject(className, classSourceCode);
|
||||
JavaFileObject sourceFile = InMemoryJavaFileObject.getSourceJavaFileObject(className, classSourceCode);
|
||||
// new InMemoryJavaFileObject(StandardLocation.SOURCE_PATH, className, javax.tools.JavaFileObject.Kind.SOURCE, null);
|
||||
// try (Writer w = sourceFile.openWriter()) {
|
||||
// w.write(classSourceCode);
|
||||
// } catch (IOException ioe) {
|
||||
// ioe.printStackTrace();
|
||||
// }
|
||||
|
||||
Iterable<? extends JavaFileObject> compilationUnits = Arrays.asList(sourceFile);
|
||||
CompilationTask task = compiler.getTask(null, fileManager , diagnosticCollector, null, null, compilationUnits);
|
||||
|
||||
@@ -73,7 +67,7 @@ public class RuntimeJavaCompiler {
|
||||
CompilationResult compilationResult = new CompilationResult(success);
|
||||
compilationResult.recordCompilationMessages(resolutionMessages);
|
||||
compilationResult.setResolvedAdditionalDependencies(new ArrayList<>(fileManager.getResolvedAdditionalDependencies().values()));
|
||||
|
||||
|
||||
// If successful there may be no errors but there might be info/warnings
|
||||
for (Diagnostic<? extends JavaFileObject> diagnostic : diagnosticCollector.getDiagnostics()) {
|
||||
CompilationMessage.Kind kind = (diagnostic.getKind()==Kind.ERROR?CompilationMessage.Kind.ERROR:CompilationMessage.Kind.OTHER);
|
||||
@@ -95,8 +89,8 @@ public class RuntimeJavaCompiler {
|
||||
CompilationMessage compilationMessage = new CompilationMessage(kind,diagnostic.getMessage(null),sourceCode,startPosition,(int)diagnostic.getEndPosition());
|
||||
compilationResult.recordCompilationMessage(compilationMessage);
|
||||
}
|
||||
if (success) {
|
||||
List<CompiledClassDefinition> ccds = fileManager.getCompiledClasses();
|
||||
if (success) {
|
||||
List<CompiledClassDefinition> ccds = fileManager.getCompiledClasses();
|
||||
List<Class<?>> classes = new ArrayList<>();
|
||||
try (SimpleClassLoader ccl = new SimpleClassLoader(this.getClass().getClassLoader())) {
|
||||
for (CompiledClassDefinition ccd: ccds) {
|
||||
@@ -111,4 +105,4 @@ public class RuntimeJavaCompiler {
|
||||
}
|
||||
return compilationResult;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016-2017 the original author or authors.
|
||||
* Copyright 2016-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -19,7 +19,6 @@ package org.springframework.cloud.function.context.catalog;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
@@ -66,28 +65,18 @@ public class InMemoryFunctionCatalog
|
||||
|
||||
@Override
|
||||
public <T> void register(FunctionRegistration<T> registration) {
|
||||
FunctionRegistrationEvent event;
|
||||
Class<?> type;
|
||||
Class<?> type = Object.class;
|
||||
if (registration.getTarget() instanceof Function) {
|
||||
type = Function.class;
|
||||
event = new FunctionRegistrationEvent(this, Function.class,
|
||||
registration.getNames());
|
||||
}
|
||||
else if (registration.getTarget() instanceof Supplier) {
|
||||
type = Supplier.class;
|
||||
event = new FunctionRegistrationEvent(this, Supplier.class,
|
||||
registration.getNames());
|
||||
}
|
||||
else if (registration.getTarget() instanceof Consumer) {
|
||||
type = Consumer.class;
|
||||
event = new FunctionRegistrationEvent(this, Consumer.class,
|
||||
registration.getNames());
|
||||
}
|
||||
else {
|
||||
type = Object.class;
|
||||
event = new FunctionRegistrationEvent(this, Object.class,
|
||||
registration.getNames());
|
||||
}
|
||||
FunctionRegistrationEvent event = new FunctionRegistrationEvent(this, type, registration.getNames());
|
||||
|
||||
registrations.put(registration.getTarget(), registration);
|
||||
FunctionRegistration<T> wrapped = registration.wrap();
|
||||
if (wrapped != registration) {
|
||||
|
||||
@@ -39,7 +39,7 @@ public abstract class MessageUtils {
|
||||
* isolated class loader, then the message will be created with the target class
|
||||
* loader (therefore the {@link Message} class must be on the classpath of the target
|
||||
* class loader).
|
||||
*
|
||||
*
|
||||
* @param handler the function that will be applied to the message
|
||||
* @param payload the payload of the message
|
||||
* @param headers the headers for the message
|
||||
@@ -71,10 +71,10 @@ public abstract class MessageUtils {
|
||||
|
||||
/**
|
||||
* Convert a message from the handler into one that is safe to consume in the caller's
|
||||
* class laoder. If the handler is a wrapper for a function in an isolated class
|
||||
* class loader. If the handler is a wrapper for a function in an isolated class
|
||||
* loader, then the message will be created with the target class loader (therefore
|
||||
* the {@link Message} class must be on the classpath of the target class loader).
|
||||
*
|
||||
*
|
||||
* @param handler the function that generated the message
|
||||
* @param message the message to convert
|
||||
* @return a message with the correct class loader
|
||||
|
||||
Reference in New Issue
Block a user