# HG changeset patch # User rbackman # Date 1484820633 -3600 # Node ID 033b9f74b930817b2dadca731432bd4c6cdfe7e5 # Parent 7a094360fe82c84917021cc23e2103f42ec596e8# Parent f38fde4a6b526922c963c3642dec2e944030a142 Merge diff -r 7a094360fe82 -r 033b9f74b930 hotspot/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/LoadedClass.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/LoadedClass.java Thu Jan 19 11:10:33 2017 +0100 @@ -0,0 +1,64 @@ +package jdk.tools.jaotc;/* + * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +public class LoadedClass { + private final String name; + private final Class clz; + + public LoadedClass(String name, Class clz) { + this.name = name; + this.clz = clz; + } + + public String getName() { + return name; + } + + public Class getLoadedClass() { + return clz; + } + + @Override + public String toString() { + return name; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof LoadedClass)) return false; + + LoadedClass that = (LoadedClass) o; + + if (name != null ? !name.equals(that.name) : that.name != null) return false; + return clz != null ? clz.equals(that.clz) : that.clz == null; + + } + + @Override + public int hashCode() { + int result = name != null ? name.hashCode() : 0; + result = 31 * result + (clz != null ? clz.hashCode() : 0); + return result; + } +} diff -r 7a094360fe82 -r 033b9f74b930 hotspot/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/Main.java --- a/hotspot/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/Main.java Thu Jan 19 10:30:37 2017 +0100 +++ b/hotspot/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/Main.java Thu Jan 19 11:10:33 2017 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -43,6 +43,7 @@ import java.text.MessageFormat; import java.util.ArrayList; import java.util.Date; +import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.ListIterator; @@ -51,7 +52,11 @@ import jdk.tools.jaotc.binformat.BinaryContainer; import jdk.tools.jaotc.binformat.ByteContainer; -import jdk.tools.jaotc.collect.ClassCollector; +import jdk.tools.jaotc.collect.*; +import jdk.tools.jaotc.collect.classname.ClassNameSourceProvider; +import jdk.tools.jaotc.collect.directory.DirectorySourceProvider; +import jdk.tools.jaotc.collect.jar.JarSourceProvider; +import jdk.tools.jaotc.collect.module.ModuleSourceProvider; import jdk.tools.jaotc.utils.Timer; import org.graalvm.compiler.api.runtime.GraalJVMCICompiler; @@ -127,17 +132,7 @@ abstract void process(Main task, String opt, String arg) throws BadArgs; } - static Option[] recognizedOptions = {new Option(" --module Module to compile", true, "--module") { - @Override - void process(Main task, String opt, String arg) { - task.options.module = arg; - } - }, new Option(" --module-path Specify where to find module to compile", true, "--module-path") { - @Override - void process(Main task, String opt, String arg) { - task.options.modulepath = arg; - } - }, new Option(" --output Output file name", true, "--output") { + static Option[] recognizedOptions = { new Option(" --output Output file name", true, "--output") { @Override void process(Main task, String opt, String arg) { String name = arg; @@ -161,10 +156,25 @@ void process(Main task, String opt, String arg) { task.options.compileWithAssertions = true; } - }, new Option(" --classpath Specify where to find user class files", true, "--classpath", "--class-path") { + }, new Option(" --classname > Class names to AOT compile (: separated list)", true, "--classname") { + @Override + void process(Main task, String opt, String arg) { + task.options.files.addAll(ClassSearch.makeList(ClassNameSourceProvider.TYPE, arg)); + } + }, new Option(" --directory Directories to search for class files. (: separated list)", true, "--directory") { @Override void process(Main task, String opt, String arg) { - task.options.classpath = arg; + task.options.files.addAll(ClassSearch.makeList(DirectorySourceProvider.TYPE, arg)); + } + }, new Option(" --jar Jar files to search for class files. (: separated list)", true, "--jar") { + @Override + void process(Main task, String opt, String arg) { + task.options.files.addAll(ClassSearch.makeList(JarSourceProvider.TYPE, arg)); + } + }, new Option(" --module module names to AOT compile (: separated list)", true, "--module") { + @Override + void process(Main task, String opt, String arg) { + task.options.files.addAll(ClassSearch.makeList(ModuleSourceProvider.TYPE, arg)); } }, new Option(" --threads Number of compilation threads to be used", true, "--threads") { @Override @@ -218,6 +228,12 @@ void process(Main task, String opt, String arg) { task.options.version = true; } + }, new Option(" --search-path Where to search for jarfiles and modules", true, "--search-path") { + @Override + void process(Main task, String opt, String arg) { + String[] elements = arg.split(":"); + task.options.searchPath.add(elements); + } }, new Option(" -J Pass directly to the runtime system", false, "-J") { @Override void process(Main task, String opt, String arg) { @@ -225,12 +241,11 @@ }}; public static class Options { - public List files = new LinkedList<>(); - public String module = null; - public String modulepath = "modules"; + public List files = new LinkedList<>(); public String outputName = "unnamed"; public String methodList; - public String classpath = "."; + public List sources = new ArrayList<>(); + public SearchPath searchPath = new SearchPath(); /** * We don't see scaling beyond 16 threads. @@ -288,7 +303,9 @@ printlnInfo("Compiling " + options.outputName + "..."); final long start = System.currentTimeMillis(); - run(); + if (!run()) { + return EXIT_ABNORMAL; + } final long end = System.currentTimeMillis(); printlnInfo("Total time: " + (end - start) + " ms"); @@ -331,17 +348,34 @@ } @SuppressWarnings("try") - private void run() throws Exception { + private boolean run() throws Exception { openLog(); try { CompilationSpec compilationRestrictions = collectSpecifiedMethods(); - Set> classesToCompile; + Set> classesToCompile = new HashSet<>(); try (Timer t = new Timer(this, "")) { - ClassCollector collector = new ClassCollector(this.options, this); - classesToCompile = collector.collectClassesToCompile(); + FileSupport fileSupport = new FileSupport(); + ClassSearch lookup = new ClassSearch(); + lookup.addProvider(new ModuleSourceProvider()); + lookup.addProvider(new ClassNameSourceProvider(fileSupport)); + lookup.addProvider(new JarSourceProvider()); + lookup.addProvider(new DirectorySourceProvider(fileSupport)); + + List found = null; + try { + found = lookup.search(options.files, options.searchPath); + } catch (InternalError e) { + reportError(e); + return false; + } + + for (LoadedClass loadedClass : found) { + classesToCompile.add(loadedClass.getLoadedClass()); + } + printInfo(classesToCompile.size() + " classes found"); } @@ -464,6 +498,7 @@ } finally { closeLog(); } + return true; } private void addMethods(AOTCompiledClass aotClass, ResolvedJavaMethod[] methods, CompilationSpec compilationRestrictions, GraalFilters filters) { @@ -527,7 +562,7 @@ break; } } else { - options.files.add(arg); + options.files.add(new SearchFor(arg)); } } } @@ -588,6 +623,12 @@ log.flush(); } + private void reportError(Throwable e) { + log.println("Error: " + e.getMessage()); + e.printStackTrace(log); + log.flush(); + } + private void reportError(String key, Object... args) { printError(MessageFormat.format(key, args)); } @@ -603,9 +644,9 @@ } private void showHelp() { - log.println("Usage: " + PROGNAME + " <--module name> | "); + log.println("Usage: " + PROGNAME + " | "); log.println(); - log.println(" list A list of class files, jar files or directories which"); + log.println(" list A list of class names, jar files or directories which"); log.println(" contains class files."); log.println(); log.println("where possible options include:"); diff -r 7a094360fe82 -r 033b9f74b930 hotspot/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/ClassCollector.java --- a/hotspot/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/ClassCollector.java Thu Jan 19 10:30:37 2017 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,332 +0,0 @@ -/* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.tools.jaotc.collect; - -import jdk.tools.jaotc.LogPrinter; -import jdk.tools.jaotc.Main; - -import java.io.File; -import java.io.IOException; -import java.net.*; -import java.nio.file.*; -import java.nio.file.attribute.BasicFileAttributes; -import java.util.*; - -import static java.nio.file.FileVisitResult.CONTINUE; - -public class ClassCollector { - private final Main.Options options; - private final LogPrinter log; - - public ClassCollector(Main.Options options, LogPrinter log) { - this.options = options; - this.log = log; - } - - /** - * Collect all class names passed by the user. - * - * @return array list of classes - */ - public Set> collectClassesToCompile() { - Set> classes = new HashSet<>(); - List filesToScan = new LinkedList<>(options.files); - - if (options.module != null) { - classes.addAll(scanModule(filesToScan)); - } - - classes.addAll(scanFiles(filesToScan)); - return classes; - } - - private Set> scanModule(List filesToScan) { - String module = options.module; - // Search module in standard JDK installation. - Path dir = getModuleDirectory(options.modulepath, module); - - if (Files.isDirectory(dir)) { - return loadFromModuleDirectory(dir); - } else { - findFilesToScan(filesToScan, module); - return new HashSet<>(); - } - } - - private Set> loadFromModuleDirectory(Path dir) { - log.printInfo("Scanning module: " + dir + " ..."); - log.printlnVerbose(" "); // Break line - - FileSystemFinder finder = new FileSystemFinder(dir, pathname -> entryIsClassFile(pathname.toString())); - Set> cls = loadWithClassLoader(() -> ClassLoader.getSystemClassLoader(), dir, finder); - log.printlnInfo(" " + cls.size() + " classes loaded."); - return cls; - } - - private void findFilesToScan(List filesToScan, String module) { - // Try to search regular directory, .jar or .class files - Path path = Paths.get(options.modulepath, module); - - if (Files.isDirectory(path)) { - filesToScan.add("."); - options.classpath = path.toString(); - } else if (path.endsWith(".jar") || path.endsWith(".class")) { - filesToScan.add(path.toString()); - } else { - path = Paths.get(options.modulepath, module + ".jar"); - if (Files.exists(path)) { - filesToScan.add(path.toString()); - } else { - path = Paths.get(options.modulepath, module + ".class"); - if (Files.exists(path)) { - filesToScan.add(path.toString()); - } else { - throw new InternalError("Expecting a .class, .jar or directory: " + path); - } - } - } - } - - private boolean entryIsClassFile(String entry) { - return entry.endsWith(".class") && !entry.endsWith("module-info.class"); - } - - private Set> scanFiles(List filesToScan) { - Set> classes = new HashSet<>(); - for (String fileName : filesToScan) { - Set> loaded = scanFile(fileName); - log.printlnInfo(" " + loaded.size() + " classes loaded."); - classes.addAll(loaded); - } - return classes; - } - - interface ClassLoaderFactory { - ClassLoader create() throws IOException; - } - - private Set> loadWithClassLoader(ClassLoaderFactory factory, Path root, FileSystemFinder finder) { - ClassLoader loader = null; - try { - loader = factory.create(); - return loadClassFiles(root, finder, loader); - } catch (IOException e) { - throw new InternalError(e); - } finally { - if (loader instanceof AutoCloseable) { - try { - ((AutoCloseable) loader).close(); - } catch (Exception e) { - throw new InternalError(e); - } - } - } - } - - private Set> scanFile(String fileName) { - log.printInfo("Scanning: " + fileName + " ..."); - log.printlnVerbose(" "); // Break line - - if (fileName.endsWith(".jar")) { - return loadFromJarFile(fileName); - } else if (fileName.endsWith(".class")) { - Set> classes = new HashSet<>(); - loadFromClassFile(fileName, classes); - return classes; - } else { - return scanClassPath(fileName); - } - } - - private Set> loadFromJarFile(String fileName) { - FileSystem fs = makeFileSystem(fileName); - FileSystemFinder finder = new FileSystemFinder(fs.getPath("/"), pathname -> entryIsClassFile(pathname.toString())); - return loadWithClassLoader(() -> URLClassLoader.newInstance(buildUrls(fileName)), fs.getPath("/"), finder); - } - - private void loadFromClassFile(String fileName, Set> classes) { - Class result; - File file = new File(options.classpath); - try (URLClassLoader loader = URLClassLoader.newInstance(buildUrls(file))) { - result = loadClassFile(loader, fileName); - } catch (IOException e) { - throw new InternalError(e); - } - Class c = result; - addClass(classes, fileName, c); - } - - private Set> scanClassPath(String fileName) { - Path classPath = Paths.get(options.classpath); - if (!Files.exists(classPath)) { - throw new InternalError("Path does not exist: " + classPath); - } - if (!Files.isDirectory(classPath)) { - throw new InternalError("Path must be a directory: " + classPath); - } - - // Combine class path and file name and see what it is. - Path combinedPath = Paths.get(options.classpath + File.separator + fileName); - if (combinedPath.endsWith(".class")) { - throw new InternalError("unimplemented"); - } else if (Files.isDirectory(combinedPath)) { - return scanDirectory(classPath, combinedPath); - } else { - throw new InternalError("Expecting a .class, .jar or directory: " + fileName); - } - } - - private FileSystem makeFileSystem(String fileName) { - try { - return FileSystems.newFileSystem(makeJarFileURI(fileName), new HashMap<>()); - } catch (IOException e) { - throw new InternalError(e); - } - } - - private URI makeJarFileURI(String fileName) { - try { - return new URI("jar:file:" + Paths.get(fileName).toAbsolutePath() + "!/"); - } catch (URISyntaxException e) { - throw new InternalError(e); - } - } - - private PathMatcher combine(PathMatcher m1, PathMatcher m2) { - return path -> m1.matches(path) && m2.matches(path); - } - - private Set> scanDirectory(Path classPath, Path combinedPath) { - String dir = options.classpath; - - FileSystem fileSystem = FileSystems.getDefault(); - PathMatcher matcher = fileSystem.getPathMatcher("glob:" + "*.class"); - FileSystemFinder finder = new FileSystemFinder(combinedPath, - combine(matcher, pathname -> entryIsClassFile(pathname.toString()))); - - File file = new File(dir); - try (URLClassLoader loader = URLClassLoader.newInstance(buildUrls(file))) { - return loadClassFiles(classPath, finder, loader); - } catch (IOException e) { - throw new InternalError(e); - } - } - - private Set> loadClassFiles(Path root, FileSystemFinder finder, ClassLoader loader) { - Set> classes = new HashSet<>(); - for (Path name : finder.done()) { - // Now relativize to the class path so we get the actual class names. - String entry = root.relativize(name).normalize().toString(); - Class c = loadClassFile(loader, entry); - addClass(classes, entry, c); - } - return classes; - } - - private void addClass(Set> classes, String name, Class c) { - if (c != null) { - classes.add(c); - log.printlnVerbose(" loaded " + name); - } - } - - private URL[] buildUrls(String fileName) throws MalformedURLException { - return new URL[]{ new URL("jar:file:" + Paths.get(fileName).toAbsolutePath() + "!/") }; - } - - private URL[] buildUrls(File file) throws MalformedURLException { - return new URL[] {file.toURI().toURL() }; - } - - private Path getModuleDirectory(String modulepath, String module) { - FileSystem fs = FileSystems.getFileSystem(URI.create("jrt:/")); - return fs.getPath(modulepath, module); - } - - /** - * Loads a class with the given file name from the specified {@link URLClassLoader}. - */ - private Class loadClassFile(final ClassLoader loader, final String fileName) { - int start = 0; - if (fileName.startsWith("/")) { - start = 1; - } - String className = fileName.substring(start, fileName.length() - ".class".length()); - className = className.replace('/', '.'); - try { - return loader.loadClass(className); - } catch (Throwable e) { - // If we are running in JCK mode we ignore all exceptions. - if (options.ignoreClassLoadingErrors) { - log.printError(className + ": " + e); - return null; - } - throw new InternalError(e); - } - } - - /** - * {@link FileVisitor} implementation to find class files recursively. - */ - private static class FileSystemFinder extends SimpleFileVisitor { - private final ArrayList fileNames = new ArrayList<>(); - private final PathMatcher filter; - - FileSystemFinder(Path combinedPath, PathMatcher filter) { - this.filter = filter; - try { - Files.walkFileTree(combinedPath, this); - } catch (IOException e) { - throw new InternalError(e); - } - } - - /** - * Compares the glob pattern against the file name. - */ - void find(Path file) { - Path name = file.getFileName(); - if (name != null && filter.matches(name)) { - fileNames.add(file); - } - } - - List done() { - return fileNames; - } - - @Override - public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) { - find(file); - return CONTINUE; - } - - @Override - public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) { - find(dir); - return CONTINUE; - } - - } -} diff -r 7a094360fe82 -r 033b9f74b930 hotspot/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/ClassSearch.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/ClassSearch.java Thu Jan 19 11:10:33 2017 +0100 @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.tools.jaotc.collect; + +import jdk.tools.jaotc.LoadedClass; + +import java.util.ArrayList; +import java.util.List; + +public class ClassSearch { + private List providers = new ArrayList<>(); + + public void addProvider(SourceProvider provider) { + providers.add(provider); + } + + public List search(List search, SearchPath searchPath) { + List loaded = new ArrayList<>(); + + List sources = new ArrayList<>(); + + for (SearchFor entry : search) { + sources.add(findSource(entry, searchPath)); + } + + for (ClassSource source : sources) { + source.eachClass((name, loader) -> loaded.add(loadClass(name, loader))); + } + + return loaded; + } + + private LoadedClass loadClass(String name, ClassLoader loader) { + try { + Class clzz = loader.loadClass(name); + return new LoadedClass(name, clzz); + } catch (ClassNotFoundException e) { + throw new InternalError("Failed to load with: " + loader, e); + } + } + + private ClassSource findSource(SearchFor searchFor, SearchPath searchPath) { + ClassSource found = null; + + for (SourceProvider provider : providers) { + if (!searchFor.isUnknown() && !provider.supports(searchFor.getType())) { + continue; + } + + ClassSource source = provider.findSource(searchFor.getName(), searchPath); + if (source != null) { + if (found != null) { + throw new InternalError("Multiple possible sources: " + source + " and: " + found); + } + found = source; + } + } + + if (found == null) { + throw new InternalError("Failed to find: " + searchFor.toString()); + } + return found; + } + + public static List makeList(String type, String argument) { + List list = new ArrayList<>(); + String[] elements = argument.split(":"); + for (String element : elements) { + list.add(new SearchFor(element, type)); + } + return list; + } +} diff -r 7a094360fe82 -r 033b9f74b930 hotspot/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/ClassSource.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/ClassSource.java Thu Jan 19 11:10:33 2017 +0100 @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.tools.jaotc.collect; + +import java.nio.file.Path; +import java.util.function.BiConsumer; + +public interface ClassSource { + static boolean pathIsClassFile(Path entry) { + String fileName = entry.getFileName().toString(); + return fileName.endsWith(".class") && !fileName.endsWith("module-info.class"); + } + + static String makeClassName(Path path) { + String fileName = path.toString(); + + if (!fileName.endsWith(".class")) { + throw new IllegalArgumentException("File doesn't end with .class: '" + fileName + "'"); + } + + int start = 0; + if (fileName.startsWith("/")) { + start = 1; + } + + String className = fileName.substring(start, fileName.length() - ".class".length()); + className = className.replace('/', '.'); + return className; + } + + void eachClass(BiConsumer consumer); +} diff -r 7a094360fe82 -r 033b9f74b930 hotspot/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/FileSupport.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/FileSupport.java Thu Jan 19 11:10:33 2017 +0100 @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.tools.jaotc.collect; + +import java.io.IOException; +import java.net.*; +import java.nio.file.*; +import java.util.HashMap; + +public class FileSupport { + public boolean exists(Path path) { + return Files.exists(path); + } + + public boolean isDirectory(Path path) { + return Files.isDirectory(path); + } + + private FileSystem makeJarFileSystem(Path path) { + try { + return FileSystems.newFileSystem(makeJarFileURI(path), new HashMap<>()); + } catch (IOException e) { + throw new InternalError(e); + } + } + + private URI makeJarFileURI(Path path) { + try { + return new URI("jar:file:" + path.toAbsolutePath() + "!/"); + } catch (URISyntaxException e) { + throw new InternalError(e); + } + } + + public ClassLoader createClassLoader(Path path, ClassLoader parent) { + try { + return URLClassLoader.newInstance(buildUrls(path), parent); + } catch (MalformedURLException e) { + throw new InternalError(e); + } + } + + public ClassLoader createClassLoader(Path path) throws MalformedURLException { + return URLClassLoader.newInstance(buildUrls(path)); + } + + private URL[] buildUrls(Path path) throws MalformedURLException { + return new URL[] { path.toUri().toURL() }; + } + + public Path getJarFileSystemRoot(Path jarFile) { + FileSystem fileSystem = makeJarFileSystem(jarFile); + return fileSystem.getPath("/"); + } + + public boolean isAbsolute(Path entry) { + return entry.isAbsolute(); + } + + public Path getSubDirectory(FileSystem fileSystem, Path root, Path path) throws IOException { + DirectoryStream paths = fileSystem.provider().newDirectoryStream(root,null); + for (Path entry : paths) { + Path relative = root.relativize(entry); + if (relative.equals(path)) { + return entry; + } + } + return null; + } +} diff -r 7a094360fe82 -r 033b9f74b930 hotspot/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/FileSystemFinder.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/FileSystemFinder.java Thu Jan 19 11:10:33 2017 +0100 @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.tools.jaotc.collect; + +import java.io.IOException; +import java.nio.file.*; +import java.nio.file.attribute.BasicFileAttributes; +import java.util.ArrayList; +import java.util.Iterator; + +import static java.nio.file.FileVisitResult.CONTINUE; + +/** + * {@link FileVisitor} implementation to find class files recursively. + */ +public class FileSystemFinder extends SimpleFileVisitor implements Iterable { + private final ArrayList fileNames = new ArrayList<>(); + private final PathMatcher filter; + + public FileSystemFinder(Path combinedPath, PathMatcher filter) { + this.filter = filter; + try { + Files.walkFileTree(combinedPath, this); + } catch (IOException e) { + throw new InternalError(e); + } + } + + /** + * Compares the glob pattern against the file name. + */ + private void find(Path file) { + Path name = file.getFileName(); + if (name != null && filter.matches(name)) { + fileNames.add(file); + } + } + + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) { + find(file); + return CONTINUE; + } + + @Override + public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) { + find(dir); + return CONTINUE; + } + + + @Override + public Iterator iterator() { + return fileNames.iterator(); + } +} diff -r 7a094360fe82 -r 033b9f74b930 hotspot/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/SearchFor.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/SearchFor.java Thu Jan 19 11:10:33 2017 +0100 @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.tools.jaotc.collect; + +public class SearchFor { + private final String name; + private final String type; + + public SearchFor(String name) { + this(name, "unknown"); + } + + public SearchFor(String name, String type) { + this.name = name; + this.type = type; + } + + public boolean isUnknown() { + return "unknown".equals(type); + } + + public String getType() { + return this.type; + } + + public String getName() { + return this.name; + } + + @Override + public String toString() { + return type + ":" + name; + } +} diff -r 7a094360fe82 -r 033b9f74b930 hotspot/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/SearchPath.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/SearchPath.java Thu Jan 19 11:10:33 2017 +0100 @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.tools.jaotc.collect; + +import java.nio.file.FileSystem; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.List; + +public class SearchPath { + private final List searchPaths = new ArrayList<>(); + private final FileSupport fileSupport; + + public SearchPath() { + this(new FileSupport()); + } + + public SearchPath(FileSupport fileSupport) { + this.fileSupport = fileSupport; + } + + public Path find(FileSystem fileSystem, Path entry, String... defaults) { + if (isAbsolute(entry)) { + if (exists(entry)) { + return entry; + } + return null; + } + + if (exists(entry)) { + return entry; + } + + for (String searchPath : defaults) { + Path newPath = fileSystem.getPath(searchPath, entry.toString()); + if (exists(newPath)) { + return newPath; + } + } + + for (Path searchPath : searchPaths) { + Path newPath = fileSystem.getPath(searchPath.toString(), entry.toString()); + if (exists(newPath)) { + return newPath; + } + } + + return null; + } + + private boolean isAbsolute(Path entry) { + return fileSupport.isAbsolute(entry); + } + + private boolean exists(Path entry) { + return fileSupport.exists(entry); + } + + public void add(String... paths) { + for (String name : paths) { + Path path = Paths.get(name); + searchPaths.add(path); + } + } +} + diff -r 7a094360fe82 -r 033b9f74b930 hotspot/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/SourceProvider.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/SourceProvider.java Thu Jan 19 11:10:33 2017 +0100 @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.tools.jaotc.collect; + +public interface SourceProvider { + ClassSource findSource(String name, SearchPath searchPath); + + boolean supports(String type); +} diff -r 7a094360fe82 -r 033b9f74b930 hotspot/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/classname/ClassNameSource.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/classname/ClassNameSource.java Thu Jan 19 11:10:33 2017 +0100 @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.tools.jaotc.collect.classname; + +import jdk.tools.jaotc.collect.ClassSource; + +import java.util.function.BiConsumer; + +public class ClassNameSource implements ClassSource { + private final String name; + private final ClassLoader classLoader; + + public ClassNameSource(String name, ClassLoader classLoader) { + this.name = name; + this.classLoader = classLoader; + } + + @Override + public void eachClass(BiConsumer consumer) { + consumer.accept(name, classLoader); + } +} diff -r 7a094360fe82 -r 033b9f74b930 hotspot/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/classname/ClassNameSourceProvider.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/classname/ClassNameSourceProvider.java Thu Jan 19 11:10:33 2017 +0100 @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.tools.jaotc.collect.classname; + +import jdk.tools.jaotc.collect.ClassSource; +import jdk.tools.jaotc.collect.FileSupport; +import jdk.tools.jaotc.collect.SearchPath; +import jdk.tools.jaotc.collect.SourceProvider; + +import java.nio.file.Path; +import java.nio.file.Paths; + +public class ClassNameSourceProvider implements SourceProvider { + public final static String TYPE = "classname"; + private final ClassLoader classLoader; + + public ClassNameSourceProvider(FileSupport fileSupport) { + String classPath = System.getProperty("java.class.path"); + ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader(); + if (classPath != null && !classPath.isEmpty()) { + classLoader = systemClassLoader; + } else { + Path path = Paths.get(".").toAbsolutePath(); + classLoader = fileSupport.createClassLoader(path, systemClassLoader); + } + } + + @Override + public ClassSource findSource(String name, SearchPath searchPath) { + try { + classLoader.loadClass(name); + return new ClassNameSource(name, classLoader); + } catch (ClassNotFoundException e) { + return null; + } + } + + @Override + public boolean supports(String type) { + return TYPE.equals(type); + } +} diff -r 7a094360fe82 -r 033b9f74b930 hotspot/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/directory/DirectorySource.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/directory/DirectorySource.java Thu Jan 19 11:10:33 2017 +0100 @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.tools.jaotc.collect.directory; + +import jdk.tools.jaotc.collect.ClassSource; +import jdk.tools.jaotc.collect.FileSystemFinder; + +import java.nio.file.Path; +import java.util.function.BiConsumer; + +public class DirectorySource implements ClassSource { + private final Path directoryPath; + private final ClassLoader classLoader; + + public DirectorySource(Path directoryPath, ClassLoader classLoader) { + this.directoryPath = directoryPath; + this.classLoader = classLoader; + } + + @Override + public void eachClass(BiConsumer consumer) { + FileSystemFinder finder = new FileSystemFinder(directoryPath, ClassSource::pathIsClassFile); + + for (Path path : finder) { + consumer.accept(ClassSource.makeClassName(directoryPath.relativize(path).normalize()), classLoader); + } + } + + @Override + public String toString() { + return "directory:" + directoryPath.toString(); + } +} diff -r 7a094360fe82 -r 033b9f74b930 hotspot/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/directory/DirectorySourceProvider.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/directory/DirectorySourceProvider.java Thu Jan 19 11:10:33 2017 +0100 @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.tools.jaotc.collect.directory; + +import jdk.tools.jaotc.collect.ClassSource; +import jdk.tools.jaotc.collect.FileSupport; +import jdk.tools.jaotc.collect.SearchPath; +import jdk.tools.jaotc.collect.SourceProvider; + +import java.net.MalformedURLException; +import java.nio.file.FileSystem; +import java.nio.file.FileSystems; +import java.nio.file.Path; + +public class DirectorySourceProvider implements SourceProvider { + private final FileSupport fileSupport; + private final FileSystem fileSystem; + public final static String TYPE = "directory"; + + public DirectorySourceProvider(FileSupport fileSupport) { + this.fileSupport = fileSupport; + fileSystem = FileSystems.getDefault(); + } + + @Override + public ClassSource findSource(String name, SearchPath searchPath) { + Path directoryPath = fileSystem.getPath(name); + + if (!fileSupport.exists(directoryPath)) { + return null; + } + if (!fileSupport.isDirectory(directoryPath)) { + return null; + } + + try { + ClassLoader classLoader = fileSupport.createClassLoader(directoryPath); + return new DirectorySource(directoryPath, classLoader); + } catch (MalformedURLException e) { + return null; + } + } + + @Override + public boolean supports(String type) { + return TYPE.equals(type); + } +} diff -r 7a094360fe82 -r 033b9f74b930 hotspot/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/jar/JarFileSource.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/jar/JarFileSource.java Thu Jan 19 11:10:33 2017 +0100 @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.tools.jaotc.collect.jar; + +import jdk.tools.jaotc.collect.ClassSource; +import jdk.tools.jaotc.collect.FileSystemFinder; + +import java.nio.file.Path; +import java.util.function.BiConsumer; + +public class JarFileSource implements ClassSource { + private final Path jarFile; + private final Path jarRootPath; + private final ClassLoader classLoader; + + + public JarFileSource(Path jarFile, Path jarRootPath, ClassLoader classLoader) { + this.jarFile = jarFile; + this.jarRootPath = jarRootPath; + this.classLoader = classLoader; + } + + public void eachClass(BiConsumer consumer) { + FileSystemFinder finder = new FileSystemFinder(jarRootPath, ClassSource::pathIsClassFile); + + for (Path path : finder) { + consumer.accept(ClassSource.makeClassName(jarRootPath.relativize(path).normalize()), classLoader); + } + } + + @Override + public String toString() { + return "jar:" + jarFile.toString(); + } +} diff -r 7a094360fe82 -r 033b9f74b930 hotspot/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/jar/JarSourceProvider.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/jar/JarSourceProvider.java Thu Jan 19 11:10:33 2017 +0100 @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.tools.jaotc.collect.jar; + +import jdk.tools.jaotc.collect.ClassSource; +import jdk.tools.jaotc.collect.FileSupport; +import jdk.tools.jaotc.collect.SearchPath; +import jdk.tools.jaotc.collect.SourceProvider; + +import java.net.MalformedURLException; +import java.nio.file.FileSystem; +import java.nio.file.FileSystems; +import java.nio.file.Path; +import java.nio.file.ProviderNotFoundException; + +public class JarSourceProvider implements SourceProvider { + private final FileSystem fileSystem; + private final FileSupport fileSupport; + public final static String TYPE = "jar"; + + public JarSourceProvider() { + this(new FileSupport()); + } + + public JarSourceProvider(FileSupport fileSupport) { + this.fileSupport = fileSupport; + fileSystem = FileSystems.getDefault(); + } + + @Override + public ClassSource findSource(String name, SearchPath searchPath) { + Path fileName = fileSystem.getPath(name); + Path jarFile = searchPath.find(fileSystem, fileName); + + if (!validPath(jarFile)) { + return null; + } + + return createSource(jarFile); + } + + private ClassSource createSource(Path jarFile) { + try { + Path jarRootPath = fileSupport.getJarFileSystemRoot(jarFile); + if (jarRootPath == null) { + return null; + } + ClassLoader classLoader = fileSupport.createClassLoader(jarFile); + return new JarFileSource(jarFile, jarRootPath, classLoader); + } catch (ProviderNotFoundException | MalformedURLException e) { + } + return null; + } + + @Override + public boolean supports(String type) { + return TYPE.equals(type); + } + + private boolean validPath(Path jarFile) { + return jarFile != null && !fileSupport.isDirectory(jarFile); + } +} diff -r 7a094360fe82 -r 033b9f74b930 hotspot/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/module/ModuleSource.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/module/ModuleSource.java Thu Jan 19 11:10:33 2017 +0100 @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.tools.jaotc.collect.module; + +import jdk.tools.jaotc.collect.ClassSource; +import jdk.tools.jaotc.collect.FileSystemFinder; + +import java.nio.file.Path; +import java.util.function.BiConsumer; + +public class ModuleSource implements ClassSource { + private final Path modulePath; + private final ClassLoader classLoader; + + public ModuleSource(Path modulePath, ClassLoader classLoader) { + this.modulePath = modulePath; + this.classLoader = classLoader; + } + + @Override + public void eachClass(BiConsumer consumer) { + FileSystemFinder finder = new FileSystemFinder(modulePath, ClassSource::pathIsClassFile); + + for (Path path : finder) { + consumer.accept(ClassSource.makeClassName(modulePath.relativize(path).normalize()), classLoader); + } + } + + public Path getModulePath() { + return modulePath; + } + + @Override + public String toString() { + return "module:" + modulePath.toString(); + } +} diff -r 7a094360fe82 -r 033b9f74b930 hotspot/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/module/ModuleSourceProvider.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/module/ModuleSourceProvider.java Thu Jan 19 11:10:33 2017 +0100 @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.tools.jaotc.collect.module; + +import jdk.tools.jaotc.collect.ClassSource; +import jdk.tools.jaotc.collect.FileSupport; +import jdk.tools.jaotc.collect.SearchPath; +import jdk.tools.jaotc.collect.SourceProvider; + +import java.io.IOException; +import java.net.URI; +import java.nio.file.FileSystem; +import java.nio.file.FileSystems; +import java.nio.file.Path; + +public class ModuleSourceProvider implements SourceProvider { + private final FileSystem fileSystem; + private final ClassLoader classLoader; + private final FileSupport fileSupport; + public final static String TYPE = "module"; + + public ModuleSourceProvider() { + this(FileSystems.getFileSystem(URI.create("jrt:/")), ClassLoader.getSystemClassLoader(), new FileSupport()); + } + + public ModuleSourceProvider(FileSystem fileSystem, ClassLoader classLoader, FileSupport fileSupport) { + this.fileSystem = fileSystem; + this.classLoader = classLoader; + this.fileSupport = fileSupport; + } + + @Override + public ClassSource findSource(String name, SearchPath searchPath) { + Path path = fileSystem.getPath(name); + Path dir = fileSystem.getPath("modules"); + + if (dir == null || !fileSupport.isDirectory(dir)) { + return null; + } + + Path found = findModuleDirectory(dir, path); + + if (found == null) { + return null; + } + + return new ModuleSource(found, classLoader); + } + + private Path findModuleDirectory(Path root, Path path) { + try { + return fileSupport.getSubDirectory(fileSystem, root, path); + } catch (IOException e) { + throw new InternalError(e); + } + } + + @Override + public boolean supports(String type) { + return TYPE.equals(type); + } +} diff -r 7a094360fe82 -r 033b9f74b930 hotspot/test/compiler/aot/AotCompiler.java --- a/hotspot/test/compiler/aot/AotCompiler.java Thu Jan 19 10:30:37 2017 +0100 +++ b/hotspot/test/compiler/aot/AotCompiler.java Thu Jan 19 11:10:33 2017 +0100 @@ -69,7 +69,7 @@ extraopts.add("-classpath"); extraopts.add(Utils.TEST_CLASS_PATH + File.pathSeparator + Utils.TEST_SRC); if (className != null && libName != null) { - OutputAnalyzer oa = launchCompiler(libName, className + ".class", extraopts, compileList); + OutputAnalyzer oa = launchCompiler(libName, className, extraopts, compileList); oa.shouldHaveExitValue(0); } else { printUsage(); @@ -100,6 +100,7 @@ args.add("--compile-commands"); args.add(file.toString()); } + args.add("--classname"); args.add(item); return launchJaotc(args, extraopts); } diff -r 7a094360fe82 -r 033b9f74b930 hotspot/test/compiler/aot/cli/jaotc/ClasspathOptionTest.java --- a/hotspot/test/compiler/aot/cli/jaotc/ClasspathOptionTest.java Thu Jan 19 10:30:37 2017 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,63 +0,0 @@ -/* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/* - * @test - * @library / /test/lib /testlibrary - * @modules java.base/jdk.internal.misc - * @requires vm.bits == "64" & os.arch == "amd64" & os.family == "linux" - * @build compiler.aot.cli.jaotc.ClasspathOptionTest - * @run driver ClassFileInstaller compiler.aot.cli.jaotc.data.HelloWorldOne - * @run driver compiler.aot.cli.jaotc.ClasspathOptionTest - * @summary check jaotc can compile class from classpath - */ - -package compiler.aot.cli.jaotc; - -import compiler.aot.cli.jaotc.data.HelloWorldOne; -import java.io.File; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import jdk.test.lib.Asserts; -import jdk.test.lib.process.OutputAnalyzer; - -public class ClasspathOptionTest { - public static void main(String[] args) { - Path cp = Paths.get("testClasspath"); - try { - Files.createDirectory(cp); - Files.move(Paths.get("compiler"), cp.resolve("compiler")); - } catch (IOException e) { - throw new Error("TESTBUG: can't create test data " + e, e); - } - OutputAnalyzer oa = JaotcTestHelper.compileLibrary("--classpath", cp.toString(), - JaotcTestHelper.getClassAotCompilationName(HelloWorldOne.class)); - oa.shouldHaveExitValue(0); - File compiledLibrary = new File(JaotcTestHelper.DEFAULT_LIB_PATH); - Asserts.assertTrue(compiledLibrary.exists(), "Compiled library file missing"); - Asserts.assertGT(compiledLibrary.length(), 0L, "Unexpected compiled library size"); - JaotcTestHelper.checkLibraryUsage(HelloWorldOne.class.getName()); - } -} diff -r 7a094360fe82 -r 033b9f74b930 hotspot/test/compiler/aot/cli/jaotc/ClasspathOptionUnknownClassTest.java --- a/hotspot/test/compiler/aot/cli/jaotc/ClasspathOptionUnknownClassTest.java Thu Jan 19 10:30:37 2017 +0100 +++ b/hotspot/test/compiler/aot/cli/jaotc/ClasspathOptionUnknownClassTest.java Thu Jan 19 11:10:33 2017 +0100 @@ -39,7 +39,7 @@ public class ClasspathOptionUnknownClassTest { public static void main(String[] args) { - OutputAnalyzer oa = JaotcTestHelper.compileLibrary("HelloWorldOne.class"); + OutputAnalyzer oa = JaotcTestHelper.compileLibrary("--classname", "HelloWorldOne"); Asserts.assertNE(oa.getExitValue(), 0, "Unexpected compilation exit code"); File compiledLibrary = new File(JaotcTestHelper.DEFAULT_LIB_PATH); Asserts.assertFalse(compiledLibrary.exists(), "Compiler library unexpectedly exists"); diff -r 7a094360fe82 -r 033b9f74b930 hotspot/test/compiler/aot/cli/jaotc/CompileClassTest.java --- a/hotspot/test/compiler/aot/cli/jaotc/CompileClassTest.java Thu Jan 19 10:30:37 2017 +0100 +++ b/hotspot/test/compiler/aot/cli/jaotc/CompileClassTest.java Thu Jan 19 11:10:33 2017 +0100 @@ -41,7 +41,7 @@ public class CompileClassTest { public static void main(String[] args) { - OutputAnalyzer oa = JaotcTestHelper.compileLibrary(JaotcTestHelper + OutputAnalyzer oa = JaotcTestHelper.compileLibrary("--classname", JaotcTestHelper .getClassAotCompilationName(HelloWorldOne.class)); oa.shouldHaveExitValue(0); File compiledLibrary = new File(JaotcTestHelper.DEFAULT_LIB_PATH); diff -r 7a094360fe82 -r 033b9f74b930 hotspot/test/compiler/aot/cli/jaotc/CompileDirectoryTest.java --- a/hotspot/test/compiler/aot/cli/jaotc/CompileDirectoryTest.java Thu Jan 19 10:30:37 2017 +0100 +++ b/hotspot/test/compiler/aot/cli/jaotc/CompileDirectoryTest.java Thu Jan 19 11:10:33 2017 +0100 @@ -42,7 +42,7 @@ public class CompileDirectoryTest { public static void main(String[] args) { - OutputAnalyzer oa =JaotcTestHelper.compileLibrary("."); + OutputAnalyzer oa =JaotcTestHelper.compileLibrary("--directory", "."); oa.shouldHaveExitValue(0); File compiledLibrary = new File(JaotcTestHelper.DEFAULT_LIB_PATH); Asserts.assertTrue(compiledLibrary.exists(), "Compiled library file missing"); diff -r 7a094360fe82 -r 033b9f74b930 hotspot/test/compiler/aot/cli/jaotc/CompileJarTest.java --- a/hotspot/test/compiler/aot/cli/jaotc/CompileJarTest.java Thu Jan 19 10:30:37 2017 +0100 +++ b/hotspot/test/compiler/aot/cli/jaotc/CompileJarTest.java Thu Jan 19 11:10:33 2017 +0100 @@ -48,7 +48,7 @@ public static void main(String[] args) { createJar(); - OutputAnalyzer oa = JaotcTestHelper.compileLibrary(JAR_NAME); + OutputAnalyzer oa = JaotcTestHelper.compileLibrary("--jar", JAR_NAME); oa.shouldHaveExitValue(0); File compiledLibrary = new File(JaotcTestHelper.DEFAULT_LIB_PATH); Asserts.assertTrue(compiledLibrary.exists(), "Compiled library file missing"); diff -r 7a094360fe82 -r 033b9f74b930 hotspot/test/compiler/aot/cli/jaotc/JaotcTestHelper.java --- a/hotspot/test/compiler/aot/cli/jaotc/JaotcTestHelper.java Thu Jan 19 10:30:37 2017 +0100 +++ b/hotspot/test/compiler/aot/cli/jaotc/JaotcTestHelper.java Thu Jan 19 11:10:33 2017 +0100 @@ -71,7 +71,11 @@ } } - public static String getClassAotCompilationName(Class classToCompile) { + public static String getClassAotCompilationFilename(Class classToCompile) { return classToCompile.getName().replaceAll("\\.", File.separator) + ".class"; } + + public static String getClassAotCompilationName(Class classToCompile) { + return classToCompile.getName(); + } } diff -r 7a094360fe82 -r 033b9f74b930 hotspot/test/compiler/aot/cli/jaotc/ListOptionNotExistingTest.java --- a/hotspot/test/compiler/aot/cli/jaotc/ListOptionNotExistingTest.java Thu Jan 19 10:30:37 2017 +0100 +++ b/hotspot/test/compiler/aot/cli/jaotc/ListOptionNotExistingTest.java Thu Jan 19 11:10:33 2017 +0100 @@ -45,7 +45,7 @@ public static void main(String[] args) { OutputAnalyzer oa = JaotcTestHelper.compileLibrary("--compile-commands", "./notExisting.list", - COMPILE_ITEM); + "--classname", COMPILE_ITEM); int exitCode = oa.getExitValue(); Asserts.assertNE(exitCode, 0, "Unexpected compilation exit code"); File compiledLibrary = new File(JaotcTestHelper.DEFAULT_LIB_PATH); diff -r 7a094360fe82 -r 033b9f74b930 hotspot/test/compiler/aot/cli/jaotc/ListOptionTest.java --- a/hotspot/test/compiler/aot/cli/jaotc/ListOptionTest.java Thu Jan 19 10:30:37 2017 +0100 +++ b/hotspot/test/compiler/aot/cli/jaotc/ListOptionTest.java Thu Jan 19 11:10:33 2017 +0100 @@ -66,7 +66,7 @@ throw new Error("TESTBUG: can't write list file " + e, e); } OutputAnalyzer oa = JaotcTestHelper.compileLibrary("--compile-commands", COMPILE_COMMAND_FILE.toString(), - JaotcTestHelper.getClassAotCompilationName(HelloWorldOne.class)); + "--classname", JaotcTestHelper.getClassAotCompilationName(HelloWorldOne.class)); oa.shouldHaveExitValue(0); File compiledLibrary = new File(JaotcTestHelper.DEFAULT_LIB_PATH); Asserts.assertTrue(compiledLibrary.exists(), "Compiled library file missing"); diff -r 7a094360fe82 -r 033b9f74b930 hotspot/test/compiler/aot/cli/jaotc/ListOptionWrongFileTest.java --- a/hotspot/test/compiler/aot/cli/jaotc/ListOptionWrongFileTest.java Thu Jan 19 10:30:37 2017 +0100 +++ b/hotspot/test/compiler/aot/cli/jaotc/ListOptionWrongFileTest.java Thu Jan 19 11:10:33 2017 +0100 @@ -49,12 +49,15 @@ private static final String COMPILE_ITEM = JaotcTestHelper.getClassAotCompilationName(HelloWorldOne.class); + private static final String COMPILE_FILE + = JaotcTestHelper.getClassAotCompilationFilename(HelloWorldOne.class); + public static void main(String[] args) { // expecting wrong file to be read but no compilation directive recognized, so, all compiled - OutputAnalyzer oa = JaotcTestHelper.compileLibrary("--compile-commands", COMPILE_ITEM, COMPILE_ITEM); + OutputAnalyzer oa = JaotcTestHelper.compileLibrary("--compile-commands", COMPILE_FILE, "--classname", COMPILE_ITEM); oa.shouldHaveExitValue(0); File compiledLibrary = new File(JaotcTestHelper.DEFAULT_LIB_PATH); - Asserts.assertTrue(compiledLibrary.exists(), "Expecte compiler library to exist"); + Asserts.assertTrue(compiledLibrary.exists(), "Expected compiler library to exist"); JaotcTestHelper.checkLibraryUsage(HelloWorldOne.class.getName(), EXPECTED, null); } } diff -r 7a094360fe82 -r 033b9f74b930 hotspot/test/compiler/aot/jdk.tools.jaotc.test/src/jdk/tools/jaotc/test/collect/ClassSearchTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/aot/jdk.tools.jaotc.test/src/jdk/tools/jaotc/test/collect/ClassSearchTest.java Thu Jan 19 11:10:33 2017 +0100 @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.tools.jaotc.test.collect; + + +import jdk.tools.jaotc.LoadedClass; +import org.junit.Assert; +import org.junit.Test; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.function.BiConsumer; + +public class ClassSearchTest { + @Test(expected = InternalError.class) + public void itShouldThrowExceptionIfNoProvidersAvailable() { + ClassSearch target = new ClassSearch(); + SearchPath searchPath = new SearchPath(); + target.search(list("foo"), searchPath); + } + + @Test + public void itShouldFindAProviderForEachEntry() { + Set searched = new HashSet<>(); + ClassSearch target = new ClassSearch(); + target.addProvider(new SourceProvider() { + @Override + public ClassSource findSource(String name, SearchPath searchPath) { + searched.add(name); + return new NoopSource(); + } + }); + target.search(list("foo", "bar", "foobar"), null); + Assert.assertEquals(hashset("foo", "bar", "foobar"), searched); + } + + @Test + public void itShouldSearchAllProviders() { + Set visited = new HashSet<>(); + ClassSearch target = new ClassSearch(); + target.addProvider((name, searchPath) -> { + visited.add("1"); + return null; + }); + target.addProvider((name, searchPath) -> { + visited.add("2"); + return null; + }); + + try { + target.search(list("foo"), null); + } catch (InternalError e) { + // throws because no provider gives a source + } + + Assert.assertEquals(hashset("1", "2"), visited); + } + + @Test + public void itShouldTryToLoadSaidClassFromClassLoader() { + Set loaded = new HashSet<>(); + + ClassSearch target = new ClassSearch(); + target.addProvider(new SourceProvider() { + @Override + public ClassSource findSource(String name, SearchPath searchPath) { + return new ClassSource() { + @Override + public void eachClass(BiConsumer consumer) { + consumer.accept("foo.Bar", new ClassLoader() { + @Override + public Class loadClass(String name) throws ClassNotFoundException { + loaded.add(name); + return null; + } + }); + } + }; + } + }); + + java.util.List search = target.search(list("/tmp/something"), null); + Assert.assertEquals(list(new LoadedClass("foo.Bar", null)), search); + } + + @Test(expected = InternalError.class) + public void itShouldThrowInternalErrorWhenClassLoaderFails() { + ClassLoader classLoader = new ClassLoader() { + @Override + public Class loadClass(String name1) throws ClassNotFoundException { + throw new ClassNotFoundException("failed to find " + name1); + } + }; + + ClassSearch target = new ClassSearch(); + target.addProvider((name, searchPath) -> consumer -> consumer.accept("foo.Bar", classLoader)); + target.search(list("foobar"), null); + } + + private List list(T... entries) { + List list = new ArrayList(); + for (T entry : entries) { + list.add(entry); + } + return list; + } + + private Set hashset(T... entries) { + Set set = new HashSet(); + for (T entry : entries) { + set.add(entry); + } + return set; + } + + private static class NoopSource implements ClassSource { + @Override + public void eachClass(BiConsumer consumer) { + } + } +} diff -r 7a094360fe82 -r 033b9f74b930 hotspot/test/compiler/aot/jdk.tools.jaotc.test/src/jdk/tools/jaotc/test/collect/ClassSourceTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/aot/jdk.tools.jaotc.test/src/jdk/tools/jaotc/test/collect/ClassSourceTest.java Thu Jan 19 11:10:33 2017 +0100 @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.tools.jaotc.test.collect; + +import org.junit.Assert; +import org.junit.Test; + +import java.nio.file.Paths; + +import static jdk.tools.jaotc.collect.ClassSource.makeClassName; + +public class ClassSourceTest { + @Test(expected=IllegalArgumentException.class) + public void itShouldThrowExceptionIfPathDoesntEndWithClass() { + makeClassName(Paths.get("Bar.clazz")); + } + + @Test + public void itShouldReplaceSlashesWithDots() { + Assert.assertEquals("foo.Bar", makeClassName(Paths.get("foo/Bar.class"))); + } + + @Test + public void itShouldStripLeadingSlash() { + Assert.assertEquals("Hello", makeClassName(Paths.get("/Hello.class"))); + } + + @Test + public void itShouldReplaceMultipleDots() { + Assert.assertEquals("some.foo.bar.FooBar", makeClassName(Paths.get("/some/foo/bar/FooBar.class"))); + } +} diff -r 7a094360fe82 -r 033b9f74b930 hotspot/test/compiler/aot/jdk.tools.jaotc.test/src/jdk/tools/jaotc/test/collect/FakeFileSupport.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/aot/jdk.tools.jaotc.test/src/jdk/tools/jaotc/test/collect/FakeFileSupport.java Thu Jan 19 11:10:33 2017 +0100 @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.tools.jaotc.test.collect; + +import java.net.MalformedURLException; +import java.nio.file.Path; +import java.util.HashSet; +import java.util.Set; + +public class FakeFileSupport extends FileSupport { + private final Set exists = new HashSet<>(); + private final Set directories = new HashSet<>(); + + private final Set checkedExists = new HashSet<>(); + private final Set checkedDirectory = new HashSet<>(); + private final Set checkedJarFileSystemRoots = new HashSet<>(); + private final Set classloaderPaths = new HashSet<>(); + + private Path jarFileSystemRoot = null; + private final ClassLoader classLoader; + + public FakeFileSupport(Set existing, Set directories) { + this.exists.addAll(existing); + this.directories.addAll(directories); + + classLoader = new ClassLoader() { + @Override + public Class loadClass(String name) throws ClassNotFoundException { + return null; + } + }; + } + + public void setJarFileSystemRoot(Path path) { + jarFileSystemRoot = path; + } + + @Override + public boolean exists(Path path) { + checkedExists.add(path.toString()); + return exists.contains(path.toString()); + } + + @Override + public boolean isDirectory(Path path) { + checkedDirectory.add(path.toString()); + return directories.contains(path.toString()); + } + + @Override + public ClassLoader createClassLoader(Path path) throws MalformedURLException { + classloaderPaths.add(path.toString()); + return classLoader; + } + + @Override + public Path getJarFileSystemRoot(Path jarFile) { + checkedJarFileSystemRoots.add(jarFile.toString()); + return jarFileSystemRoot; + } + + @Override + public boolean isAbsolute(Path entry) { + return entry.toString().startsWith("/"); + } + + public void addExist(String name) { + exists.add(name); + } + + public void addDirectory(String name) { + directories.add(name); + } + + public Set getCheckedExists() { + return checkedExists; + } + + public Set getCheckedDirectory() { + return checkedDirectory; + } + + public Set getCheckedJarFileSystemRoots() { + return checkedJarFileSystemRoots; + } + + public Set getClassloaderPaths() { + return classloaderPaths; + } +} diff -r 7a094360fe82 -r 033b9f74b930 hotspot/test/compiler/aot/jdk.tools.jaotc.test/src/jdk/tools/jaotc/test/collect/FakeSearchPath.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/aot/jdk.tools.jaotc.test/src/jdk/tools/jaotc/test/collect/FakeSearchPath.java Thu Jan 19 11:10:33 2017 +0100 @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.tools.jaotc.test.collect; + +import java.nio.file.FileSystem; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Set; + +import static jdk.tools.jaotc.test.collect.Utils.set; + +public class FakeSearchPath extends SearchPath { + private Path path = null; + public Set entries = set(); + + public FakeSearchPath(String name) { + if (name != null) { + path = Paths.get(name); + } + } + + @Override + public Path find(FileSystem fileSystem, Path entry, String... defaults) { + entries.add(entry.toString()); + return path; + } +} diff -r 7a094360fe82 -r 033b9f74b930 hotspot/test/compiler/aot/jdk.tools.jaotc.test/src/jdk/tools/jaotc/test/collect/SearchPathTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/aot/jdk.tools.jaotc.test/src/jdk/tools/jaotc/test/collect/SearchPathTest.java Thu Jan 19 11:10:33 2017 +0100 @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.tools.jaotc.test.collect; + +import org.junit.Before; +import org.junit.Test; + +import java.nio.file.FileSystem; +import java.nio.file.FileSystems; +import java.nio.file.Path; +import java.nio.file.Paths; + +import static jdk.tools.jaotc.test.collect.Utils.set; +import static org.junit.Assert.*; + +public class SearchPathTest { + private FakeFileSupport fileSupport; + private FileSystem fs; + + @Before + public void setUp() throws Exception { + fs = FileSystems.getDefault(); + } + + @Test + public void itShouldUsePathIfPathIsAbsoluteAndExisting() { + fileSupport = new FakeFileSupport(set("/foo"), set()); + SearchPath target = new SearchPath(fileSupport); + Path foo = Paths.get("/foo"); + Path result = target.find(fs, foo); + assertSame(result, foo); + } + + @Test + public void itShouldReturnNullIfPathIsAbsoluteAndNonExisting() { + fileSupport = new FakeFileSupport(set(), set()); + SearchPath target = new SearchPath(fileSupport); + Path result = target.find(fs, Paths.get("/bar")); + assertNull(result); + } + + @Test + public void itShouldUseRelativeExisting() { + fileSupport = new FakeFileSupport(set("hello", "tmp/hello", "search/hello"), set()); + SearchPath target = new SearchPath(fileSupport); + target.add("search"); + Path hello = Paths.get("hello"); + Path result = target.find(fs, hello, "tmp"); + assertSame(result, hello); + } + + @Test + public void itShouldSearchDefaultsBeforeSearchPaths() { + fileSupport = new FakeFileSupport(set("bar/foobar"), set()); + SearchPath target = new SearchPath(fileSupport); + Path result = target.find(fs, Paths.get("foobar"), "default1", "bar"); + assertEquals("bar/foobar", result.toString()); + assertEquals(set("foobar", "default1/foobar", "bar/foobar"), fileSupport.getCheckedExists()); + } + + @Test + public void itShouldUseSearchPathsIfNotInDefaults() { + fileSupport = new FakeFileSupport(set("bar/tmp/foobar"), set()); + SearchPath target = new SearchPath(fileSupport); + target.add("foo/tmp", "bar/tmp"); + + Path result = target.find(fs, Paths.get("foobar"), "foo", "bar"); + assertEquals("bar/tmp/foobar", result.toString()); + assertEquals(set("foobar", "foo/foobar", "bar/foobar", "bar/tmp/foobar", "foo/tmp/foobar"), fileSupport.getCheckedExists()); + } + + @Test + public void itShouldReturnNullIfNoExistingPathIsFound() { + fileSupport = new FakeFileSupport(set(), set()); + SearchPath target = new SearchPath(fileSupport); + target.add("dir1", "dir2"); + + Path result = target.find(fs, Paths.get("entry"), "dir3", "dir4"); + assertNull(result); + assertEquals(set("entry", "dir1/entry", "dir2/entry", "dir3/entry", "dir4/entry"), fileSupport.getCheckedExists()); + } +} diff -r 7a094360fe82 -r 033b9f74b930 hotspot/test/compiler/aot/jdk.tools.jaotc.test/src/jdk/tools/jaotc/test/collect/Utils.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/aot/jdk.tools.jaotc.test/src/jdk/tools/jaotc/test/collect/Utils.java Thu Jan 19 11:10:33 2017 +0100 @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.tools.jaotc.test.collect; + +import java.util.HashSet; +import java.util.Set; + +public class Utils { + public static Set set(T... entries) { + Set set = new HashSet(); + for (T entry : entries) { + set.add(entry); + } + return set; + } +} diff -r 7a094360fe82 -r 033b9f74b930 hotspot/test/compiler/aot/jdk.tools.jaotc.test/src/jdk/tools/jaotc/test/collect/directory/DirectorySourceProviderTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/aot/jdk.tools.jaotc.test/src/jdk/tools/jaotc/test/collect/directory/DirectorySourceProviderTest.java Thu Jan 19 11:10:33 2017 +0100 @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.tools.jaotc.test.collect.directory; + +import jdk.tools.jaotc.collect.ClassSource; +import jdk.tools.jaotc.test.collect.FakeFileSupport; +import jdk.tools.jaotc.test.collect.FileSupport; +import org.junit.Assert; +import org.junit.Test; + +import java.net.MalformedURLException; +import java.nio.file.Path; +import java.util.Set; + +import static jdk.tools.jaotc.test.collect.Utils.set; + +public class DirectorySourceProviderTest { + @Test + public void itShouldReturnNullForNonExistantPath() { + DirectorySourceProvider target = new DirectorySourceProvider(new FakeFileSupport(set(), set())); + ClassSource result = target.findSource("hello", null); + Assert.assertNull(result); + } + + @Test + public void itShouldReturnNullForNonDirectory() { + DirectorySourceProvider target = new DirectorySourceProvider(new FakeFileSupport(set("foobar"), set())); + ClassSource result = target.findSource("foobar", null); + Assert.assertNull(result); + } + + @Test + public void itShouldReturnNullForMalformedURI() { + Set visited = set(); + DirectorySourceProvider target = new DirectorySourceProvider(new FakeFileSupport(set("foobar"), set("foobar")) { + @Override + public ClassLoader createClassLoader(Path path) throws MalformedURLException { + visited.add("1"); + throw new MalformedURLException("..."); + } + }); + ClassSource result = target.findSource("foobar", null); + Assert.assertNull(result); + Assert.assertEquals(set("1"), visited); + } + + @Test + public void itShouldCreateSourceIfNameExistsAndIsADirectory() { + FileSupport fileSupport = new FakeFileSupport(set("foo"), set("foo")); + DirectorySourceProvider target = new DirectorySourceProvider(fileSupport); + ClassSource foo = target.findSource("foo", null); + Assert.assertNotNull(foo); + Assert.assertEquals("directory:foo", foo.toString()); + } + +} diff -r 7a094360fe82 -r 033b9f74b930 hotspot/test/compiler/aot/jdk.tools.jaotc.test/src/jdk/tools/jaotc/test/collect/jar/JarSourceProviderTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/aot/jdk.tools.jaotc.test/src/jdk/tools/jaotc/test/collect/jar/JarSourceProviderTest.java Thu Jan 19 11:10:33 2017 +0100 @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.tools.jaotc.test.collect.jar; + +import jdk.tools.jaotc.collect.ClassSource; +import jdk.tools.jaotc.test.collect.FakeFileSupport; +import jdk.tools.jaotc.test.collect.FakeSearchPath; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.ProviderNotFoundException; +import java.util.Set; + +import static jdk.tools.jaotc.test.collect.Utils.set; + +public class JarSourceProviderTest { + + private FakeFileSupport fileSupport; + private JarSourceProvider target; + + @Before + public void setUp() throws Exception { + fileSupport = new FakeFileSupport(set(), set()); + target = new JarSourceProvider(fileSupport); + } + + @Test + public void itShouldUseSearchPathToFindPath() { + Set visited = set(); + JarSourceProvider target = new JarSourceProvider(fileSupport); + FakeSearchPath searchPath = new FakeSearchPath(null); + ClassSource source = target.findSource("hello", searchPath); + + Assert.assertEquals(set("hello"), searchPath.entries); + } + + @Test + public void itShouldReturnNullIfPathIsNull() { + JarSourceProvider target = new JarSourceProvider(fileSupport); + ClassSource source = target.findSource("foobar", new FakeSearchPath(null)); + Assert.assertNull(source); + } + + @Test + public void itShouldReturnNullIfPathIsDirectory() { + fileSupport.addDirectory("hello/foobar"); + ClassSource source = target.findSource("foobar", new FakeSearchPath("hello/foobar")); + + Assert.assertNull(source); + Assert.assertEquals(set("hello/foobar"), fileSupport.getCheckedDirectory()); + } + + @Test + public void itShouldReturnNullIfUnableToMakeJarFileSystem() { + fileSupport.setJarFileSystemRoot(null); + ClassSource result = target.findSource("foobar", new FakeSearchPath("foo/bar")); + + Assert.assertEquals(set("foo/bar"), fileSupport.getCheckedJarFileSystemRoots()); + Assert.assertNull(result); + } + + @Test + public void itShouldReturnNullIfNotValidJarProvider() { + fileSupport = new FakeFileSupport(set(), set()) { + + @Override + public Path getJarFileSystemRoot(Path jarFile) { + super.getJarFileSystemRoot(jarFile); + throw new ProviderNotFoundException(); + } + }; + fileSupport.setJarFileSystemRoot(null); + target = new JarSourceProvider(fileSupport); + + ClassSource result = target.findSource("foobar", new FakeSearchPath("foo/bar")); + + Assert.assertEquals(set("foo/bar"), fileSupport.getCheckedJarFileSystemRoots()); + Assert.assertNull(result); + } + + @Test + public void itShouldReturnSourceWhenAllIsValid() { + fileSupport.setJarFileSystemRoot(Paths.get("some/bar")); + ClassSource result = target.findSource("foobar", new FakeSearchPath("this/bar")); + + Assert.assertEquals(set("this/bar"), fileSupport.getClassloaderPaths()); + Assert.assertEquals("jar:this/bar", result.toString()); + } +} diff -r 7a094360fe82 -r 033b9f74b930 hotspot/test/compiler/aot/jdk.tools.jaotc.test/src/jdk/tools/jaotc/test/collect/module/ModuleSourceProviderTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/aot/jdk.tools.jaotc.test/src/jdk/tools/jaotc/test/collect/module/ModuleSourceProviderTest.java Thu Jan 19 11:10:33 2017 +0100 @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.tools.jaotc.test.collect.module; + +import jdk.tools.jaotc.*; +import jdk.tools.jaotc.test.collect.FakeSearchPath; +import jdk.tools.jaotc.test.collect.Utils; +import org.junit.Before; +import org.junit.Test; + +import java.nio.file.FileSystems; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; + +public class ModuleSourceProviderTest { + private ClassLoader classLoader; + private ModuleSourceProvider target; + + @Before + public void setUp() { + classLoader = new FakeClassLoader(); + target = new ModuleSourceProvider(FileSystems.getDefault(), classLoader); + } + + @Test + public void itShouldUseSearchPath() { + FakeSearchPath searchPath = new FakeSearchPath("blah/java.base"); + ModuleSource source = (ModuleSource) target.findSource("java.base", searchPath); + assertEquals(Utils.set("java.base"), searchPath.entries); + assertEquals("blah/java.base", source.getModulePath().toString()); + assertEquals("module:blah/java.base", source.toString()); + } + + @Test + public void itShouldReturnNullIfSearchPathReturnsNull() { + FakeSearchPath searchPath = new FakeSearchPath(null); + ModuleSource source = (ModuleSource) target.findSource("jdk.base", searchPath); + assertEquals(Utils.set("jdk.base"), searchPath.entries); + assertNull(source); + } + + private static class FakeClassLoader extends ClassLoader { + @Override + public Class loadClass(String name) throws ClassNotFoundException { + return null; + } + } +} diff -r 7a094360fe82 -r 033b9f74b930 hotspot/test/compiler/aot/verification/ClassAndLibraryNotMatchTest.java --- a/hotspot/test/compiler/aot/verification/ClassAndLibraryNotMatchTest.java Thu Jan 19 10:30:37 2017 +0100 +++ b/hotspot/test/compiler/aot/verification/ClassAndLibraryNotMatchTest.java Thu Jan 19 11:10:33 2017 +0100 @@ -85,9 +85,8 @@ } private void compileAotLibrary() { - AotCompiler.launchCompiler(LIB_NAME, HELLO_WORLD_CLASS_NAME + ".class", - Arrays.asList("-classpath", Utils.TEST_CLASS_PATH + File.pathSeparator - + Utils.TEST_SRC), null); + AotCompiler.launchCompiler(LIB_NAME, HELLO_WORLD_CLASS_NAME, + Arrays.asList("-classpath", Utils.TEST_CLASS_PATH + ":."), null); } private void runAndCheckHelloWorld(String checkString) { diff -r 7a094360fe82 -r 033b9f74b930 hotspot/test/compiler/aot/verification/vmflags/BasicFlagsChange.java --- a/hotspot/test/compiler/aot/verification/vmflags/BasicFlagsChange.java Thu Jan 19 10:30:37 2017 +0100 +++ b/hotspot/test/compiler/aot/verification/vmflags/BasicFlagsChange.java Thu Jan 19 11:10:33 2017 +0100 @@ -76,7 +76,7 @@ extraOpts.add(option); extraOpts.add("-classpath"); extraOpts.add(Utils.TEST_CLASS_PATH + File.pathSeparator + Utils.TEST_SRC); - AotCompiler.launchCompiler(libName, className + ".class", extraOpts, null); + AotCompiler.launchCompiler(libName, className, extraOpts, null); } private static void runAndCheck(String option, String libName,