Code polishing and general cleanup

This commit is contained in:
Oleg Zhurakousky
2018-06-27 08:43:28 -04:00
parent bb397c6a07
commit 377c4d93f0
7 changed files with 61 additions and 89 deletions

View 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.
@@ -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;
}
}
}

View 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.
@@ -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) {

View 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();
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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) {

View File

@@ -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