diff --git a/spring-cloud-function-compiler/src/main/java/org/springframework/cloud/function/compiler/java/CompiledClassDefinition.java b/spring-cloud-function-compiler/src/main/java/org/springframework/cloud/function/compiler/java/CompiledClassDefinition.java index 11560bb01..4dbbeb972 100644 --- a/spring-cloud-function-compiler/src/main/java/org/springframework/cloud/function/compiler/java/CompiledClassDefinition.java +++ b/spring-cloud-function-compiler/src/main/java/org/springframework/cloud/function/compiler/java/CompiledClassDefinition.java @@ -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; } -} \ No newline at end of file +} diff --git a/spring-cloud-function-compiler/src/main/java/org/springframework/cloud/function/compiler/java/DirEnumeration.java b/spring-cloud-function-compiler/src/main/java/org/springframework/cloud/function/compiler/java/DirEnumeration.java index 59777bf6a..c7df9be18 100644 --- a/spring-cloud-function-compiler/src/main/java/org/springframework/cloud/function/compiler/java/DirEnumeration.java +++ b/spring-cloud-function-compiler/src/main/java/org/springframework/cloud/function/compiler/java/DirEnumeration.java @@ -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 { - -// private final static Logger logger = LoggerFactory.getLogger(DirEnumeration.class); - + // The starting point - private File basedir; - + private File basedir; + // Candidates collected so far - private List filesToReturn; + private List filesToReturn; // Places still to explore for candidates - private List directoriesToExplore; + private List directoriesToExplore; public DirEnumeration(File basedir) { this.basedir = basedir; @@ -58,7 +56,7 @@ public class DirEnumeration implements Enumeration { } } } - + @Override public boolean hasMoreElements() { computeValue(); @@ -87,7 +85,6 @@ public class DirEnumeration implements Enumeration { } } } -// logger.debug("after visiting {} filesToReturn=#{} dirsToExplore=#{}",dir,filesToReturn.size(), directoriesToExplore.size()); } public File getDirectory() { @@ -97,7 +94,7 @@ public class DirEnumeration implements Enumeration { /** * 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) { diff --git a/spring-cloud-function-compiler/src/main/java/org/springframework/cloud/function/compiler/java/IterableClasspath.java b/spring-cloud-function-compiler/src/main/java/org/springframework/cloud/function/compiler/java/IterableClasspath.java index 393bbff80..bc92d4f73 100644 --- a/spring-cloud-function-compiler/src/main/java/org/springframework/cloud/function/compiler/java/IterableClasspath.java +++ b/spring-cloud-function-compiler/src/main/java/org/springframework/cloud/function/compiler/java/IterableClasspath.java @@ -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 classpathEntries = new ArrayList<>(); - + private List 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 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(); } -} \ No newline at end of file +} diff --git a/spring-cloud-function-compiler/src/main/java/org/springframework/cloud/function/compiler/java/MemoryBasedJavaFileManager.java b/spring-cloud-function-compiler/src/main/java/org/springframework/cloud/function/compiler/java/MemoryBasedJavaFileManager.java index ba1ac46f3..b3cc3e168 100644 --- a/spring-cloud-function-compiler/src/main/java/org/springframework/cloud/function/compiler/java/MemoryBasedJavaFileManager.java +++ b/spring-cloud-function-compiler/src/main/java/org/springframework/cloud/function/compiler/java/MemoryBasedJavaFileManager.java @@ -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 toClose = new ArrayList<>(); - private Map resolvedAdditionalDependencies = new LinkedHashMap<>(); - + private String platformClasspath; private String classpath; private CompilationInfoCache compilationInfoCache; - + private Map 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 archivePackageCache; - + static class ArchiveInfo { - + // The packages identified in a particular archive private List packageNames; - + private boolean isBootJar = false; - + public ArchiveInfo(List 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 kinds; private boolean recurse; - + public Key(String classpath, String packageName, Set 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 list(Location location, String packageName, Set kinds, boolean recurse) throws IOException { @@ -487,4 +482,4 @@ public class MemoryBasedJavaFileManager implements JavaFileManager { return resolvedAdditionalDependencies; } -} \ No newline at end of file +} diff --git a/spring-cloud-function-compiler/src/main/java/org/springframework/cloud/function/compiler/java/RuntimeJavaCompiler.java b/spring-cloud-function-compiler/src/main/java/org/springframework/cloud/function/compiler/java/RuntimeJavaCompiler.java index 5b8a5d58e..c10ec0ba4 100644 --- a/spring-cloud-function-compiler/src/main/java/org/springframework/cloud/function/compiler/java/RuntimeJavaCompiler.java +++ b/spring-cloud-function-compiler/src/main/java/org/springframework/cloud/function/compiler/java/RuntimeJavaCompiler.java @@ -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 diagnosticCollector = new DiagnosticCollector(); MemoryBasedJavaFileManager fileManager = new MemoryBasedJavaFileManager(); List 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 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 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 ccds = fileManager.getCompiledClasses(); + if (success) { + List ccds = fileManager.getCompiledClasses(); List> classes = new ArrayList<>(); try (SimpleClassLoader ccl = new SimpleClassLoader(this.getClass().getClassLoader())) { for (CompiledClassDefinition ccd: ccds) { @@ -111,4 +105,4 @@ public class RuntimeJavaCompiler { } return compilationResult; } -} \ No newline at end of file +} diff --git a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/catalog/InMemoryFunctionCatalog.java b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/catalog/InMemoryFunctionCatalog.java index e370aa19a..467921dc1 100644 --- a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/catalog/InMemoryFunctionCatalog.java +++ b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/catalog/InMemoryFunctionCatalog.java @@ -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 void register(FunctionRegistration 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 wrapped = registration.wrap(); if (wrapped != registration) { diff --git a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/message/MessageUtils.java b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/message/MessageUtils.java index f8f9cde9e..1174592d2 100644 --- a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/message/MessageUtils.java +++ b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/message/MessageUtils.java @@ -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