# HG changeset patch # Parent a0071ded705e1688a09e35552637464ee515977a # User mhaupt jlink review changes diff -r a0071ded705e src/jdk.jlink/share/classes/jdk/tools/jlink/Jlink.java --- a/src/jdk.jlink/share/classes/jdk/tools/jlink/Jlink.java Mon Mar 07 11:25:26 2016 +0100 +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/Jlink.java Mon Mar 14 13:23:57 2016 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 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 @@ -32,6 +32,8 @@ import java.util.Map; import java.util.Objects; import java.util.Set; +import java.util.stream.Collectors; + import jdk.tools.jlink.internal.JlinkTask; import jdk.tools.jlink.plugin.Plugin; import jdk.tools.jlink.plugin.PluginContext; @@ -49,10 +51,10 @@ /** * Create a plugin. * - * @param name Plugin name + * @param name Plugin name. * @param configuration Plugin configuration. - * @param pluginsLayer Plugins Layer. null means boot layer. - * @return A new plugin or null if plugin is unknown. + * @param pluginsLayer Plugins layer. {@code null} means boot layer. + * @return A new plugin or {@code null} if plugin is unknown. */ public static Plugin newPlugin(String name, Map configuration, Layer pluginsLayer) { @@ -90,14 +92,14 @@ } /** - * Plugins configuration with a last sorter and an ImageBuilder. No - * sorting can occur after the last sorter plugin. The ImageBuilder is - * in charge to layout the image content on disk. + * Plugins configuration with a last sorter and an {@link ImageBuilder}. + * No sorting can occur after the last sorter plugin. The ImageBuilder is + * in charge of laying out the image content on disk. * * @param plugins List of transformer plugins. * @param imageBuilder Image builder. * @param lastSorterPluginName Name of last sorter plugin, no sorting - * can occur after it. + * can occur after it. */ public PluginsConfiguration(List plugins, ImageBuilder imageBuilder, String lastSorterPluginName) { @@ -105,15 +107,16 @@ } /** - * Plugins configuration with a last sorter and an ImageBuilder. No - * sorting can occur after the last sorter plugin. The ImageBuilder is - * in charge to layout the image content on disk. + * Plugins configuration with a last sorter, an {@link ImageBuilder}, + * and a {@link PluginContext}. No sorting can occur after the last + * sorter plugin. The ImageBuilder is in charge to layout the image + * content on disk. The PluginContext provides release properties. * * @param plugins List of transformer plugins. * @param imageBuilder Image builder. * @param lastSorterPluginName Name of last sorter plugin, no sorting + * can occur after it. * @param ctx the plugin context - * can occur after it. */ public PluginsConfiguration(List plugins, ImageBuilder imageBuilder, String lastSorterPluginName, @@ -157,13 +160,9 @@ public String toString() { StringBuilder builder = new StringBuilder(); builder.append("imagebuilder=").append(imageBuilder).append("\n"); - StringBuilder pluginsBuilder = new StringBuilder(); - for (Plugin p : plugins) { - pluginsBuilder.append(p).append(","); - } - builder.append("plugins=").append(pluginsBuilder).append("\n"); + builder.append(plugins.stream().map(Plugin::toString). + collect(Collectors.joining(",", "plugins=", "\n"))); builder.append("lastsorter=").append(lastSorterPluginName).append("\n"); - return builder.toString(); } } @@ -181,13 +180,13 @@ private final ByteOrder endian; /** - * jlink configuration, + * jlink configuration. * * @param output Output directory, must not exist. - * @param modulepaths Modules paths - * @param modules Root modules to resolve - * @param limitmods Limit the universe of observable modules - * @param endian Jimage byte order. Native order by default + * @param modulepaths Modules paths. + * @param modules Root modules to resolve. + * @param limitmods Limit the universe of observable modules. + * @param endian Jimage byte order. Native order by default. */ public JlinkConfiguration(Path output, List modulepaths, @@ -202,12 +201,12 @@ } /** - * jlink configuration, + * jlink configuration. * * @param output Output directory, must not exist. - * @param modulepaths Modules paths - * @param modules Root modules to resolve - * @param limitmods Limit the universe of observable modules + * @param modulepaths Modules paths. + * @param modules Root modules to resolve. + * @param limitmods Limit the universe of observable modules. */ public JlinkConfiguration(Path output, List modulepaths, @@ -255,33 +254,21 @@ @Override public String toString() { StringBuilder builder = new StringBuilder(); - builder.append("output=").append(output).append("\n"); - StringBuilder pathsBuilder = new StringBuilder(); - for (Path p : modulepaths) { - pathsBuilder.append(p).append(","); - } - builder.append("modulepaths=").append(pathsBuilder).append("\n"); - - StringBuilder modsBuilder = new StringBuilder(); - for (String p : modules) { - modsBuilder.append(p).append(","); - } - builder.append("modules=").append(modsBuilder).append("\n"); - - StringBuilder limitsBuilder = new StringBuilder(); - for (String p : limitmods) { - limitsBuilder.append(p).append(","); - } - builder.append("limitmodules=").append(limitsBuilder).append("\n"); + builder.append(modulepaths.stream().map(Path::toString). + collect(Collectors.joining(",", "modulepaths=", "\n"))); + builder.append(modules.stream(). + collect(Collectors.joining(",", "modules=", "\n"))); + builder.append(limitmods.stream(). + collect(Collectors.joining(",", "limitmods=", "\n"))); builder.append("endian=").append(endian).append("\n"); return builder.toString(); } } /** - * Jlink instance constructor, if a security manager is set, the jlink - * permission is checked. + * Jlink instance constructor. If a security manager is set, the + * {@linkplain JlinkPermission jlink permission} is checked. */ public Jlink() { if (System.getSecurityManager() != null) { @@ -293,8 +280,9 @@ /** * Build the image. * - * @param config Jlink config, must not be null. - * @throws PluginException + * @param config Jlink config, must not be {@code null}. + * @throws PluginException when any exception is thrown during image + * generation. */ public void build(JlinkConfiguration config) { build(config, null); @@ -303,9 +291,10 @@ /** * Build the image with a plugin configuration. * - * @param config Jlink config, must not be null. - * @param pluginsConfig Plugins config, can be null - * @throws PluginException + * @param config Jlink config, must not be {@code null}. + * @param pluginsConfig Plugins config, can be {@code null}. + * @throws PluginException when any exception is thrown during image + * generation. */ public void build(JlinkConfiguration config, PluginsConfiguration pluginsConfig) { Objects.requireNonNull(config); @@ -317,10 +306,10 @@ } /** - * Post process the image with a plugin configuration. + * Post-process the image with a plugin configuration. * * @param image Existing image. - * @param plugins Plugins cannot be null + * @param plugins Plugins, must not be {@code null}. */ public void postProcess(ExecutableImage image, List plugins) { Objects.requireNonNull(image); diff -r a0071ded705e src/jdk.jlink/share/classes/jdk/tools/jlink/JlinkPermission.java --- a/src/jdk.jlink/share/classes/jdk/tools/jlink/JlinkPermission.java Mon Mar 07 11:25:26 2016 +0100 +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/JlinkPermission.java Mon Mar 14 13:23:57 2016 +0100 @@ -27,9 +27,8 @@ import java.security.BasicPermission; /** - * The permission required to use jlink API. The permission target_name is - * "jlink". e.g.: permission jdk.tools.jlink.plugins.JlinkPermission "jlink"; - * + * The permission required to use the jlink API. The permission target_name is + * "jlink"; e.g., {@code permission jdk.tools.jlink.plugins.JlinkPermission "jlink";} */ public final class JlinkPermission extends BasicPermission { diff -r a0071ded705e src/jdk.jlink/share/classes/jdk/tools/jlink/builder/DefaultImageBuilder.java --- a/src/jdk.jlink/share/classes/jdk/tools/jlink/builder/DefaultImageBuilder.java Mon Mar 07 11:25:26 2016 +0100 +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/builder/DefaultImageBuilder.java Mon Mar 14 13:23:57 2016 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 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 @@ -53,6 +53,8 @@ import java.util.Optional; import java.util.Properties; import java.util.Set; +import java.util.stream.Collectors; + import jdk.tools.jlink.internal.BasicImageWriter; import jdk.tools.jlink.internal.plugins.FileCopierPlugin; import jdk.tools.jlink.internal.plugins.FileCopierPlugin.SymImageFile; @@ -61,13 +63,12 @@ import jdk.tools.jlink.plugin.Pool.ModuleData; /** - * * Default Image Builder. This builder creates the default runtime image layout. */ public class DefaultImageBuilder implements ImageBuilder { /** - * The default java executable Image. + * The default Java executable image. */ static class DefaultExecutableImage extends ExecutableImage { @@ -101,9 +102,9 @@ /** * Default image builder constructor. * - * @param genBom true, generates a bom file. + * @param genBom if {@code true}, the builder generates a bom file. * @param root The image root directory. - * @throws IOException + * @throws IOException when the output directory cannot be created. */ public DefaultImageBuilder(boolean genBom, Path root) throws IOException { Objects.requireNonNull(root); @@ -131,36 +132,20 @@ } private void addModules(Properties release, Set modules) throws IOException { - StringBuilder builder = new StringBuilder(); - int i = 0; - for (String m : modules) { - builder.append(m); - if (i < modules.size() - 1) { - builder.append(","); - } - i++; - } - release.setProperty("MODULES", builder.toString()); + release.setProperty("MODULES", modules.stream().collect(Collectors.joining(","))); } @Override public void storeFiles(Pool files, String bom, Properties release) { try { - for (ModuleData f : files.getContent()) { - if (!f.getType().equals(Pool.ModuleDataType.CLASS_OR_RESOURCE)) { - accept(f); - } - } - for (Module m : files.getModules()) { - // Only add modules that contain packages - if (!m.getAllPackages().isEmpty()) { - // Skip the fake module used by FileCopierPlugin when copying files. - if (m.getName().equals(FileCopierPlugin.FAKE_MODULE)) { - continue; - } - modules.add(m.getName()); - } - } + files.getContent().stream().filter(f -> !f.getType().equals(Pool.ModuleDataType.CLASS_OR_RESOURCE)). + forEach(this::accept); + modules.addAll(files.getModules().stream(). + // only add modules that contain packages + filter(m -> !m.getAllPackages().isEmpty()). + // skip the fake module used by FileCopierPlugin when copying files + filter(m -> !m.getName().equals(FileCopierPlugin.FAKE_MODULE)). + map(Module::getName).collect(Collectors.toList())); storeFiles(modules, bom, release); if (Files.getFileStore(root).supportsFileAttributeView(PosixFileAttributeView.class)) { @@ -194,13 +179,16 @@ } /** - * Generates launcher scripts. + * Generates launcher scripts for modules that have a main class. + * * @param imageContent The image content. * @param modules The set of modules that the runtime image contains. - * @throws IOException + * @throws IOException when module-info.class is not found for any given + * module, OR when module data cannot be read, OR when any of the + * application files cannot be written, OR when the bin directory + * to store application files in cannot be resolved. */ protected void prepareApplicationFiles(Pool imageContent, Set modules) throws IOException { - // generate launch scripts for the modules with a main class for (String module : modules) { String path = "/" + module + "/module-info.class"; ModuleData res = imageContent.get(path); @@ -251,9 +239,9 @@ } } - private void accept(ModuleData file) throws IOException { + private void accept(ModuleData file) { String fullPath = file.getPath(); - String module = "/" + file.getModule()+ "/"; + String module = "/" + file.getModule() + "/"; String filename = fullPath.substring(module.length()); // Remove radical native|config|... filename = filename.substring(filename.indexOf('/') + 1); @@ -286,6 +274,8 @@ default: throw new InternalError("unexpected entry: " + fullPath); } + } catch (IOException ioe) { + throw new UncheckedIOException(ioe); } } @@ -351,20 +341,20 @@ return new DefaultExecutableImage(root, modules); } - // This is experimental, we should get rid-off the scripts in a near future + // This is experimental, we should get rid of the scripts in a near future private static void patchScripts(ExecutableImage img, List args) throws IOException { Objects.requireNonNull(args); if (!args.isEmpty()) { Files.find(img.getHome().resolve("bin"), 2, (path, attrs) -> { return img.getModules().contains(path.getFileName().toString()); - }).forEach((p) -> { + }).forEach(p -> { try { String pattern = "JLINK_VM_OPTIONS="; byte[] content = Files.readAllBytes(p); String str = new String(content, StandardCharsets.UTF_8); int index = str.indexOf(pattern); - StringBuilder builder = new StringBuilder(); if (index != -1) { + StringBuilder builder = new StringBuilder(); builder.append(str.substring(0, index)). append(pattern); for (String s : args) { @@ -392,8 +382,7 @@ public static ExecutableImage getExecutableImage(Path root) { if (Files.exists(root.resolve("bin").resolve(getJavaProcessName()))) { - return new DefaultImageBuilder.DefaultExecutableImage(root, - retrieveModules(root)); + return new DefaultExecutableImage(root, retrieveModules(root)); } return null; } @@ -414,7 +403,6 @@ for (String m : arr) { modules.add(m.trim()); } - } } return modules; diff -r a0071ded705e src/jdk.jlink/share/classes/jdk/tools/jlink/builder/ImageBuilder.java --- a/src/jdk.jlink/share/classes/jdk/tools/jlink/builder/ImageBuilder.java Mon Mar 07 11:25:26 2016 +0100 +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/builder/ImageBuilder.java Mon Mar 14 13:23:57 2016 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 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 @@ -32,8 +32,9 @@ import jdk.tools.jlink.plugin.Pool; /** - * Implement this interface to develop your own image layout. First the jimage - * is written onto the output stream returned by getOutputStream then storeFiles + * Implement this interface to develop your own image layout. First, the jimage + * is written onto the output stream returned by {@link #getJImageOutputStream()}; + * then, {@link #storeFiles(Pool, String)} or {@link #storeFiles(Pool, String, Properties)} * is called. */ public interface ImageBuilder { @@ -43,7 +44,7 @@ * * @param content Pool of module content. * @param bom The options used to build the image file. - * @param release the release properties + * @param release the release properties. * @throws PluginException */ public default void storeFiles(Pool content, String bom, Properties release) { @@ -64,7 +65,7 @@ /** * The OutputStream to store the jimage file. * - * @return The output stream + * @return The output stream. * @throws PluginException */ public DataOutputStream getJImageOutputStream(); diff -r a0071ded705e src/jdk.jlink/share/classes/jdk/tools/jlink/internal/Utils.java --- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/Utils.java Mon Mar 07 11:25:26 2016 +0100 +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/Utils.java Mon Mar 14 13:23:57 2016 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 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 @@ -25,17 +25,13 @@ package jdk.tools.jlink.internal; import java.lang.reflect.Module; -import java.util.ArrayList; -import java.util.Comparator; import java.util.List; import java.util.function.Function; +import java.util.stream.Collectors; + import jdk.tools.jlink.plugin.Plugin; import jdk.tools.jlink.plugin.Plugin.PluginType; -/** - * - * @author jdenise - */ public class Utils { private Utils() {} @@ -102,45 +98,25 @@ } public static List getPostProcessors(List plugins) { - List res = new ArrayList<>(); - for (Plugin p : plugins) { - if (isPostProcessor(p)) { - res.add(p); - } - } - return res; + return plugins.stream().filter(Utils::isPostProcessor). + collect(Collectors.toList()); } public static List getSortedPostProcessors(List plugins) { - List res = getPostProcessors(plugins); - res.sort(new Comparator() { - @Override - public int compare(Plugin o1, Plugin o2) { - return o1.getName().compareTo(o2.getName()); - } - }); - return res; + return getPostProcessors(plugins).stream(). + sorted((o1, o2) -> o1.getName().compareTo(o2.getName())). + collect(Collectors.toList()); } public static List getSortedPreProcessors(List plugins) { - List res = getPreProcessors(plugins); - res.sort(new Comparator() { - @Override - public int compare(Plugin o1, Plugin o2) { - return o1.getName().compareTo(o2.getName()); - } - }); - return res; + return getPreProcessors(plugins).stream(). + sorted((o1, o2) -> o1.getName().compareTo(o2.getName())). + collect(Collectors.toList()); } public static List getPreProcessors(List plugins) { - List res = new ArrayList<>(); - for (Plugin p : plugins) { - if (isPreProcessor(p)) { - res.add(p); - } - } - return res; + return plugins.stream().filter(Utils::isPreProcessor). + collect(Collectors.toList()); } public static boolean isFunctional(Plugin prov) { @@ -155,7 +131,10 @@ return prov.getState().contains(Plugin.STATE.DISABLED); } - // is this a builtin (jdk.jlink) plugin? + /** + * @param prov a plugin. + * @return whether the argument is a built-in ({@code jdk.jlink}) plugin. + */ public static boolean isBuiltin(Plugin prov) { return THIS_MODULE.equals(prov.getClass().getModule()); } diff -r a0071ded705e src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/DefaultCompressPlugin.java --- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/DefaultCompressPlugin.java Mon Mar 07 11:25:26 2016 +0100 +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/DefaultCompressPlugin.java Mon Mar 14 13:23:57 2016 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 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 @@ -26,10 +26,7 @@ import java.io.IOException; import java.io.UncheckedIOException; -import java.util.ArrayList; import java.util.Collections; -import java.util.HashSet; -import java.util.List; import java.util.Map; import java.util.Set; @@ -43,10 +40,10 @@ import jdk.tools.jlink.internal.Utils; /** - * - * ZIP and String Sharing compression plugin + * ZIP and string sharing compression plugin. */ public final class DefaultCompressPlugin implements TransformerPlugin, ResourcePrevisitor { + public static final String NAME = "compress"; public static final String FILTER = "filter"; public static final String LEVEL_0 = "0"; @@ -84,9 +81,7 @@ @Override public Set getType() { - Set set = new HashSet<>(); - set.add(CATEGORY.COMPRESSOR); - return Collections.unmodifiableSet(set); + return Collections.singleton(CATEGORY.COMPRESSOR); } @Override diff -r a0071ded705e src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/ExcludeFilesPlugin.java --- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/ExcludeFilesPlugin.java Mon Mar 07 11:25:26 2016 +0100 +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/ExcludeFilesPlugin.java Mon Mar 14 13:23:57 2016 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 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 @@ -27,7 +27,6 @@ import java.io.IOException; import java.io.UncheckedIOException; import java.util.Collections; -import java.util.HashSet; import java.util.Map; import java.util.Set; import java.util.function.Predicate; @@ -37,8 +36,7 @@ import jdk.tools.jlink.internal.Utils; /** - * - * Exclude files plugin + * Exclude files plugin. */ public final class ExcludeFilesPlugin implements TransformerPlugin { @@ -62,9 +60,7 @@ @Override public Set getType() { - Set set = new HashSet<>(); - set.add(CATEGORY.FILTER); - return Collections.unmodifiableSet(set); + return Collections.singleton(CATEGORY.FILTER); } @Override diff -r a0071ded705e src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/ExcludePlugin.java --- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/ExcludePlugin.java Mon Mar 07 11:25:26 2016 +0100 +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/ExcludePlugin.java Mon Mar 14 13:23:57 2016 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 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 @@ -36,8 +36,7 @@ import jdk.tools.jlink.internal.Utils; /** - * - * Exclude resources plugin + * Exclude resources plugin. */ public final class ExcludePlugin implements TransformerPlugin { @@ -76,9 +75,7 @@ @Override public Set getType() { - Set set = new HashSet<>(); - set.add(CATEGORY.FILTER); - return Collections.unmodifiableSet(set); + return Collections.singleton(CATEGORY.FILTER); } @Override diff -r a0071ded705e src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/ExcludeVMPlugin.java --- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/ExcludeVMPlugin.java Mon Mar 07 11:25:26 2016 +0100 +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/ExcludeVMPlugin.java Mon Mar 14 13:23:57 2016 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 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 @@ -32,7 +32,6 @@ import java.nio.charset.StandardCharsets; import java.util.Collections; import java.util.Comparator; -import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; @@ -46,7 +45,6 @@ import jdk.tools.jlink.plugin.PluginException; /** - * * Exclude VM plugin */ public final class ExcludeVMPlugin implements TransformerPlugin { @@ -55,27 +53,30 @@ @Override public int compare(Jvm o1, Jvm o2) { - return o1.getEfficience() - o2.getEfficience(); + return o1.getEfficiency() - o2.getEfficiency(); } } private enum Jvm { - // The efficience order server - client - minimal. - SERVER("server", 3), CLIENT("client", 2), MINIMAL("minimal", 1); + // Efficiency order, descending: server - client - minimal. + SERVER("server", 3), + CLIENT("client", 2), + MINIMAL("minimal", 1); + private final String name; - private final int efficience; + private final int efficiency; - Jvm(String name, int efficience) { + Jvm(String name, int efficiency) { this.name = name; - this.efficience = efficience; + this.efficiency = efficiency; } private String getName() { return name; } - private int getEfficience() { - return efficience; + private int getEfficiency() { + return efficiency; } } @@ -98,15 +99,15 @@ /** * VM paths: - * /java.base/native/{architecture}/{server|client|minimal}/{shared lib} - * e.g.: /java.base/native/amd64/server/libjvm.so - * /java.base/native/server/libjvm.dylib + * {@code /java.base/native/{architecture}/{server|client|minimal}/{shared lib}}, + * e.g., {@code /java.base/native/amd64/server/libjvm.so}, + * {@code /java.base/native/server/libjvm.dylib}. */ private List getVMs(Pool in) { String jvmlib = jvmlib(); - List ret = in.getModule("java.base").getContent().stream().filter((t) -> { - return t.getPath().endsWith("/" + jvmlib); - }).collect(Collectors.toList()); + List ret = in.getModule("java.base").getContent().stream(). + filter(t -> t.getPath().endsWith("/" + jvmlib)). + collect(Collectors.toList()); return ret; } @@ -116,7 +117,7 @@ TreeSet existing = new TreeSet<>(new JvmComparator()); TreeSet removed = new TreeSet<>(new JvmComparator()); if (!keepAll) { - // First retrieve all available VM names and removed VM + // first, retrieve all available VM names and removed VM List jvms = getVMs(in); for (Jvm jvm : Jvm.values()) { for (Pool.ModuleData md : jvms) { @@ -128,15 +129,13 @@ } } } - } - // Check that target exists - if (!keepAll) { + // check that target exists if (!existing.contains(target)) { throw new PluginException("Selected VM " + target.getName() + " doesn't exist."); } } - // Rewrite the jvm.cfg file. + // rewrite the jvm.cfg file in.visit((file) -> { if (!keepAll) { if (file.getType().equals(ModuleDataType.NATIVE_LIB)) { @@ -161,9 +160,7 @@ @Override public Set getType() { - Set set = new HashSet<>(); - set.add(CATEGORY.FILTER); - return Collections.unmodifiableSet(set); + return Collections.singleton(CATEGORY.FILTER); } @Override @@ -188,7 +185,7 @@ String exclude = ""; switch (value) { case ALL: { - // no filter. + // no filter keepAll = true; break; } @@ -224,27 +221,23 @@ return orig; } StringBuilder builder = new StringBuilder(); - // Keep comments + // keep comments try (BufferedReader reader = new BufferedReader(new InputStreamReader(orig.stream(), StandardCharsets.UTF_8))) { - reader.lines().forEach((s) -> { - if (s.startsWith("#")) { - builder.append(s).append("\n"); - } - }); + reader.lines().filter(s -> s.startsWith("#")). + forEach(s -> builder.append(s).append('\n')); } TreeSet remaining = new TreeSet<>(new JvmComparator()); - // Add entry in jvm.cfg file from the more efficient to less efficient. - for (Jvm platform : existing) { - if (!removed.contains(platform)) { - remaining.add(platform); - builder.append("-").append(platform.getName()).append(" KNOWN\n"); - } - } + // add entry in jvm.cfg file from the more efficient to less efficient + existing.stream().filter(platform -> !removed.contains(platform)). + forEach(platform -> { + remaining.add(platform); + builder.append("-").append(platform.getName()).append(" KNOWN\n"); + }); - // removed JVM are aliased to the most efficient remaining JVM (last one). - // The order in the file is from most to less efficient platform + // Removed JVMs are aliased to the most efficient remaining JVM (last one). + // The order in the file is from most to least efficient platform. for (Jvm platform : removed.descendingSet()) { builder.append("-").append(platform.getName()). append(" ALIASED_TO -"). diff -r a0071ded705e src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/FileCopierPlugin.java --- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/FileCopierPlugin.java Mon Mar 07 11:25:26 2016 +0100 +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/FileCopierPlugin.java Mon Mar 14 13:23:57 2016 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 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 @@ -49,7 +49,6 @@ import jdk.tools.jlink.internal.Utils; /** - * * Copy files to image from various locations. */ public class FileCopierPlugin implements TransformerPlugin { @@ -57,10 +56,10 @@ public static final String NAME = "copy-files"; private static final class CopiedFile { - Path source; Path target; } + public static final String FAKE_MODULE = "$jlink-file-copier"; private final List files = new ArrayList<>(); @@ -189,9 +188,7 @@ @Override public Set getType() { - Set set = new HashSet<>(); - set.add(CATEGORY.TRANSFORMER); - return Collections.unmodifiableSet(set); + return Collections.singleton(CATEGORY.TRANSFORMER); } @Override @@ -210,7 +207,7 @@ Path file = Paths.get(a); if (file.isAbsolute()) { cf.source = file; - // The target is the image root directory. + // the target is the image root directory cf.target = file.getFileName(); } else { file = new File(javahome, a).toPath(); @@ -240,11 +237,9 @@ @Override public void visit(Pool in, Pool out) { - in.visit((file) -> { - return file; - }, out); + in.visit(file -> file, out); - // Add new files. + // add new files try { for (CopiedFile file : files) { if (Files.isRegularFile(file.source)) { @@ -253,7 +248,7 @@ DirectoryCopy dc = new DirectoryCopy(file.source, out, file.target.toString()); Files.walkFileTree(file.source, dc); - // Add symlinks after actual content + // add symlinks after actual content for (SymImageFile imf : dc.symlinks) { try { out.add(imf); diff -r a0071ded705e src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/InstalledModuleDescriptorPlugin.java --- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/InstalledModuleDescriptorPlugin.java Mon Mar 07 11:25:26 2016 +0100 +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/InstalledModuleDescriptorPlugin.java Mon Mar 14 13:23:57 2016 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 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 @@ -52,20 +52,24 @@ /** * Jlink plugin to reconstitute module descriptors for installed modules. - * It will extend module-info.class with ConcealedPackages attribute, - * if not present. It also determines the number of packages of - * the boot layer at link time. - * - * This plugin will override jdk.internal.module.InstalledModules class + * It will extend {@code module-info.class} with a {@code ConcealedPackages} + * attribute, if it is not already present. It also determines the number of + * packages of the boot layer at link time. + *

+ * This plugin will override the {@code jdk.internal.module.InstalledModules} + * class. * * @see java.lang.module.InstalledModuleFinder * @see jdk.internal.module.InstalledModules */ public final class InstalledModuleDescriptorPlugin implements TransformerPlugin { + private static final String NAME = "installed-modules"; private static final String DESCRIPTION = PluginsResourceBundle.getDescription(NAME); private boolean enabled; + private static final String MODULE_INFO = "module-info.class"; + public InstalledModuleDescriptorPlugin() { this.enabled = true; } @@ -108,12 +112,12 @@ Builder builder = new Builder(); // generate the byte code to create ModuleDescriptors - // skip parsing module-info.class and skip name check + // skip parsing module-info.class, and skip name check for (Pool.Module module : in.getModules()) { - Pool.ModuleData data = module.get("module-info.class"); + Pool.ModuleData data = module.get(MODULE_INFO); if (data == null) { // automatic module not supported yet - throw new PluginException("module-info.class not found for " + module.getName() + " module"); + throw new PluginException(MODULE_INFO + " not found for " + module.getName() + " module"); } assert module.getName().equals(data.getModule()); try { @@ -138,12 +142,12 @@ } - // Generate the new class + // generate the new class ClassWriter cwriter = builder.build(); for (Pool.ModuleData data : in.getContent()) { - if (data.getPath().endsWith("module-info.class")) + if (data.getPath().endsWith(MODULE_INFO)) { continue; - + } if (builder.isOverriddenClass(data.getPath())) { byte[] bytes = cwriter.toByteArray(); Pool.ModuleData ndata = new Pool.ModuleData(data.getModule(), data.getPath(), data.getType(), @@ -155,14 +159,14 @@ } } - /* - * Add ConcealedPackages attribute + /** + * Add the {@code ConcealedPackages} attribute. */ class ModuleInfoRewriter extends ByteArrayOutputStream { final ModuleInfoExtender extender; ModuleInfoRewriter(InputStream in, Set conceals) throws IOException { this.extender = ModuleInfoExtender.newExtender(in); - // Add ConcealedPackages attribute + // add the ConcealedPackages attribute this.extender.conceals(conceals); this.extender.write(this); } @@ -179,8 +183,9 @@ } for (Exports e : md.exports()) { Checks.requirePackageName(e.source()); - if (e.isQualified()) - e.targets().forEach(Checks::requireModuleName); + if (e.isQualified()) { + e.targets().forEach(Checks::requireModuleName); + } } for (Map.Entry e : md.provides().entrySet()) { String service = e.getKey(); @@ -197,9 +202,9 @@ } } - /* - * Returns the initial capacity for a new Set or Map of the given size - * to avoid resizing. + /** + * Returns the initial capacity for a new {@code Set} or {@code Map} of the + * given size to avoid resizing. */ static final int initialCapacity(int size) { if (size == 0) { @@ -212,8 +217,8 @@ } /** - * Builder of a new jdk.internal.module.InstalledModules class - * to reconstitute ModuleDescriptor of the installed modules. + * Builder of a new {@link jdk.internal.module.InstalledModules} class + * to reconstitute {@link ModuleDescriptor}s of installed modules. */ static class Builder { private static final String CLASSNAME = @@ -249,10 +254,8 @@ this.cw = new ClassWriter(ClassWriter.COMPUTE_MAXS+ClassWriter.COMPUTE_FRAMES); } - /* - * static initializer initializing the static fields - * - * static Map map = new HashMap<>(); + /** + * Generate a static initializer. */ private void clinit(int numModules, int numPackages) { cw.visit(Opcodes.V1_8, ACC_PUBLIC+ACC_FINAL+ACC_SUPER, CLASSNAME, @@ -293,10 +296,10 @@ } - /* - * Adds the given ModuleDescriptor to the installed module list, and - * prepares mapping from Set to StringSetBuilders to emit an - * optimized number of string sets during build. + /** + * Adds the given {@code ModuleDescriptor} to the installed module list, and + * prepares mapping from {@code Set} to {@link StringSetBuilder}s to + * emit an optimized number of string sets during build. */ public ModuleDescriptorBuilder module(ModuleDescriptor md, Set packages) { ModuleDescriptorBuilder builder = new ModuleDescriptorBuilder(md, packages); @@ -305,25 +308,25 @@ // exports for (ModuleDescriptor.Exports e : md.exports()) { if (e.isQualified()) { - stringSets.computeIfAbsent(e.targets(), s -> new StringSetBuilder(s)) + stringSets.computeIfAbsent(e.targets(), StringSetBuilder::new) .increment(); } } // provides for (ModuleDescriptor.Provides p : md.provides().values()) { - stringSets.computeIfAbsent(p.providers(), s -> new StringSetBuilder(s)) + stringSets.computeIfAbsent(p.providers(), StringSetBuilder::new) .increment(); } // uses - stringSets.computeIfAbsent(md.uses(), s -> new StringSetBuilder(s)) + stringSets.computeIfAbsent(md.uses(), StringSetBuilder::new) .increment(); return builder; } - /* - * Generate bytecode for InstalledModules + /** + * Generate bytecode for installed modules. */ public ClassWriter build() { int numModules = builders.size(); @@ -409,9 +412,10 @@ mv.visitVarInsn(ALOAD, BUILDER_VAR); } - /* - * Returns the set of concealed packages from ModuleDescriptor, if present - * or compute it if the module oes not have ConcealedPackages attribute + /** + * Returns the set of concealed packages from {@code ModuleDescriptor}, + * if present; or computes it if the module does not have a + * {@code ConcealedPackages} attribute. */ Set conceals() { Set conceals = md.conceals(); @@ -488,8 +492,8 @@ putModuleDescriptor(); } - /* - * Put ModuleDescriptor into the modules array + /** + * Put {@code ModuleDescriptor} into the modules array. */ void putModuleDescriptor() { mv.visitVarInsn(ALOAD, MD_VAR); @@ -500,8 +504,8 @@ mv.visitInsn(AASTORE); } - /* - * Invoke Builder.requires(String mn) + /** + * Invoke {@code Builder.requires(String mn)}. */ void requires(String name) { mv.visitVarInsn(ALOAD, BUILDER_VAR); @@ -511,8 +515,8 @@ mv.visitInsn(POP); } - /* - * Invoke Builder.requires(Modifier mod, String mn) + /** + * Invoke {@code Builder.requires(Modifier mod, String mn)}. */ void requires(ModuleDescriptor.Requires.Modifier mod, String name) { mv.visitVarInsn(ALOAD, BUILDER_VAR); @@ -524,21 +528,23 @@ mv.visitInsn(POP); } - /* - * Invoke Builder.requires(Set mods, String mn) + /** + * Invoke {@code Builder.requires(Set mods, String mn)}. * + *

              * EnumSet mods = EnumSet.of(mod,....);
-             * Buidler.requires(mods, mn);
+             * Builder.requires(mods, mn);
+             * 
*/ void requires(Set mods, String name) { mv.visitVarInsn(ALOAD, MODS_VAR); - String signature = "("; + StringBuilder sigb = new StringBuilder("("); for (ModuleDescriptor.Requires.Modifier m : mods) { mv.visitFieldInsn(GETSTATIC, REQUIRES_MODIFIER_CLASSNAME, m.name(), REQUIRES_MODIFIER_TYPE); - signature += "Ljava/util/Enum;"; + sigb.append("Ljava/util/Enum;"); } - signature += ")Ljava/util/EnumSet;"; + String signature = sigb.append(")Ljava/util/EnumSet;").toString(); mv.visitMethodInsn(INVOKESTATIC, "java/util/EnumSet", "of", signature, false); mv.visitVarInsn(ASTORE, MODS_VAR); @@ -550,8 +556,8 @@ mv.visitInsn(POP); } - /* - * Invoke Builder.exports(String pn) + /** + * Invoke {@code Builder.exports(String pn)}. */ void exports(String pn) { mv.visitVarInsn(ALOAD, BUILDER_VAR); @@ -562,14 +568,16 @@ mv.visitInsn(POP); } - /* - * Invoke Builder.exports(String pn, Set targets) + /** + * Invoke {@code Builder.exports(String pn, Set targets)}. * + *
              * Set targets = new HashSet<>();
              * targets.add(t);
              * :
              * :
              * Builder.exports(pn, targets);
+             * 
*/ void exports(String pn, Set targets) { int varIndex = stringSets.get(targets).build(); @@ -581,8 +589,8 @@ mv.visitInsn(POP); } - /* - * Invokes Builder.uses(Set uses) + /** + * Invoke {@code Builder.uses(Set uses)}. */ void uses(Set uses) { int varIndex = stringSets.get(uses).build(); @@ -593,14 +601,16 @@ mv.visitInsn(POP); } - /* - * Invoke Builder.provides(String service, Set providers) + /** + * Invoke {@code Builder.provides(String service, Set providers)}. * + *
              * Set providers = new HashSet<>();
              * providers.add(impl);
              * :
              * :
              * Builder.exports(service, providers);
+             * 
*/ void provides(String service, Set providers) { int varIndex = stringSets.get(providers).build(); @@ -612,8 +622,8 @@ mv.visitInsn(POP); } - /* - * Invoke Builder.conceals(String pn) + /** + * Invoke {@code Builder.conceals(String pn)}. */ void conceals(String pn) { mv.visitVarInsn(ALOAD, BUILDER_VAR); @@ -623,8 +633,8 @@ mv.visitInsn(POP); } - /* - * Invoke Builder.mainClass(String cn) + /** + * Invoke {@code Builder.mainClass(String cn)}. */ void mainClass(String cn) { mv.visitVarInsn(ALOAD, BUILDER_VAR); @@ -634,8 +644,8 @@ mv.visitInsn(POP); } - /* - * Invoke Builder.version(Version v); + /** + * Invoke {@code Builder.version(Version v)}. */ void version(ModuleDescriptor.Version v) { mv.visitVarInsn(ALOAD, BUILDER_VAR); @@ -647,17 +657,19 @@ } - /* - * StringSetBuilder generates bytecode to create one single instance - * of HashSet for a given set of names and assign to a local variable - * slot. When there is only one single reference to a Set, - * it will reuse STRING_SET_VAR for reference. For Set with - * multiple references, it will use a new local variable. + /** + * {@code StringSetBuilder} generates bytecode to create one single + * instance of {@code HashSet} for a given set of names and assign to a + * local variable slot. When there is only one single reference to a + * {@code Set}, it will reuse {@code STRING_SET_VAR} for + * reference. For {@code Set} with multiple references, it will + * use a new local variable. */ class StringSetBuilder { final Set names; int refCount; int localVarIndex; + StringSetBuilder(Set names) { this.names = names; } @@ -666,10 +678,10 @@ refCount++; } - /* - * Build bytecode for the Set represented by this builder, - * or get the local variable index of a previously generated set - * (in the local scope). + /** + * Build bytecode for the {@code Set} represented by this + * builder and return its local variable index; or return the local + * variable index of a previously generated set (in the local scope). * * @return local variable index of the generated set. */ diff -r a0071ded705e src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/OptimizationPlugin.java --- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/OptimizationPlugin.java Mon Mar 07 11:25:26 2016 +0100 +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/OptimizationPlugin.java Mon Mar 14 13:23:57 2016 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 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 @@ -24,7 +24,6 @@ */ package jdk.tools.jlink.internal.plugins; -import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; @@ -32,7 +31,6 @@ import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Collections; -import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Objects; @@ -52,9 +50,8 @@ import jdk.tools.jlink.plugin.PluginException; /** - * - * Optimize Classes following various strategies. Strategies are implementation - * of ClassOptimizer and MethodOptimizer. + * Optimize classes following various strategies. Strategies are implementations + * of {@link ClassOptimizer} and {@link MethodOptimizer}. */ public final class OptimizationPlugin extends AsmPlugin { @@ -110,19 +107,16 @@ } public interface Optimizer { - void close() throws IOException; } public interface ClassOptimizer extends Optimizer { - boolean optimize(Consumer logger, AsmPools pools, AsmModulePool modulePool, ClassNode cn) throws Exception; } public interface MethodOptimizer extends Optimizer { - boolean optimize(Consumer logger, AsmPools pools, AsmModulePool modulePool, ClassNode cn, MethodNode m, TypeResolver resolver) throws Exception; @@ -139,19 +133,18 @@ content = content + "\n"; stream.write(content.getBytes(StandardCharsets.UTF_8)); } catch (IOException ex) { - System.err.println(ex); + throw new UncheckedIOException(ex); } } } private void close() throws IOException { log("Num analyzed methods " + numMethods); - for (Optimizer optimizer : optimizers) { try { optimizer.close(); } catch (IOException ex) { - System.err.println("Error closing optimizer " + ex); + throw new PluginException("Error closing optimizer.", ex); } } if (stream != null) { @@ -200,7 +193,7 @@ for (Optimizer optimizer : optimizers) { if (optimizer instanceof ClassOptimizer) { try { - boolean optim = ((ClassOptimizer) optimizer). + boolean optim =((ClassOptimizer) optimizer). optimize(this::log, pools, modulePool, cn); if (optim) { optimized = true; @@ -214,7 +207,7 @@ for (MethodNode m : cn.methods) { if ((m.access & Opcodes.ACC_ABSTRACT) == 0 && (m.access & Opcodes.ACC_NATIVE) == 0) { - numMethods += 1; + ++numMethods; try { boolean optim = moptimizer. optimize(this::log, pools, modulePool, cn, @@ -235,7 +228,7 @@ if (optimized) { writer = new ClassWriter(ClassWriter.COMPUTE_MAXS); try { - // add a validation layer in between to check for class vallidity + // add a validation layer in between to check for class validity CheckClassAdapter ca = new CheckClassAdapter(writer); cn.accept(ca); } catch (Exception ex) { @@ -288,8 +281,6 @@ @Override public Set getType() { - Set set = new HashSet<>(); - set.add(CATEGORY.TRANSFORMER); - return Collections.unmodifiableSet(set); + return Collections.singleton(CATEGORY.TRANSFORMER); } } diff -r a0071ded705e src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/ReleaseInfoPlugin.java --- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/ReleaseInfoPlugin.java Mon Mar 07 11:25:26 2016 +0100 +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/ReleaseInfoPlugin.java Mon Mar 14 13:23:57 2016 +0100 @@ -24,11 +24,9 @@ */ package jdk.tools.jlink.internal.plugins; -import java.lang.module.ModuleDescriptor; import java.io.FileInputStream; import java.io.IOException; import java.util.Collections; -import java.util.EnumSet; import java.util.List; import java.util.Map; import java.util.Set; @@ -37,15 +35,13 @@ import jdk.tools.jlink.internal.Utils; import jdk.tools.jlink.plugin.ExecutableImage; import jdk.tools.jlink.plugin.PluginContext; -import jdk.tools.jlink.plugin.PluginException; -import jdk.tools.jlink.plugin.Pool; import jdk.tools.jlink.plugin.PostProcessorPlugin; /** - * This plugin adds/deletes information for 'release' file. + * This plugin adds/deletes information for the 'release' file. */ public final class ReleaseInfoPlugin implements PostProcessorPlugin { - // option name + public static final String NAME = "release-info"; public static final String KEYS = "keys"; @@ -65,11 +61,6 @@ } @Override - public Set getState() { - return EnumSet.of(STATE.FUNCTIONAL); - } - - @Override public boolean hasArguments() { return true; } @@ -81,7 +72,7 @@ @Override public void configure(Map config, PluginContext ctx) { - Properties release = ctx != null? ctx.getReleaseProperties() : null; + Properties release = ctx != null ? ctx.getReleaseProperties() : null; if (release != null) { String operation = config.get(NAME); switch (operation) { @@ -91,7 +82,6 @@ // // --release-info add:build_type=fastdebug,source=openjdk,java_version=9 // and put whatever value that was passed in command line. - config.keySet().stream(). filter(s -> !NAME.equals(s)). forEach(s -> release.put(s, config.get(s))); @@ -122,7 +112,7 @@ @Override public List process(ExecutableImage image) { - // Nothing to do! Release info copied already during configure! + // Nothing to do; the release info was already copied during configuration. return Collections.emptyList(); } } diff -r a0071ded705e src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/ResourceFilter.java --- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/ResourceFilter.java Mon Mar 07 11:25:26 2016 +0100 +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/ResourceFilter.java Mon Mar 14 13:23:57 2016 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 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 @@ -30,6 +30,7 @@ import java.io.IOException; import java.io.InputStreamReader; import java.nio.charset.StandardCharsets; +import java.util.Arrays; import java.util.List; import java.util.function.Predicate; import java.util.regex.Matcher; @@ -37,8 +38,7 @@ import java.util.stream.Collectors; /** - * - * Filter in or out a resource + * Filter in or out a resource. */ public class ResourceFilter implements Predicate { @@ -52,8 +52,7 @@ } public ResourceFilter(String[] patterns, boolean negateAll) throws IOException { - - // Get the patterns from a file + // get the patterns from a file if (patterns != null && patterns.length == 1) { String filePath = patterns[0]; File f = new File(filePath); @@ -71,11 +70,8 @@ } if (patterns != null && negateAll) { - String[] excluded = new String[patterns.length]; - for (int i = 0; i < patterns.length; i++) { - excluded[i] = ResourceFilter.NEG + patterns[i]; - } - patterns = excluded; + patterns = Arrays.stream(patterns). + map(p -> NEG + p).toArray(String[]::new); } StringBuilder inPatternsBuilder = new StringBuilder(); @@ -111,22 +107,13 @@ if (outPatterns != null) { Matcher mout = outPatterns.matcher(path); if (mout.matches()) { - //System.out.println("Excluding file " + resource.getPath()); return false; } } - boolean accepted = false; - // If the inPatterns is null, means that all resources are accepted. - if (inPatterns == null) { - accepted = true; - } else { - Matcher m = inPatterns.matcher(path); - if (m.matches()) { - //System.out.println("Including file " + resource.getPath()); - accepted = true; - } - } - return accepted; + // if inPatterns is null, all resources are accepted + return inPatterns == null ? + true : + inPatterns.matcher(path).matches(); } @Override diff -r a0071ded705e src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/SortResourcesPlugin.java --- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/SortResourcesPlugin.java Mon Mar 07 11:25:26 2016 +0100 +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/SortResourcesPlugin.java Mon Mar 14 13:23:57 2016 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 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 @@ -32,7 +32,6 @@ import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Collections; -import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; @@ -47,8 +46,7 @@ import jdk.tools.jlink.internal.Utils; /** - * - * Sort Resources plugin + * Sort resources plugin. */ public final class SortResourcesPlugin implements TransformerPlugin { @@ -86,15 +84,13 @@ } private int getPatternOrdinal(String path) { - int ordinal = -1; for (int i = 0; i < filters.size(); i++) { Matcher m = filters.get(i).matcher(path); if (m.matches()) { - ordinal = i; - break; + return i; } } - return ordinal; + return -1; } private int getFileOrdinal(String path) { @@ -105,7 +101,7 @@ public void visit(Pool in, Pool out) { in.getContent().stream() .filter(w -> w.getType().equals(ModuleDataType.CLASS_OR_RESOURCE)) - .map((r) -> new SortWrapper(r, isFile + .map(r -> new SortWrapper(r, isFile ? getFileOrdinal(r.getPath()) : getPatternOrdinal(r.getPath()))) .sorted((sw1, sw2) -> { @@ -123,16 +119,17 @@ } return sw1.getPath().compareTo(sw2.getPath()); - }).forEach((sw) -> { - try { - out.add(sw.getResource()); - } catch (Exception ex) { - throw new RuntimeException(ex); - } - }); + }) + .forEach(sw -> { + try { + out.add(sw.getResource()); + } catch (Exception ex) { + throw new RuntimeException(ex); + } + }); in.getContent().stream() .filter(m -> !m.getType().equals(ModuleDataType.CLASS_OR_RESOURCE)) - .forEach((m) -> { + .forEach(m -> { try { out.add(m); } catch (Exception ex) { @@ -143,9 +140,7 @@ @Override public Set getType() { - Set set = new HashSet<>(); - set.add(CATEGORY.SORTER); - return Collections.unmodifiableSet(set); + return Collections.singleton(CATEGORY.SORTER); } @Override @@ -165,9 +160,9 @@ @Override public void configure(Map config) { - String val = config.get(NAME); + String value = config.get(NAME); try { - String[] patterns = Utils.listParser.apply(val); + String[] patterns = Utils.listParser.apply(value); boolean isf = false; List paths = null; if (patterns != null) { @@ -176,10 +171,9 @@ File f = new File(filePath); if (f.exists()) { isf = true; - try (FileInputStream fis = new FileInputStream(f); - InputStreamReader ins - = new InputStreamReader(fis, StandardCharsets.UTF_8); - BufferedReader reader = new BufferedReader(ins)) { + try (BufferedReader reader = new BufferedReader( + new InputStreamReader( + new FileInputStream(f), StandardCharsets.UTF_8))) { paths = reader.lines().collect(Collectors.toList()); } } diff -r a0071ded705e src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/StringSharingPlugin.java --- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/StringSharingPlugin.java Mon Mar 07 11:25:26 2016 +0100 +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/StringSharingPlugin.java Mon Mar 14 13:23:57 2016 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 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 @@ -66,19 +66,14 @@ import jdk.tools.jlink.internal.Utils; /** - * - * A Plugin that stores the image classes constant pool UTF_8 entries into the - * Image StringsTable. + * A plugin that stores the image classes constant pool UTF_8 entries into the + * image StringsTable. */ public class StringSharingPlugin implements TransformerPlugin, ResourcePrevisitor { public static final String NAME = "compact-cp"; - private static final int[] SIZES; - - static { - SIZES = StringSharingDecompressor.getSizes(); - } + private static final int[] SIZES = StringSharingDecompressor.getSizes(); private static final class CompactCPHelper { @@ -93,13 +88,9 @@ private Set scan() throws Exception { Set utf8Descriptors = new HashSet<>(); scanConstantPool(utf8Descriptors); - scanFields(utf8Descriptors); - scanMethods(utf8Descriptors); - scanAttributes(cf.attributes, utf8Descriptors); - return utf8Descriptors; } @@ -189,7 +180,6 @@ utf8Descriptors.add(descriptorIndex); scanAttributes(field.attributes, utf8Descriptors); } - } private void scanMethods(Set utf8Descriptors) @@ -216,7 +206,6 @@ = (ConstantPool.CONSTANT_MethodType_info) info; utf8Descriptors.add(mt.descriptor_index); } - if (info instanceof ConstantPool.CONSTANT_Double_info || info instanceof ConstantPool.CONSTANT_Long_info) { i++; @@ -229,7 +218,7 @@ } public byte[] transform(ModuleData resource, Pool out, - StringTable strings) throws IOException, Exception { + StringTable strings) throws Exception { byte[] content = resource.getBytes(); ClassFile cf; try (InputStream stream = new ByteArrayInputStream(content)) { @@ -265,26 +254,22 @@ SignatureParser.ParseResult parseResult = SignatureParser.parseSignatureDescriptor(original); List indexes - = parseResult.types.stream().map((type) -> { - return strings.addString(type); - }).collect(Collectors.toList()); + = parseResult.types.stream().map(strings::addString). + collect(Collectors.toList()); if (!indexes.isEmpty()) { out.write(StringSharingDecompressor.EXTERNALIZED_STRING_DESCRIPTOR); int sigIndex = strings.addString(parseResult.formatted); byte[] compressed = CompressIndexes.compress(sigIndex); out.write(compressed, 0, compressed.length); - writeDescriptorReference(out, indexes); continue; } } - // Put all strings in strings table. + // put all strings in strings table writeUTF8Reference(out, strings.addString(original)); - break; } - case ConstantPool.CONSTANT_Long: case ConstantPool.CONSTANT_Double: { i++; @@ -315,9 +300,7 @@ buffers.add(buffer); } ByteBuffer bb = ByteBuffer.allocate(l); - buffers.stream().forEach((buf) -> { - bb.put(buf); - }); + buffers.stream().forEach(bb::put); byte[] compressed_indices = bb.array(); byte[] compressed_size = CompressIndexes. compress(compressed_indices.length); @@ -349,9 +332,7 @@ @Override public Set getType() { - Set set = new HashSet<>(); - set.add(CATEGORY.COMPRESSOR); - return Collections.unmodifiableSet(set); + return Collections.singleton(CATEGORY.COMPRESSOR); } @Override diff -r a0071ded705e src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/StripDebugPlugin.java --- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/StripDebugPlugin.java Mon Mar 07 11:25:26 2016 +0100 +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/StripDebugPlugin.java Mon Mar 14 13:23:57 2016 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 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 @@ -28,8 +28,6 @@ import java.io.IOException; import java.io.UncheckedIOException; import java.util.Collections; -import java.util.HashSet; -import java.util.Map; import java.util.Set; import java.util.function.Predicate; import jdk.internal.org.objectweb.asm.ClassReader; @@ -40,13 +38,14 @@ import jdk.tools.jlink.plugin.TransformerPlugin; /** - * - * Strip debug attributes plugin + * Strip debug attributes plugin. */ public final class StripDebugPlugin implements TransformerPlugin { + private static final String[] PATTERNS = {"*.diz"}; public static final String NAME = "strip-debug"; private final Predicate predicate; + public StripDebugPlugin() { try { predicate = new ResourceFilter(PATTERNS); @@ -62,9 +61,7 @@ @Override public Set getType() { - Set set = new HashSet<>(); - set.add(CATEGORY.TRANSFORMER); - return Collections.unmodifiableSet(set); + return Collections.singleton(CATEGORY.TRANSFORMER); } @Override @@ -74,14 +71,14 @@ @Override public void visit(Pool in, Pool out) { - //remove *.diz files as well as debug attributes. + // remove *.diz files as well as debug attributes in.visit((resource) -> { ModuleData res = resource; if (resource.getType().equals(ModuleDataType.CLASS_OR_RESOURCE)) { String path = resource.getPath(); if (path.endsWith(".class")) { if (path.endsWith("module-info.class")) { - // XXX. Do we have debug info? Is Asm ready for module-info? + // TODO Do we have debug info? Is ASM ready for module-info? } else { ClassReader reader = new ClassReader(resource.getBytes()); ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS); diff -r a0071ded705e src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/StripNativeCommandsPlugin.java --- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/StripNativeCommandsPlugin.java Mon Mar 07 11:25:26 2016 +0100 +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/StripNativeCommandsPlugin.java Mon Mar 14 13:23:57 2016 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 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 @@ -25,15 +25,12 @@ package jdk.tools.jlink.internal.plugins; import java.util.Collections; -import java.util.HashSet; -import java.util.Map; import java.util.Set; import jdk.tools.jlink.plugin.Pool; import jdk.tools.jlink.plugin.TransformerPlugin; /** - * - * Strip Native Commands plugin + * Strip Native Commands plugin. */ public final class StripNativeCommandsPlugin implements TransformerPlugin { @@ -46,9 +43,7 @@ @Override public Set getType() { - Set set = new HashSet<>(); - set.add(CATEGORY.FILTER); - return Collections.unmodifiableSet(set); + return Collections.singleton(CATEGORY.FILTER); } @Override diff -r a0071ded705e src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/ZipPlugin.java --- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/ZipPlugin.java Mon Mar 07 11:25:26 2016 +0100 +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/ZipPlugin.java Mon Mar 14 13:23:57 2016 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 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 @@ -28,7 +28,6 @@ import java.io.IOException; import java.nio.ByteBuffer; import java.util.Collections; -import java.util.HashSet; import java.util.Map; import java.util.Set; import java.util.function.Predicate; @@ -43,7 +42,7 @@ /** * - * ZIP Compression plugin + * ZIP compression plugin. */ public final class ZipPlugin implements TransformerPlugin { @@ -51,7 +50,6 @@ private Predicate predicate; public ZipPlugin() { - } ZipPlugin(String[] patterns) throws IOException { @@ -69,9 +67,7 @@ @Override public Set getType() { - Set set = new HashSet<>(); - set.add(CATEGORY.COMPRESSOR); - return Collections.unmodifiableSet(set); + return Collections.singleton(CATEGORY.COMPRESSOR); } @Override diff -r a0071ded705e src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/asm/AsmGlobalPool.java --- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/asm/AsmGlobalPool.java Mon Mar 07 11:25:26 2016 +0100 +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/asm/AsmGlobalPool.java Mon Mar 14 13:23:57 2016 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 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 @@ -33,14 +33,14 @@ /** * Associate a package to a module, useful when adding new classes in new - * packages. WARNING: In order to properly handle new package and/or new - * module, module-info class must be added and/or updated. + * packages. WARNING: In order to properly handle new packages and/or new + * modules, a {@code module-info.class} must be added and/or updated. * - * @param pkg The new package, following java binary syntax (/-separated - * path name). + * @param pkg The new package, following Java binary syntax (/-separated + * path name). * @param module An existing or new module. - * @throws jdk.tools.jlink.plugins.PluginException If a mapping already - * exist for this package. + * @throws jdk.tools.jlink.plugin.PluginException If a mapping already + * exists for this package. */ public void addPackageModuleMapping(String pkg, String module); @@ -48,7 +48,7 @@ * Return the set of accessible packages for a given module. * * @param module The module from which packages are accessible. - * @return Set of packages or null if the module is not found. + * @return Set of packages or {@code null} if the module is not found. */ public Set getAccessiblePackages(String module); } diff -r a0071ded705e src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/asm/AsmModulePool.java --- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/asm/AsmModulePool.java Mon Mar 07 11:25:26 2016 +0100 +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/asm/AsmModulePool.java Mon Mar 14 13:23:57 2016 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 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 @@ -29,35 +29,36 @@ import jdk.internal.org.objectweb.asm.ClassReader; /** - * A pool for a given module + * A pool for a given module. */ public interface AsmModulePool extends AsmPool { /** * Associate a package to this module, useful when adding new classes in new - * packages. WARNING: In order to properly handle new package and/or new - * module, module-info class must be added and/or updated. + * packages. WARNING: In order to properly handle new packages and/or new + * modules, a {@code module-info.class} must be added and/or updated. * * @param pkg The new package, following java binary syntax (/-separated - * path name). - * @throws jdk.tools.jlink.plugins.PluginException If a mapping already - * exist for this package. + * path name). + * @throws jdk.tools.jlink.plugin.PluginException If a mapping already + * exists for this package. */ public void addPackage(String pkg); /** * The module name of this pool. - * @return The module name; + * + * @return The module name. */ public String getModuleName(); /** - * Lookup the class in this pool and the required pools. NB: static module + * Look up the class in this pool and the required pools. NB: static module * readability can be different at execution time. * * @param binaryName The class to lookup. - * @return The reader or null if not found - * @throws jdk.tools.jlink.plugins.PluginException + * @return The reader or {@code null} if not found. + * @throws jdk.tools.jlink.plugin.PluginException */ public ClassReader getClassReaderInDependencies(String binaryName); @@ -68,8 +69,8 @@ * * @param callerModule Name of calling module. * @param binaryName The class to lookup. - * @return The reader or null if not found - * @throws jdk.tools.jlink.plugins.PluginException + * @return The reader or {@code null} if not found. + * @throws jdk.tools.jlink.plugin.PluginException */ public ClassReader getExportedClassReader(String callerModule, String binaryName); @@ -77,14 +78,14 @@ /** * The module descriptor. * - * @return The module descriptor; + * @return The module descriptor. */ public ModuleDescriptor getDescriptor(); /** * Retrieve the internal and exported packages. * - * @return + * @return the set of all internal and exported packages for this module. */ public Set getAllPackages(); } diff -r a0071ded705e src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/asm/AsmPlugin.java --- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/asm/AsmPlugin.java Mon Mar 07 11:25:26 2016 +0100 +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/asm/AsmPlugin.java Mon Mar 14 13:23:57 2016 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 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 @@ -33,7 +33,6 @@ /** * Extend this class to develop your own plugin in order to transform jimage * resources. - * */ public abstract class AsmPlugin implements TransformerPlugin { @@ -58,11 +57,12 @@ } /** - * This is the method to implement in order to - * apply Asm transformation to jimage contained classes. - * @param pools The pool of Asm classes and other resource files. - * @param strings To add a string to the jimage strings table. + * This is the method to implement in order to apply ASM transformations to + * jimage contained classes. + * + * @param pools The pool of ASM classes and other resource files. * @throws jdk.tools.jlink.plugin.PluginException */ public abstract void visit(AsmPools pools); + } diff -r a0071ded705e src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/asm/AsmPool.java --- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/asm/AsmPool.java Mon Mar 07 11:25:26 2016 +0100 +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/asm/AsmPool.java Mon Mar 14 13:23:57 2016 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 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 @@ -24,8 +24,6 @@ */ package jdk.tools.jlink.internal.plugins.asm; -import java.io.InputStream; -import java.nio.ByteBuffer; import java.util.Collection; import java.util.List; import jdk.internal.org.objectweb.asm.ClassReader; @@ -33,13 +31,13 @@ import jdk.tools.jlink.plugin.Pool; /** - * A pool of ClassReader and other resource files. + * A pool of {@link ClassReader}s and resource files. * This class allows to transform and sort classes and resource files. *

- * Classes in the class pool are named following java binary name specification. - * For example, java.lang.Object class is named java/lang/Object + * Naming of classes in the pool follows the Java binary name specification. + * For example, the {@code java.lang.Object} class is named {@code java/lang/Object}. *

- * Module information has been stripped out from class and other resource files + * Module information has been stripped from class and other resource files * (.properties, binary files, ...).

*/ public interface AsmPool { @@ -48,9 +46,8 @@ * A resource that is not a class file. *

* The path of a resource is a /-separated path name that identifies the - * resource. For example com.foo.bar.Bundle.properties resource name is - * com/foo/bar/Bundle.properties

- *

+ * resource. For example, the resource name for {@code com.foo.bar.Bundle.properties} + * is {@code com/foo/bar/Bundle.properties}. */ public class ResourceFile { @@ -72,29 +69,29 @@ } /** - * To visit each Class contained in the pool + * To visit each class contained in the pool. */ public interface ClassReaderVisitor { /** - * Called for each ClassReader located in the pool. + * Called for each {@link ClassReader} located in the pool. * * @param reader A class reader. - * @return A writer or null if the class has not been transformed. + * @return A writer or {@code null} if the class has not been transformed. */ public ClassWriter visit(ClassReader reader); } /** - * To visit each Resource contained in the pool + * To visit each resource contained in the pool. */ public interface ResourceFileVisitor { /** - * Called for each Resource file located in the pool. + * Called for each resource file located in the pool. * * @param reader A resource file. - * @return A resource file or null if the resource has not been + * @return A resource file or {@code null} if the resource has not been * transformed. */ public ResourceFile visit(ResourceFile reader); @@ -107,7 +104,7 @@ public interface WritableClassPool { /** - * Add a class to the pool, if a class already exists, it is replaced. + * Add a class to the pool. If a class already exists, it is replaced. * * @param writer The class writer. * @throws jdk.tools.jlink.plugin.PluginException @@ -125,8 +122,8 @@ /** * Get a transformed class. * - * @param binaryName The java class binary name - * @return The ClassReader or null if the class is not found. + * @param binaryName The Java class binary name. + * @return The ClassReader or {@code null} if the class is not found. * @throws jdk.tools.jlink.plugin.PluginException */ public ClassReader getClassReader(String binaryName); @@ -135,7 +132,7 @@ * Get a transformed class. * * @param res A class resource. - * @return The ClassReader or null if the class is not found. + * @return The ClassReader or {@code null} if the class is not found. * @throws jdk.tools.jlink.plugin.PluginException */ public ClassReader getClassReader(Pool.ModuleData res); @@ -155,7 +152,7 @@ public interface WritableResourcePool { /** - * Add a resource, if the resource exists, it is replaced. + * Add a resource. If the resource exists, it is replaced. * * @param resFile The resource file to add. * @throws jdk.tools.jlink.plugin.PluginException @@ -165,25 +162,25 @@ /** * The resource will be not added to the jimage file. * - * @param resourceName + * @param resourceName the name of the resource to forget. * @throws jdk.tools.jlink.plugin.PluginException If the resource to - * forget doesn't exist or is null. + * forget doesn't exist or is {@code null}. */ public void forgetResourceFile(String resourceName); /** * Get a transformed resource. * - * @param name The java resource name - * @return The Resource or null if the resource is not found. + * @param name The Java resource name. + * @return The resource or {@code null} if the resource is not found. */ public ResourceFile getResourceFile(String name); /** * Get a transformed resource. * - * @param res The java resource - * @return The Resource or null if the resource is not found. + * @param res The Java resource. + * @return The resource or {@code null} if the resource is not found. */ public ResourceFile getResourceFile(Pool.ModuleData res); @@ -202,7 +199,7 @@ /** * @param resources The resources will be added to the jimage following - * the order of this ResourcePool. + * the order of this resource pool. * @return The resource paths ordered in the way to use for storage in the jimage. * @throws jdk.tools.jlink.plugin.PluginException */ @@ -225,10 +222,10 @@ /** * Set a sorter instance to sort all files. If no sorter is set, then input - * Resources will be added in the order they have been received followed by + * resources will be added in the order they have been received followed by * newly added resources. * - * @param sorter + * @param sorter the sorter to use for resource ordering. */ public void setSorter(Sorter sorter); @@ -240,39 +237,39 @@ public Collection getClasses(); /** - * Returns the resources contained in the pool. Resources are all the file - * that are not classes (eg: properties file, binary files, ...) + * Returns the resources contained in the pool. Resources are all files + * that are not classes (e.g., .properties files, binary files, ...) * - * @return The array of resource files. + * @return The collection of resource files. */ public Collection getResourceFiles(); /** * Retrieves a resource based on the binary name. This name doesn't contain * the module name. + *

* NB: When dealing with resources that have the same name in various - * modules (eg: META-INFO/*), you should use the ResourcePool - * referenced from this AsmClassPool. + * modules (e.g., {@code META-INFO/*}), the ResourcePool + * referenced from this AsmClassPool should be used. * - * @param binaryName Name of a Java resource or null if the resource doesn't - * exist. - * @return + * @param binaryName Name of a Java resource. + * @return the resource or {@code null} if the resource does not exist. */ public ResourceFile getResourceFile(String binaryName); /** * Retrieves a resource for the passed resource. * - * @param res The resource - * @return The resource file or null if it doesn't exist. + * @param res The resource. + * @return The resource file or {@code null} if it doesn't exist. */ public ResourceFile getResourceFile(Pool.ModuleData res); /** * Retrieve a ClassReader from the pool. * - * @param binaryName Class binary name - * @return A reader or null if the class is unknown + * @param binaryName Class binary name. + * @return A reader or {@code null} if the class is unknown. * @throws jdk.tools.jlink.plugin.PluginException */ public ClassReader getClassReader(String binaryName); @@ -281,7 +278,7 @@ * Retrieve a ClassReader from the pool. * * @param res A resource. - * @return A reader or null if the class is unknown + * @return A reader or {@code null} if the class is unknown. * @throws jdk.tools.jlink.plugin.PluginException */ public ClassReader getClassReader(Pool.ModuleData res); diff -r a0071ded705e src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/asm/AsmPoolImpl.java --- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/asm/AsmPoolImpl.java Mon Mar 07 11:25:26 2016 +0100 +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/asm/AsmPoolImpl.java Mon Mar 14 13:23:57 2016 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 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 @@ -41,8 +41,10 @@ import java.util.Map; import java.util.Map.Entry; import java.util.Objects; -import java.util.Optional; import java.util.Set; +import java.util.stream.Collectors; +import java.util.stream.Stream; + import jdk.internal.org.objectweb.asm.ClassReader; import jdk.internal.org.objectweb.asm.ClassWriter; import jdk.tools.jlink.internal.ImageFileCreator; @@ -51,37 +53,19 @@ import jdk.tools.jlink.plugin.Pool; import jdk.tools.jlink.plugin.Pool.ModuleData; -/** - * A pool of ClassReader and other resource files. This class allows to - * transform and sort classes and resource files. - *

- * Classes in the class pool are named following java binary name specification. - * For example, java.lang.Object class is named java/lang/Object - *

- * Module information has been stripped out from class and other resource files - * (.properties, binary files, ...).

- */ final class AsmPoolImpl implements AsmModulePool { - /** - * Contains the transformed classes. When the jimage file is generated, - * transformed classes take precedence on unmodified ones. - */ + private static final String MODULE_INFO = "module-info.class"; + public final class WritableClassPoolImpl implements WritableClassPool { private WritableClassPoolImpl() { } - /** - * Add a class to the pool, if a class already exists, it is replaced. - * - * @param writer The class writer. - * @throws java.io.IOException - */ @Override public void addClass(ClassWriter writer) { Objects.requireNonNull(writer); - // Retrieve the className + // retrieve the className ClassReader reader = newClassReader(writer.toByteArray()); String className = reader.getClassName(); String path; @@ -99,11 +83,6 @@ transformedClasses.put(className, res); } - /** - * The class will be not added to the jimage file. - * - * @param className The class name to forget. - */ @Override public void forgetClass(String className) { Objects.requireNonNull(className); @@ -117,16 +96,10 @@ } String path = toClassNamePath(className); forgetResources.add(path); - // Just in case it has been added. + // just in case it had been added transformedClasses.remove(className); } - /** - * Get a transformed class. - * - * @param binaryName The java class binary name - * @return The ClassReader or null if the class is not found. - */ @Override public ClassReader getClassReader(String binaryName) { Objects.requireNonNull(binaryName); @@ -138,18 +111,9 @@ return reader; } - /** - * Returns all the classes contained in the writable pool. - * - * @return The array of transformed classes. - */ @Override public Collection getClasses() { - List classes = new ArrayList<>(); - for (Entry entry : transformedClasses.entrySet()) { - classes.add(entry.getValue()); - } - return classes; + return transformedClasses.values(); } @Override @@ -158,20 +122,11 @@ } } - /** - * Contains the transformed resources. When the jimage file is generated, - * transformed resources take precedence on unmodified ones. - */ public final class WritableResourcePoolImpl implements WritableResourcePool { private WritableResourcePoolImpl() { } - /** - * Add a resource, if the resource exists, it is replaced. - * - * @param resFile The resource file to add. - */ @Override public void addResourceFile(ResourceFile resFile) { Objects.requireNonNull(resFile); @@ -180,12 +135,6 @@ transformedResources.put(resFile.getPath(), res); } - /** - * The resource will be not added to the jimage file. - * - * @param resourceName - * @throws java.io.IOException - */ @Override public void forgetResourceFile(String resourceName) { Objects.requireNonNull(resourceName); @@ -199,16 +148,10 @@ } } forgetResources.add(path); - // Just in case it has been added. + // just in case it had been added transformedResources.remove(resourceName); } - /** - * Get a transformed resource. - * - * @param name The java resource name - * @return The Resource or null if the resource is not found. - */ @Override public ResourceFile getResourceFile(String name) { Objects.requireNonNull(name); @@ -220,18 +163,9 @@ return resFile; } - /** - * Returns all the resources contained in the writable pool. - * - * @return The array of transformed classes. - */ @Override public Collection getResourceFiles() { - List resources = new ArrayList<>(); - for (Entry entry : transformedResources.entrySet()) { - resources.add(entry.getValue()); - } - return resources; + return transformedResources.values(); } @Override @@ -267,7 +201,7 @@ private final AsmPools pools; /** - * A new Asm pool. + * Create a new AamPool instance. * * @param inputResources The raw resources to build the pool from. * @param moduleName The name of a module. @@ -299,7 +233,7 @@ if (ImageFileCreator.isClassPackage(res.getPath())) { packageClassToModule.put(split[1], res.getModule()); } else { - // Keep a map of other resources + // Keep a map of other resources. // Same resource names such as META-INF/* should be handled with full path name. if (!split[1].isEmpty()) { packageOtherToModule.put(split[1], res.getModule()); @@ -318,70 +252,31 @@ return moduleName; } - /** - * The writable pool used to store transformed resources. - * - * @return The writable pool. - */ @Override public WritableClassPool getTransformedClasses() { return transClassesPool; } - /** - * The writable pool used to store transformed resource files. - * - * @return The writable pool. - */ @Override public WritableResourcePool getTransformedResourceFiles() { return transResourcesPool; } - /** - * Set a sorter instance to sort all files. If no sorter is set, then input - * Resources will be added in the order they have been received followed by - * newly added resources. - * - * @param sorter - */ @Override public void setSorter(Sorter sorter) { this.sorter = sorter; } - /** - * Returns the classes contained in the pool. - * - * @return The array of classes. - */ @Override public Collection getClasses() { return inputClasses.values(); } - /** - * Returns the resources contained in the pool. Resources are all the file - * that are not classes (eg: properties file, binary files, ...) - * - * @return The array of classes. - */ @Override public Collection getResourceFiles() { return inputResources.values(); } - /** - * Retrieves a resource based on the binary name. This name doesn't contain - * the module name. - * NB: When dealing with resources that have the same name in various - * modules (eg: META-INFO/*), you should use the ResourcePool - * referenced from this AsmClassPool. - * - * @param binaryName Name of a Java resource or null if the resource doesn't - * exist. - * @return - */ @Override public ResourceFile getResourceFile(String binaryName) { Objects.requireNonNull(binaryName); @@ -393,12 +288,6 @@ return resFile; } - /** - * Retrieve a ClassReader from the pool. - * - * @param binaryName Class binary name - * @return A reader or null if the class is unknown - */ @Override public ClassReader getClassReader(String binaryName) { Objects.requireNonNull(binaryName); @@ -421,13 +310,6 @@ return newClassReader(res.getBytes()); } - /** - * Lookup the class in this pool and the required pools. NB: static module - * readability can be different at execution time. - * - * @param binaryName The class to lookup. - * @return The reader or null if not found - */ @Override public ClassReader getClassReaderInDependencies(String binaryName) { Objects.requireNonNull(binaryName); @@ -444,15 +326,6 @@ return reader; } - /** - * Lookup the class in the exported packages of this module. "public - * requires" modules are looked up. NB: static module readability can be - * different at execution time. - * - * @param callerModule Name of calling module. - * @param binaryName The class to lookup. - * @return The reader or null if not found - */ @Override public ClassReader getExportedClassReader(String callerModule, String binaryName) { Objects.requireNonNull(callerModule); @@ -462,11 +335,9 @@ for (Exports e : descriptor.exports()) { String pkg = e.source(); Set targets = e.targets(); - System.out.println("PKG " + pkg); if (targets.isEmpty() || targets.contains(callerModule)) { if (binaryName.startsWith(pkg)) { String className = binaryName.substring(pkg.length()); - System.out.println("CLASS " + className); exported = !className.contains("."); } if (exported) { @@ -489,7 +360,6 @@ clazz = getClassReader(binaryName); } return clazz; - } @Override @@ -497,11 +367,6 @@ return descriptor; } - /** - * To visit the set of ClassReaders. - * - * @param visitor The visitor. - */ @Override public void visitClassReaders(ClassReaderVisitor visitor) { Objects.requireNonNull(visitor); @@ -509,17 +374,11 @@ ClassReader reader = newClassReader(res.getBytes()); ClassWriter writer = visitor.visit(reader); if (writer != null) { - getTransformedClasses().addClass(writer); } } } - /** - * To visit the set of ClassReaders. - * - * @param visitor The visitor. - */ @Override public void visitResourceFiles(ResourceFileVisitor visitor) { Objects.requireNonNull(visitor); @@ -534,17 +393,12 @@ } } - /** - * Returns the pool of all the resources (transformed and unmodified). The - * input resources are replaced by the transformed ones. If a sorter has - * been set, it is used to sort the returned resources. * - */ @Override public void fillOutputResources(Pool outputResources) { List added = new ArrayList<>(); // If the sorter is null, use the input order. - // New resources are added at the end - // First input classes that have not been removed + // New resources are added at the end. + // First, process input classes that have not been removed. Pool output = new PoolImpl(outputResources.getByteOrder(), ((PoolImpl)outputResources).getStringTable()); for (ModuleData inResource : jimageResources.getContent()) { @@ -566,41 +420,17 @@ added.add(resource.getPath()); } } - // Then new resources - for (Map.Entry entry : transformedResources.entrySet()) { - ModuleData resource = entry.getValue(); - if (!forgetResources.contains(resource.getPath())) { - if (!added.contains(resource.getPath())) { - output.add(resource); - } - } - } - // And new classes - for (Map.Entry entry : transformedClasses.entrySet()) { - ModuleData resource = entry.getValue(); - if (!forgetResources.contains(resource.getPath())) { - if (!added.contains(resource.getPath())) { - output.add(resource); - } - } - } + // Next, process new resources and new classes. + Stream.of(transformedResources, transformedClasses).flatMap(t -> t.values().stream()). + filter(resource -> !forgetResources.contains(resource.getPath()) && !added.contains(resource.getPath())). + forEach(output::add); AsmPools.sort(outputResources, output, sorter); } - /** - * Associate a package to this module, useful when adding new classes in new - * packages. WARNING: In order to properly handle new package and/or new - * module, module-info class must be added and/or updated. - * - * @param pkg The new package, following java binary syntax (/-separated - * path name). - * @throws PluginException If a mapping already exist for this package. - */ @Override public void addPackage(String pkg) { Objects.requireNonNull(pkg); - Objects.requireNonNull(moduleName); pkg = pkg.replaceAll("/", "."); String mod = newPackageMapping.get(pkg); if (mod != null) { @@ -612,17 +442,11 @@ @Override public Set getAllPackages() { ModuleDescriptor desc = getDescriptor(); - Set packages = new HashSet<>(); - for (String p : desc.conceals()) { - packages.add(p.replaceAll("\\.", "/")); - } - for (String p : newPackageMapping.keySet()) { - packages.add(p.replaceAll("\\.", "/")); - } - for (Exports ex : desc.exports()) { - packages.add(ex.source().replaceAll("\\.", "/")); - } - return packages; + return Stream.concat( + Stream.of(desc.conceals(), newPackageMapping.keySet()).flatMap(Set::stream), + desc.exports().stream().map(Exports::source)). + map(p -> p.replaceAll("\\.", "/")). + collect(Collectors.toSet()); } private static ClassReader newClassReader(byte[] bytes) { @@ -636,7 +460,7 @@ } private static String toJavaBinaryClassName(String path) { - if (path.endsWith("module-info.class")) { + if (path.endsWith(MODULE_INFO)) { path = removeClassExtension(path); } else { path = removeModuleName(path); @@ -646,7 +470,7 @@ } private static String toJavaBinaryResourceName(String path) { - if (!path.endsWith("module-info.class")) { + if (!path.endsWith(MODULE_INFO)) { path = removeModuleName(path); } return path; @@ -657,7 +481,7 @@ } private static String removeModuleName(String path) { - path = path.substring(1); + path = path.substring(1); // remove leading / return path.substring(path.indexOf("/") + 1, path.length()); } @@ -679,7 +503,7 @@ if (module == null) { module = inputOtherPackageMapping.get(pkg); if (module == null) { - throw new PluginException("No module for package" + pkg); + throw new PluginException("No module for package " + pkg); } } } @@ -692,7 +516,7 @@ } int i = path.lastIndexOf("/"); if (i == -1) { - // Default package... + // default package return ""; } return path.substring(0, i).replaceAll("/", "."); diff -r a0071ded705e src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/asm/AsmPools.java --- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/asm/AsmPools.java Mon Mar 07 11:25:26 2016 +0100 +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/asm/AsmPools.java Mon Mar 14 13:23:57 2016 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 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 @@ -48,8 +48,8 @@ import jdk.tools.jlink.plugin.Pool.ModuleData; /** - * A container for pools of ClassReader and other resource files. A pool of all - * the resources or a pool for a given module can be retrieved + * A container for pools of {@link ClassReader}s and other resource files. A + * pool of all the resources or a pool for a given module can be retrieved. */ public final class AsmPools { @@ -62,9 +62,9 @@ * Sort the list of modules. * * @param modules The list of module names. The module will be stored in - * the jimage following this order. + * the jimage following this order. * @return A list of module names that expresses the order in which the - * modules are stored in the jimage. + * modules are stored in the jimage. */ public List sort(List modules); } @@ -99,11 +99,8 @@ @Override public Collection getClasses() { List all = new ArrayList<>(); - visitAllPools((AsmModulePool pool) -> { - for (Pool.ModuleData rf : pool.getTransformedClasses().getClasses()) { - all.add(rf); - } - }); + visitAllPools((AsmModulePool pool) -> + all.addAll(pool.getTransformedClasses().getClasses())); return all; } @@ -142,11 +139,8 @@ @Override public Collection getResourceFiles() { List all = new ArrayList<>(); - visitAllPools((AsmModulePool pool) -> { - for (Pool.ModuleData rf : pool.getTransformedResourceFiles().getResourceFiles()) { - all.add(rf); - } - }); + visitAllPools((AsmModulePool pool) -> + all.addAll(pool.getTransformedResourceFiles().getResourceFiles())); return all; } @@ -177,22 +171,15 @@ @Override public Collection getClasses() { List all = new ArrayList<>(); - visitAllPools((AsmModulePool pool) -> { - for (Pool.ModuleData rf : pool.getClasses()) { - all.add(rf); - } - }); + visitAllPools((AsmModulePool pool) -> all.addAll(pool.getClasses())); return all; } @Override public Collection getResourceFiles() { List all = new ArrayList<>(); - visitAllPools((AsmModulePool pool) -> { - for (Pool.ModuleData rf : pool.getResourceFiles()) { - all.add(rf); - } - }); + visitAllPools((AsmModulePool pool) -> + all.addAll(pool.getResourceFiles())); return all; } @@ -262,13 +249,13 @@ Set packages = new HashSet<>(); packages.addAll(p.getAllPackages()); - // Retrieve direct dependencies and indirect ones (public) + // retrieve direct dependencies and indirect ones (public) Set modules = new HashSet<>(); for (Requires req : desc.requires()) { modules.add(req.name()); addAllRequirePublicModules(req.name(), modules); } - // Add exported packages of readable modules + // add exported packages of readable modules for (String readable : modules) { AsmModulePool mp = pools.get(readable); if (mp != null) { @@ -278,7 +265,6 @@ packages.add(e.source().replaceAll("\\.", "/")); } } - } } return packages; @@ -299,17 +285,14 @@ } private interface VoidPoolVisitor { - void visit(AsmModulePool pool); } private interface VoidPoolVisitorEx { - void visit(AsmModulePool pool); } private interface RetPoolVisitor

{ - P visit(AsmModulePool pool); } @@ -320,7 +303,7 @@ private ModuleSorter moduleSorter; /** - * A new Asm pools. + * Create a new AsmPools instance. * * @param inputResources The raw resources to build the pool from. */ @@ -342,9 +325,9 @@ } p.add(res); } + poolsArray = new AsmModulePool[resPools.size()]; int i = 0; - for (Entry entry : resPools.entrySet()) { ModuleDescriptor descriptor = descriptors.get(entry.getKey()); if (descriptor == null) { @@ -354,8 +337,9 @@ entry.getKey(), this, descriptor); pools.put(entry.getKey(), p); poolsArray[i] = p; - i += 1; + ++i; } + global = new AsmGlobalPoolImpl(); } @@ -382,6 +366,7 @@ /** * The array of module pools. + * * @return The module pool array. */ public AsmModulePool[] getModulePools() { @@ -389,9 +374,9 @@ } /** - * Set a module sorter. Sorter is used when computing the output resources. + * Set a module sorter. This is used when computing the output resources. * - * @param moduleSorter The module sorter + * @param moduleSorter The module sorter. */ public void setModuleSorter(ModuleSorter moduleSorter) { Objects.requireNonNull(moduleSorter); @@ -401,39 +386,28 @@ /** * Returns the pool of all the resources (transformed and unmodified). The * input resources are replaced by the transformed ones. If a sorter has - * been set, it is used to sort in modules. + * been set, it is used to sort the modules. * * @param outputResources The pool used to fill the jimage. */ public void fillOutputResources(Pool outputResources) { - // First sort modules - List modules = new ArrayList<>(); - for (String k : pools.keySet()) { - modules.add(k); - } + // first, sort the modules + List modules = new ArrayList<>(pools.keySet()); if (moduleSorter != null) { modules = moduleSorter.sort(modules); } Pool output = new PoolImpl(outputResources.getByteOrder(), ((PoolImpl)outputResources).getStringTable()); - for (String mn : modules) { - AsmPool pool = pools.get(mn); - pool.fillOutputResources(output); - } + modules.stream().map(mn -> pools.get(mn)).forEach(pool -> pool.fillOutputResources(output)); sort(outputResources, output, global.sorter); } static void sort(Pool outputResources, Pool transientOutput, Sorter sorter) { if (sorter != null) { - List order = sorter.sort(transientOutput); - for (String s : order) { - outputResources.add(transientOutput.get(s)); - } + sorter.sort(transientOutput).forEach(s -> outputResources.add(transientOutput.get(s))); } else { - for (ModuleData res : transientOutput.getContent()) { - outputResources.add(res); - } + transientOutput.getContent().forEach(outputResources::add); } } @@ -454,15 +428,11 @@ } private void visitAllPools(VoidPoolVisitor pv) { - for (Entry entry : pools.entrySet()) { - pv.visit(entry.getValue()); - } + pools.entrySet().stream().map(e -> e.getValue()).forEach(pv::visit); } private void visitAllPoolsEx(VoidPoolVisitorEx pv) { - for (Entry entry : pools.entrySet()) { - pv.visit(entry.getValue()); - } + pools.entrySet().stream().map(e -> e.getValue()).forEach(pv::visit); } private

P visitPoolsEx(RetPoolVisitor

pv) { diff -r a0071ded705e src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/optim/ControlFlow.java --- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/optim/ControlFlow.java Mon Mar 07 11:25:26 2016 +0100 +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/optim/ControlFlow.java Mon Mar 14 13:23:57 2016 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 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 @@ -46,14 +46,13 @@ /** * Split Java method onto a control flow. - * */ -public final class ControlFlow { +final class ControlFlow { /** - * A block of control + * A block of control. */ - public static final class Block implements Comparable { + static final class Block implements Comparable { private final InstructionNode firstInstruction; private final List instr = new ArrayList<>(); @@ -163,13 +162,11 @@ } } } - //System.err.println("TO EXCLUDE:\n " + toExclude); allReachable.removeAll(toExclude); - //System.err.println("CLOSURE:\n " + allReachable); return Collections.unmodifiableSet(allReachable); } - // Compute the set of blocks reachable from the current block + // Compute the set of blocks reachable from the current block. private void addAll(Block current, Set closure) { Objects.requireNonNull(current); closure.add(current); @@ -190,9 +187,9 @@ } /** - * An instruction + * An instruction. */ - public static final class InstructionNode { + static final class InstructionNode { private final int index; private final List next = new ArrayList<>(); @@ -246,14 +243,11 @@ private ControlFlow(Map allBlocks) { this.allBlocks = allBlocks; - for (Block b : allBlocks.values()) { - blocks.add(b); - } + blocks.addAll(allBlocks.values()); Collections.sort(blocks); } public List getBlocks() { - return Collections.unmodifiableList(blocks); } @@ -263,18 +257,17 @@ public static ControlFlow createControlFlow(String owner, MethodNode method) throws Exception { - BlockBuilder bb = new BlockBuilder(owner, method); return bb.build(); } /** - * Return the set of blocks that are only reachable from this block For - * example, if b is an Exception handler, returns all the blocks reachable - * only from this handler + * Returns the set of blocks that are only reachable from a given block. For + * example, if b is an exception handler, returns all the blocks reachable + * only from this handler. * - * @param b - * @return + * @param b block for which to compute the closure. + * @return the closure for the block. */ public Set getClosure(Block b) { return new ClosureBuilder(b).build(); @@ -299,8 +292,7 @@ Analyzer analyzer = new Analyzer(new BasicInterpreter()) { @Override - protected boolean newControlFlowExceptionEdge(int insn, - int successor) { + protected boolean newControlFlowExceptionEdge(int insn, int successor) { List lst = handlers.get(successor); if (lst == null) { lst = new ArrayList<>(); @@ -311,8 +303,7 @@ } @Override - protected void newControlFlowEdge(int from, - int to) { + protected void newControlFlowEdge(int from, int to) { if (root == null) { root = new InstructionNode(from, method.instructions.get(from)); instructions.put(from, root); @@ -353,10 +344,8 @@ List reachableBlocks = new ArrayList<>(); createBlocks(root, reachableBlocks); List handlersBlocks = new ArrayList<>(); - for (Entry> entry : handlers.entrySet()) { - InstructionNode node = instructions.get(entry.getKey()); - createBlocks(node, handlersBlocks); - } + handlers.keySet().stream().map(instructions::get). + forEach(node -> createBlocks(node, handlersBlocks)); // attach handler to try blocks for (Entry> entry : handlers.entrySet()) { @@ -365,8 +354,8 @@ int startTry = entry.getValue().get(0); Block tryBlock = allBlocks.get(startTry); if (tryBlock == null) { - // Need to find the block that contains the instruction and - // make a new block + // Find the block that contains the instruction, + // and make a new block Block split = null; for (Block b : allBlocks.values()) { Iterator it = b.instr.iterator(); @@ -403,13 +392,8 @@ } } -// System.err.println("ALL BLOCKS FOUND"); -// Iterator> blockIt0 = allBlocks.entrySet().iterator(); -// while (blockIt0.hasNext()) { -// Block b = blockIt0.next().getValue(); -// System.err.println(b); -// } - //compute real exception blocks, if an instruction is in another block, stop. + // Compute real exception blocks. + // Stop if an instruction is in another block. Iterator> blockIt = allBlocks.entrySet().iterator(); while (blockIt.hasNext()) { Block b = blockIt.next().getValue(); @@ -431,22 +415,13 @@ } } } - -// System.err.println("Reduced blocks"); -// Iterator> blockIt1 = allBlocks.entrySet().iterator(); -// while (blockIt1.hasNext()) { -// Block b = blockIt1.next().getValue(); -// System.err.println(b); -// } } private boolean startsWith(Block block, int index, Collection reachableBlocks) { - for (Block b : reachableBlocks) { - if (b != block && !b.instr.isEmpty() && b.instr.get(0).getIndex() == index) { - return true; - } - } - return false; + return reachableBlocks.stream(). + anyMatch(b -> b != block + && !b.instr.isEmpty() + && b.instr.get(0).getIndex() == index); } private static final class StackItem { @@ -463,8 +438,8 @@ } /** - * This algorithm can't be recursive, possibly too much instructions in - * methods. + * This algorithm can't be recursive, possibly due to too many instructions + * in methods. */ private void createBlocks(InstructionNode root, List blocks) { final Stack stack = new Stack<>(); @@ -507,8 +482,8 @@ currentBlock)); } } - } else { // to a new block... - // Do nothing... + } else { // to a new block ... + // do nothing ... blocks.add(currentBlock); Block newBlock = newBlock(current); currentBlock.reachable.add(newBlock); diff -r a0071ded705e src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/optim/ForNameFolding.java --- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/optim/ForNameFolding.java Mon Mar 07 11:25:26 2016 +0100 +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/optim/ForNameFolding.java Mon Mar 14 13:23:57 2016 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 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 @@ -38,7 +38,6 @@ import jdk.tools.jlink.internal.plugins.optim.ReflectionOptimizer.Data; import jdk.tools.jlink.internal.plugins.optim.ReflectionOptimizer.TypeResolver; - /** * MethodOptimizer that removes Class.forName when possible. * WARNING: This code is experimental. @@ -68,7 +67,7 @@ return data.removedInstructions() > 0; } - public TypeResolver createResolver(TypeResolver resolver) { + private TypeResolver createResolver(TypeResolver resolver) { return (ClassNode cn, MethodNode mn, String type) -> { ClassReader reader = resolver.resolve(cn, mn, type); if (reader == null) { diff -r a0071ded705e src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/optim/ReflectionOptimizer.java --- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/optim/ReflectionOptimizer.java Mon Mar 07 11:25:26 2016 +0100 +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/optim/ReflectionOptimizer.java Mon Mar 14 13:23:57 2016 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 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 @@ -33,6 +33,8 @@ import java.util.Map; import java.util.Set; import java.util.TreeSet; +import java.util.stream.Collectors; + import jdk.internal.org.objectweb.asm.ClassReader; import jdk.internal.org.objectweb.asm.Type; import jdk.internal.org.objectweb.asm.tree.AbstractInsnNode; @@ -50,7 +52,7 @@ */ public class ReflectionOptimizer { - public static class Data { + static class Data { private int removedInstructions; private final Map> removedHandlers = new HashMap<>(); @@ -68,11 +70,10 @@ } public interface TypeResolver { - public ClassReader resolve(ClassNode cn, MethodNode m, String type); } - public static Data replaceWithClassConstant(ClassNode cn, MethodNode m, + static Data replaceWithClassConstant(ClassNode cn, MethodNode m, TypeResolver cch) throws Exception { Iterator it = m.instructions.iterator(); @@ -82,6 +83,7 @@ while (it.hasNext()) { AbstractInsnNode n = it.next(); if (n instanceof LdcInsnNode) { + // track String LDC nodes - they might be used in a Class.forName call LdcInsnNode ldc = (LdcInsnNode) n; if (ldc.cst instanceof String) { insNode = ldc; @@ -92,7 +94,7 @@ if (met.name.equals("forName") && met.owner.equals("java/lang/Class") && met.desc.equals("(Ljava/lang/String;)Ljava/lang/Class;")) { - // Can we load the type? + // can we load the type? Type type = null; String binaryName = insNode.cst.toString().replaceAll("\\.", "/"); String unaryClassName = binaryName; @@ -104,7 +106,7 @@ unaryClassName = unaryClassName.substring(0, unaryClassName.length() - 1); } else { - //primitive, this is just fine. + // primitive, this is just fine type = Type.getObjectType(binaryName); } } @@ -121,7 +123,7 @@ } else { insNode = null; } - // Virtual node, not taken into account + // virtual node, not taken into account } else if (!(n instanceof LabelNode) && !(n instanceof LineNumberNode)) { insNode = null; } @@ -133,7 +135,6 @@ if (!replacement.isEmpty()) { String[] types = {"java/lang/ClassNotFoundException"}; data.removedInstructions += deleteExceptionHandlers(cch, data, cn, m, types); - } return data; } @@ -150,14 +151,14 @@ List tcbToRemove = new ArrayList<>(); while (it.hasNext()) { TryCatchBlockNode bn = it.next(); - if (bn.type == null - || !bn.type.equals(ex) // An empty block + if (bn.type == null // an empty block + || !bn.type.equals(ex) || tcbToRemove.contains(bn)) { continue; } - // Check that the handler is still required + // check that the handler is still required if (!Utils.canThrowCheckedException(cch, cn, m, bn)) { - // try to suppress it. + // try to suppress it int block = m.instructions.indexOf(bn.handler); ControlFlow.Block blockHandler = f.getBlock(block); if (blockHandler == null) { @@ -169,55 +170,34 @@ } } tcbToRemove.add(bn); - // Don't delete block if shared (eg: ClassNotFoundException | NoSuchMethodException | - Iterator it2 = m.tryCatchBlocks.iterator(); - boolean cont = false; - while (it2.hasNext()) { - TryCatchBlockNode bn2 = it2.next(); - if (bn2 != bn) { - if (bn2.start.equals(bn.start)) { - cont = true; - } - } - } - if (cont) { + // don't delete block if shared (e.g., ClassNotFoundException | NoSuchMethodException) + if (m.tryCatchBlocks.stream().anyMatch(bn2 -> bn2 != bn && bn2.start.equals(bn.start))) { continue; } - // An handler is a root, blocks that are only reachable by it + + // A handler is a root, blocks that are reachable only by this handler // can be removed. Set blocks = f.getClosure(blockHandler); - StringBuilder sb = new StringBuilder(); for (ControlFlow.Block b : blocks) { - sb.append(b).append("\n"); removed.add(b.getFirstInstruction().getIndex()); - // Remove Exception handler if the associated block has been removed - for (TryCatchBlockNode tcb : m.tryCatchBlocks) { - if (tcb != bn) { - // An exception handler removed as a side effect. - if (b.isExceptionHandler() - && b.getFirstInstruction().getInstr() == tcb.handler) { - tcbToRemove.add(tcb); - } - } - } + // remove Exception handler if the associated block has been removed + tcbToRemove.addAll(m.tryCatchBlocks.stream(). + filter(tcb -> tcb != bn + && b.isExceptionHandler() + && b.getFirstInstruction().getInstr() == tcb.handler). + collect(Collectors.toList())); } blocksToRemove.addAll(blocks); data.removedHandlers.put(ex, blocks); - } } m.tryCatchBlocks.removeAll(tcbToRemove); if (!blocksToRemove.isEmpty()) { - for (ControlFlow.Block b : blocksToRemove) { - for (ControlFlow.InstructionNode ins : b.getInstructions()) { - if (ins.getInstr().getOpcode() > 0) { - instructionsRemoved += 1; - } - } - } + instructionsRemoved += (int) blocksToRemove.stream().flatMap(b -> b.getInstructions().stream()). + filter(ins -> ins.getInstr().getOpcode() > 0).count(); Utils.suppressBlocks(m, blocksToRemove); } } diff -r a0071ded705e src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/optim/Utils.java --- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/optim/Utils.java Mon Mar 07 11:25:26 2016 +0100 +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/optim/Utils.java Mon Mar 14 13:23:57 2016 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 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 @@ -34,7 +34,7 @@ import jdk.internal.org.objectweb.asm.tree.TryCatchBlockNode; /** - * Optimization utility methods + * Optimization utility methods. */ public class Utils { @@ -50,14 +50,9 @@ if (reader != null) { ClassNode cn = new ClassNode(); reader.accept(cn, ClassReader.EXPAND_FRAMES); - for (MethodNode method : cn.methods) { - if (method.name.equals(meth.name)) { - for (String e : method.exceptions) { - if (e.equals(bn.type)) { - return true; - } - } - } + if (cn.methods.stream().filter(method -> method.name.equals(meth.name)). + flatMap(method -> method.exceptions.stream()).anyMatch(e -> e.equals(bn.type))) { + return true; } } else { return true; @@ -72,16 +67,8 @@ Iterator it = m.instructions.iterator(); while (it.hasNext()) { AbstractInsnNode n = it.next(); - Iterator handlers = m.tryCatchBlocks.iterator(); - boolean cont = false; - // Do not delete instructions that are end of other try block. - while (handlers.hasNext()) { - TryCatchBlockNode handler = handlers.next(); - if (handler.end == n) { - cont = true; - } - } - if (cont) { + // Do not delete instructions that are at the end of another try block. + if (m.tryCatchBlocks.stream().anyMatch(handler -> handler.end == n)) { continue; } diff -r a0071ded705e src/jdk.jlink/share/classes/jdk/tools/jlink/plugin/ExecutableImage.java --- a/src/jdk.jlink/share/classes/jdk/tools/jlink/plugin/ExecutableImage.java Mon Mar 07 11:25:26 2016 +0100 +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/plugin/ExecutableImage.java Mon Mar 14 13:23:57 2016 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 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 @@ -32,7 +32,7 @@ import java.util.Set; /** - * An executable runtime image. Instance of this class contains the information + * An executable runtime image. Instance of this class contain the information * needed to create image processes. */ public abstract class ExecutableImage { @@ -41,8 +41,7 @@ private final List args; private final Set modules; - protected ExecutableImage(Path home, Set modules, - List args) { + protected ExecutableImage(Path home, Set modules, List args) { Objects.requireNonNull(home); Objects.requireNonNull(args); if (!Files.exists(home)) { @@ -83,7 +82,7 @@ /** * Store new arguments required to execute the image. * - * @param args Additional arguments + * @param args Additional arguments. */ public abstract void storeLaunchArgs(List args); } diff -r a0071ded705e src/jdk.jlink/share/classes/jdk/tools/jlink/plugin/Plugin.java --- a/src/jdk.jlink/share/classes/jdk/tools/jlink/plugin/Plugin.java Mon Mar 07 11:25:26 2016 +0100 +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/plugin/Plugin.java Mon Mar 14 13:23:57 2016 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 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 @@ -26,7 +26,6 @@ import java.util.Collections; import java.util.EnumSet; -import java.util.List; import java.util.Map; import java.util.Set; import jdk.tools.jlink.internal.plugins.PluginsResourceBundle; @@ -40,7 +39,6 @@ * Type of plugin. */ public interface PluginType { - public String getName(); } @@ -48,14 +46,14 @@ * Order of categories: *

    *
  1. FILTER: Filter in/out resources or files.
  2. - *
  3. TRANSFORMER: Transform resources or files(eg: refactoring, bytecode + *
  4. TRANSFORMER: Transform resources or files (e.g., refactoring, bytecode * manipulation).
  5. - *
  6. MODULEINFO_TRANSFORMER: Transform only module-info.class
  7. - *
  8. SORTER: Sort resources within the resource container.
  9. - *
  10. COMPRESSOR: Compress resource within the resouce containers.
  11. + *
  12. MODULEINFO_TRANSFORMER: Transform only {@code module-info.class}.
  13. + *
  14. SORTER: Sort resources within resource containers.
  15. + *
  16. COMPRESSOR: Compress resources within resouce containers.
  17. *
  18. VERIFIER: Does some image verification.
  19. *
  20. PROCESSOR: Does some post processing on image.
  21. - *
  22. PACKAGER: Final processing
  23. + *
  24. PACKAGER: Final processing.
  25. *
*/ public enum CATEGORY implements PluginType { @@ -87,8 +85,8 @@ *
  • AUTO_ENABLED: The plugin is enabled by default. It doesn't require its * option to be present to be called.
  • *
  • FUNCTIONAL: The plugin is properly configured and can operate. - * Non functional plugin must advertise their status in the - * {@link #getStateDescription() getStateDescription} method
  • + * Non functional plugins must advertise their status in the + * {@link #getStateDescription()} method. * */ public enum STATE { @@ -98,7 +96,8 @@ } /** - * The Plugin set of types. + * A plugin's set of types. + * * @return The set of types. */ public default Set getType() { @@ -106,7 +105,8 @@ } /** - * The Plugin set of states. + * A plugin's set of states. + * * @return The set of states. */ public default Set getState() { @@ -116,6 +116,7 @@ /** * The set of plugin names that must be located, within the stack of plugins, * before this plugin. + * * @return The set of names. By default this set is empty. */ public default Set isBefore() { @@ -125,6 +126,7 @@ /** * The set of plugin names that must be located, within the stack of plugins, * after this plugin. + * * @return The set of names. By default this set is empty. */ public default Set isAfter() { @@ -133,6 +135,7 @@ /** * The plugin name. + * * @return The name. */ public default String getName() { @@ -141,15 +144,16 @@ /** * The plugin description. - * @return The description. + * + * @return The description. */ public default String getDescription() { return ""; } /** - * The option that identifies this plugin. This may be null. - * "--" is prefixed to the String (when non-null) when invoking + * The option that identifies this plugin. This may be {@code null}. + * "--" is prefixed to the String (when non-{@code null}) when invoking * this plugin from jlink command line. * * @return The plugin option. @@ -159,14 +163,15 @@ } /** - * Has this plugin require one or more arguments? + * Does this plugin require one or more arguments? * A plugin can have one or more optional arguments. - *
    + *

    * A plugin option with a single argument is specified as follows: *

          *     --plugin-option=arg_value
          * 
    - * If there are more than arguments, command line option looks like: + * If there are more than one arguments, the command line option with + * arguments looks like this: *
          *     --plugin-option=arg_value:arg2=value2:arg3=value3...
          *
    @@ -179,7 +184,8 @@ /** * The plugin argument(s) description. - * @return The argument(s) description. + * + * @return The argument(s) description. */ public default String getArgumentsDescription() { return ""; @@ -198,7 +204,7 @@ /** * Configure the plugin based on the passed configuration. - * This method is called prior to invoke the plugin. + * This method is called prior to invoking the plugin. * * @param config The plugin configuration. */ @@ -207,10 +213,10 @@ /** * Configure the plugin based on the passed configuration. - * This method is called prior to invoke the plugin. + * This method is called prior to invoking the plugin. * * @param config The plugin configuration. - * @param ctx The plugin context + * @param ctx The plugin context. */ public default void configure(Map config, PluginContext ctx) { configure(config); diff -r a0071ded705e src/jdk.jlink/share/classes/jdk/tools/jlink/plugin/PluginContext.java --- a/src/jdk.jlink/share/classes/jdk/tools/jlink/plugin/PluginContext.java Mon Mar 07 11:25:26 2016 +0100 +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/plugin/PluginContext.java Mon Mar 14 13:23:57 2016 +0100 @@ -31,7 +31,7 @@ */ public interface PluginContext { /** - * Returns 'release' properties + * Returns 'release' properties. */ public Properties getReleaseProperties(); } diff -r a0071ded705e src/jdk.jlink/share/classes/jdk/tools/jlink/plugin/PluginException.java --- a/src/jdk.jlink/share/classes/jdk/tools/jlink/plugin/PluginException.java Mon Mar 07 11:25:26 2016 +0100 +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/plugin/PluginException.java Mon Mar 14 13:23:57 2016 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 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 @@ -25,7 +25,7 @@ package jdk.tools.jlink.plugin; /** - * An unchecked exception thrown by jlink plugin API for unrecoverable + * An unchecked exception thrown by the jlink plugin API for unrecoverable * conditions. */ public final class PluginException extends RuntimeException { @@ -33,7 +33,6 @@ private static final long serialVersionUID = 7117982019443100395L; public PluginException() { - } public PluginException(Throwable ex) { diff -r a0071ded705e src/jdk.jlink/share/classes/jdk/tools/jlink/plugin/Pool.java --- a/src/jdk.jlink/share/classes/jdk/tools/jlink/plugin/Pool.java Mon Mar 07 11:25:26 2016 +0100 +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/plugin/Pool.java Mon Mar 14 13:23:57 2016 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 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 @@ -43,21 +43,19 @@ /** * Pool of module data. - * */ public abstract class Pool { /** - * Interface to visit the content of a Pool. + * Interface to visit the contents of a Pool. */ public interface Visitor { - /** * Called for each visited ModuleData. * - * @param content A ModuleData - * @return A ModuleData instance or null if the passed ModuleData is to - * be removed from the image. + * @param content A ModuleData instance to visit. + * @return A ModuleData instance or {@code null} if the passed ModuleData + * is to be removed from the image. * @throws PluginException */ public ModuleData visit(ModuleData content); @@ -74,7 +72,6 @@ * */ public static enum ModuleDataType { - CLASS_OR_RESOURCE, CONFIG, NATIVE_CMD, @@ -95,12 +92,12 @@ public String getName(); /** - * Retrieves a ModuleData from a path (e.g: - * /mymodule/com.foo.bar/MyClass.class) + * Retrieves a ModuleData from a path (e.g., + * {@code /mymodule/com.foo.bar/MyClass.class}). * - * @param path The piece of data path. - * @return A ModuleData or null if the path doesn't identify a - * ModuleData. + * @param path A data path. + * @return A ModuleData or {@code null} if the path doesn't identify a + * ModuleData. */ public ModuleData get(String path); @@ -126,7 +123,7 @@ public Set getAllPackages(); /** - * Retrieves the collection of ModuleData. + * Retrieves the collection of ModuleData for this module. * * @return The ModuleData collection. */ @@ -178,7 +175,7 @@ @Override public void add(ModuleData data) { if (isReadOnly()) { - throw new PluginException("pool is readonly"); + throw new PluginException("pool is read-only"); } Objects.requireNonNull(data); if (!data.getModule().equals(name)) { @@ -193,7 +190,7 @@ Set pkgs = new HashSet<>(); moduleContent.values().stream().filter(m -> m.getType(). equals(ModuleDataType.CLASS_OR_RESOURCE)).forEach((res) -> { - // Module metadata only contains packages with .class files + // module meta-data only contains packages with .class files if (ImageFileCreator.isClassPackage(res.getPath())) { String[] split = ImageFileCreator.splitPath(res.getPath()); String pkg = split[1]; @@ -217,16 +214,16 @@ } /** - * A ModuleData is the elementary unit of data inside an image. It is - * generally a file. e.g.: a java class file, a resource file, a shared - * library, ... - *
    - * A ModuleData is identified by a path of the form: + * A ModuleData instance represents an elementary unit of data inside an + * image. It is generally a file, e.g., a Java class file, a resource file, + * a shared library, etc. + *

    + * A ModuleData is identified by a path of one of the following forms: *

      - *
    • For jimage content: /{module name}/{package1}>/.../{packageN}/{file - * name}
    • - *
    • For other files (shared lib, launchers, config, ...):/{module name>}/ - * {@literal }/{dir1}>/.../{dirN}/{file name}
    • + *
    • For jimage content: + * {@code /{module name}/{package1}/.../{packageN}/{file name}}
    • + *
    • For other files (shared library, launchers, config, ...): + * {@code /{module name>}//{dir1}>/.../{dirN}/{file name}}
    • *
    */ public static class ModuleData { @@ -239,7 +236,7 @@ private byte[] buffer; /** - * Create a new ModuleData. + * Create a new ModuleData instance. * * @param module The module name. * @param path The data path identifier. @@ -288,9 +285,9 @@ } /** - * The ModuleData content as an array of byte. + * The ModuleData content as an array of {@code byte}. * - * @return An Array of bytes. + * @return The raw ModuleData contents. */ public byte[] getBytes() { if (buffer == null) { @@ -359,7 +356,7 @@ } /** - * Read only state. No data can be added to a ReadOnly Pool. + * Read-only state. No data can be added to a read-only pool. * * @return true if readonly false otherwise. */ @@ -397,8 +394,8 @@ /** * Retrieves the module for the provided name. * - * @param name The module name - * @return the module or null if the module doesn't exist. + * @param name The module name. + * @return the module or {@code null} if the module doesn't exist. */ public Module getModule(String name) { Objects.requireNonNull(name); @@ -417,7 +414,7 @@ /** * Get all ModuleData contained in this pool instance. * - * @return The collection of resources; + * @return The collection of resources. */ public Collection getContent() { return Collections.unmodifiableCollection(resources.values()); @@ -426,8 +423,8 @@ /** * Get the ModuleData for the passed path. * - * @param path A data path - * @return A ModuleData instance or null if the data is not found + * @param path A data path. + * @return A ModuleData instance or {@code null} if the data is not found. */ public ModuleData get(String path) { Objects.requireNonNull(path); @@ -438,7 +435,7 @@ * Check if the pool contains this data. * * @param data The module data to check existence for. - * @return The module data or null if not found. + * @return The module data or {@code null} if not found. */ public boolean contains(ModuleData data) { Objects.requireNonNull(data); @@ -446,9 +443,10 @@ } /** - * Check if the Pool contains some content. + * Check whether the pool contains no content. * - * @return True, no content, false otherwise. + * @return {@code true} iff the pool contains no content; + * {@code false} otherwise. */ public boolean isEmpty() { return resources.isEmpty(); @@ -458,7 +456,7 @@ * Visit the pool. * * @param visitor The Visitor called for each ModuleData found in the pool. - * @param output The pool to be filled with Visitor returned ModuleData. + * @param output The pool to be filled with Visitor-returned ModuleData. */ public void visit(Visitor visitor, Pool output) { for (ModuleData resource : getContent()) { @@ -480,9 +478,9 @@ /** * Create a ModuleData located inside a jimage file. Such ModuleData has a - * ModuleDataType being equals to CLASS_OR_RESOURCE. + * ModuleDataType equal to CLASS_OR_RESOURCE. * - * @param path The complete resource path (contains the module radical). + * @param path The complete resource path (contains the module root). * @param content The resource content. * @param size The content size. * @return A new ModuleData. @@ -503,8 +501,7 @@ * @return A new ModuleData. */ public static ModuleData newResource(String path, byte[] content) { - return newResource(path, new ByteArrayInputStream(content), - content.length); + return newResource(path, new ByteArrayInputStream(content), content.length); } /** diff -r a0071ded705e src/jdk.jlink/share/classes/jdk/tools/jlink/plugin/PostProcessorPlugin.java --- a/src/jdk.jlink/share/classes/jdk/tools/jlink/plugin/PostProcessorPlugin.java Mon Mar 07 11:25:26 2016 +0100 +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/plugin/PostProcessorPlugin.java Mon Mar 14 13:23:57 2016 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 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 @@ -27,13 +27,12 @@ import java.util.List; /** - * Implement this interface to develop a PostProcessor plugin. - * PostProcessor plugins are called once the image has been generated and is executable. - **/ + * Implement this interface to develop a post-processor plugin. Post-processor + * plugins are called once the image has been generated and is executable. + */ public interface PostProcessorPlugin extends Plugin { - /** - * Post process an image. + * Post-process an image. * * @param image The executable image. * @return The list of arguments to add to launchers (if any). diff -r a0071ded705e src/jdk.jlink/share/classes/jdk/tools/jlink/plugin/TransformerPlugin.java --- a/src/jdk.jlink/share/classes/jdk/tools/jlink/plugin/TransformerPlugin.java Mon Mar 07 11:25:26 2016 +0100 +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/plugin/TransformerPlugin.java Mon Mar 14 13:23:57 2016 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 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 @@ -24,19 +24,18 @@ */ package jdk.tools.jlink.plugin; - /** - * Implement this interface to develop a Transformer plugin. - * TransformerPlugin are called during image creation. This kind of plugin aims to - * modify the content of the runtime image. + * Implement this interface to develop a transformer plugin. Transformer plugins + * are called during image creation. This kind of plugin aims to modify the + * contents of the runtime image. */ public interface TransformerPlugin extends Plugin { /** - * Visit the content of the modules that are composing the image. + * Visit the content of the modules constituting the image. * - * @param in Read only content. + * @param in Read-only content. * @param out The pool to fill with content. This pool must contain - * the result of the visit. + * the result of the visit. * * @throws PluginException */ diff -r a0071ded705e src/jdk.jlink/share/classes/jdk/tools/jlink/resources/jlink.properties --- a/src/jdk.jlink/share/classes/jdk/tools/jlink/resources/jlink.properties Mon Mar 07 11:25:26 2016 +0100 +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/resources/jlink.properties Mon Mar 14 13:23:57 2016 +0100 @@ -43,18 +43,18 @@ An exception has occurred in jlink. \ Please file a bug at the Java Bug Database (http://bugreport.java.com/bugreport/) \ after checking the database for duplicates. \ -Include your program and the following diagnostic in your report. Thank you. +Include your program and the following diagnostic in your report. Thank you. main.extended.help=\ List of available plugins: -err.unknown.byte.order:unknown byte order {0} -err.output.must.be.specified:--output must be specified -err.modulepath.must.be.specified:--modulepath must be specified -err.mods.must.be.specified:no modules specified to {0} +err.unknown.byte.order=unknown byte order {0} +err.output.must.be.specified=--output must be specified +err.modulepath.must.be.specified=--modulepath must be specified +err.mods.must.be.specified=no modules specified to {0} err.path.not.found=path not found: {0} err.path.not.valid=invalid path: {0} -err.existing.image.must.exist=existing image doesn't exists or is not a directory +err.existing.image.must.exist=existing image doesn't exist or is not a directory err.existing.image.invalid=existing image is not valid err.file.not.found=cannot find file: {0} err.file.error=cannot access file: {0} @@ -69,5 +69,5 @@ err.config.defaults=property {0} is missing from configuration err.config.defaults.value=wrong value in defaults property: {0} err.bom.generation=bom file generation failed: {0} -warn.invalid.arg=Invalid classname or pathname not exist: {0} +warn.invalid.arg=Invalid class name, or path does not exist: {0} warn.split.package=package {0} defined in {1} {2} diff -r a0071ded705e src/jdk.jlink/share/classes/jdk/tools/jlink/resources/plugins.properties --- a/src/jdk.jlink/share/classes/jdk/tools/jlink/resources/plugins.properties Mon Mar 07 11:25:26 2016 +0100 +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/resources/plugins.properties Mon Mar 14 13:23:57 2016 +0100 @@ -16,11 +16,11 @@ compress.description=\ Compress all resources in the output image.\n\ -Level 0: constant string sharing\n\ -Level 1: ZIP\n\ +Level 0: constant string sharing,\n\ +Level 1: ZIP,\n\ Level 2: both.\n\ An optional filter can be specified to list the pattern of files to be filtered.\n\ -Use ^ for negation. eg: *Exception.class,*Error.class,^/java.base/java/lang/* +Use ^ for negation. For example: *Exception.class,*Error.class,^/java.base/java/lang/* compact-cp.argument= @@ -31,18 +31,18 @@ copy-files.argument== to copy to the image>. copy-files.description=\ -If files to copy are not absolute path, JDK home dir is used.\n\ -eg: jrt-fs.jar,LICENSE,/home/me/myfile.txt=somewehere/conf.txt +If files to copy are not absolute paths, JDK home dir is used.\n\ +For example: jrt-fs.jar,LICENSE,/home/me/myfile.txt=somewehere/conf.txt -exclude-files.argument= +exclude-files.argument= exclude-files.description=\ -Specify files to exclude. eg: *.diz, /java.base/native/client/* +Specify files to exclude. For example: *.diz, /java.base/native/client/* exclude-resources.argument= exclude-resources.description=\ -Specify resources to exclude. eg: *.jcov, */META-INF/* +Specify resources to exclude. For example: *.jcov, */META-INF/* installed-modules.description=Fast loading of module descriptors (always enabled) @@ -51,7 +51,7 @@ sort-resources.argument= sort-resources.description=\ -Sort resources. eg: */modules-info.class,/java-base/java/lang/* +Sort resources. For example: */modules-info.class,/java-base/java/lang/* strip-debug.description=\ Strip debug information from the output image @@ -62,7 +62,7 @@ vm.argument= vm.description=\ -Select the HotSpot VM in the output image. Default is all +Select the HotSpot VM in the output image. Default is all zip.argument=[comma separated list of resource paths] @@ -70,7 +70,7 @@ main.status.ok=Functional. -main.status.not.ok= Not functional. +main.status.not.ok=Not functional. plugin.plugins.header=\ List of available plugin options: @@ -143,7 +143,7 @@ err.plugin.option.not.set=Option {0} must be set. warn.thirdparty.plugins=\ -Enabling third party plugins can lead to unusable generated image. +Enabling third-party plugins can lead to an unusable generated image. warn.thirdparty.plugins.enabled=\ -You have enabled third party plugins. +You have enabled third-party plugins. diff -r a0071ded705e src/jdk.jlink/share/classes/review-comments.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.jlink/share/classes/review-comments.txt Mon Mar 14 13:23:57 2016 +0100 @@ -0,0 +1,104 @@ +Open questions: + +* JLink + - JlinkConfiguration, ctor, output dir must not exist + Is this enforced? Where? + +* ImageBuilder + - all methods: under which circumstances is PluginException thrown? + - storeFiles default implementation discards release notes argument. + a note on that would be good (@implNote) + +* DefaultImageBuilder + - patchScripts: time to remove? + +* AsmPool, AsmGlobalPool, AsmModulePool, AsmPlugin + - declared exceptions throughout: when are they thrown? + +* AsmPools + - is the poolsArray field *really* needed? it's used from only one client, and that doesn't look as if it depended + on the order of modules in the array + +* optim/Utils + - suppressBlocks: sure that it.remove() can't happen more than once? what would be the effect? + +* optim/ReflectionOptimizer + - replaceWithClassConstant - where does the comment "// virtual node, not taken into account" actually belong? + - should those methods rather throw PluginException? + - TypeResolver shouldn't be declared here; it is required by the MethodOptimizer plugin (moving it elsewhere would + also allow for making ReflectionOptimizer package-private - no need for this class to be public at all) + +* optim/ForNameFolding + - TODO comment: address this like in ReflectionOptimizer? or does ReflectionOptimizer cover that? it seems the "can we + load the type" material in ReflectionOptimizer.replaceWithClassConstant does that. + +* optim/ControlFlow + - ClosureBuilder.addAll: all thore requireNonNull calls ... are they supposed to throw really, or should nulls just be + ignored? + - shouldn't buildBlocks rather throw PluginException? + +* Plugin + - move documentation for enum instances to enum instances rather than in enum class comment + - enums CATEGORY, STATE - naming convention, anyone? + - enum CATEGORY - why does it implement an extra interface (PluginType)? the interface should go away, and this enum + should be named PluginType. Code in internal/Utils seems to suggest there can be non-CATEGORY classes that implement + PluginType, but there is no other class implementing this interface. + - CATEGORY is a bit strange; it appears it is possible for a plugin to have more than one category. How is it enforced + that no nonsensical combinations occur? Why is the default "no category"? Does this even make sense? + - STATE is really problematic. Can a plugin be in more than one state, e.g., AUTO_ENABLED and FUNCTIONAL? If so, what + prevents the plugin from being put into a combination of states that is not sensible, e.g., DISABLED and + AUTO_ENABLED? getState returns an EnumSet - a state should be a single value, not a combination thereof. Why is + FUNCTIONAL the default? In fact, AUTO_ENABLED should imply FUNCTIONAL, so that there should actually be a total + order of states. It seems InstalledModuleDescriptorPlugin is the only plugin that uses more than one state + simultaneously. + - isBefore/isAfter are very badly named (they sound like predicates, but aren't); better: precedingPlugins/ + succeedingPlugins + - getOption: how is the option chosen when this method returns null? + - hasArguments: for >1 arguments, why not arg1=val1:arg2=val2:... + +* Plugin hierarchy + - proposal: add default implementation for getDescription(): return PluginsResourceBundle.getDescription(getName()) + - proposal: add default implementation for getArgumentsDescription(): return PluginsResourceBundle.getArgument(getName()) + - proposal: don't use a NAME constant in plugins, but rather return the string from getName() and use this getter + - configure() methods: shouldn't they all throw PluginException rather than IOException? + - some other methods also throw UncheckedIOException, shouldn't they also throw PluginException? + +* PluginContext + - what is a "release property"? + +* TransformerPlugin + - under what circumstances is the PluginException supposed to be thrown? + +* plugin/Pool + - under what circumstances are PluginExceptions supposed to be thrown? + - enum ModuleDataType: move doc to enum elements + - add: TODO comment about FileCopierPlugin + +* ZipPlugin + - unused constructor for String[] - remove, or is it used by reflection somewhere? + - compression logic simply returns uncompressed data in case of IOException - that OK? + +* StripDebugPlugin + - TODO comment about debug info and ASM + +* ReleaseInfoPlugin + - configure: long comment does not parse properly + - process: is it appropriate for configure to do all the work? Isn't there some potential for trouble? + +* SortResourcesPlugin + - formatting of stream sequences - choose a unified format? + +* OptimizationPlugin + - couldn't the two optimizer interfaces just extend AutoCloseable, and the close() implementation be replaced by a + try(){} block? + +* InstalledModuleDescriptorPlugin + - conceals: shouldn't it throw PluginException rather than AssertionError? + +* internal/Utils + - the various checks for isPost/isPre/... should really be properties of the plugin category enum, and/or of Plugin + - consequently, the Utils class could be significantly simplified or even go away in its entirety + +Follow-up RFEs: + +* Remove BOM file support altogether.