8159206: All jlink or jmod tests failing
authorjlaskey
Thu, 16 Jun 2016 09:09:53 -0300
changeset 39042 52db877f18db
parent 39041 347b1b47ce21
child 39043 815e52744068
8159206: All jlink or jmod tests failing Reviewed-by: alanb, mchung
jdk/src/java.base/share/classes/jdk/internal/jrtfs/JrtUtils.java
jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/Utils.java
jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/DefaultCompressPlugin.java
jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/ExcludeFilesPlugin.java
jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/ExcludePlugin.java
jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/ExcludeVMPlugin.java
jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/FileCopierPlugin.java
jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/IncludeLocalesPlugin.java
jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/OrderResourcesPlugin.java
jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/ReleaseInfoPlugin.java
jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/ResourceFilter.java
jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/StringSharingPlugin.java
jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/StripDebugPlugin.java
jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/ZipPlugin.java
jdk/src/jdk.jlink/share/classes/jdk/tools/jmod/JmodTask.java
jdk/test/ProblemList.txt
jdk/test/tools/jlink/JLinkOptimTest.java
jdk/test/tools/jlink/plugins/CompressorPluginTest.java
jdk/test/tools/jlink/plugins/ExcludeFilesPluginTest.java
jdk/test/tools/jlink/plugins/ExcludePluginTest.java
jdk/test/tools/jlink/plugins/OrderResourcesPluginTest.java
jdk/test/tools/jlink/plugins/ResourceFilterTest.java
--- a/jdk/src/java.base/share/classes/jdk/internal/jrtfs/JrtUtils.java	Wed Jun 15 23:24:08 2016 +0000
+++ b/jdk/src/java.base/share/classes/jdk/internal/jrtfs/JrtUtils.java	Thu Jun 16 09:09:53 2016 -0300
@@ -45,7 +45,7 @@
     private static boolean isGlobMeta(char c) {
         return globMetaChars.indexOf(c) != -1;
     }
-    private static final char EOL = 0;  //TBD
+    private static final char EOL = 0;
     private static char next(String glob, int i) {
         if (i < glob.length()) {
             return glob.charAt(i);
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/Utils.java	Wed Jun 15 23:24:08 2016 +0000
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/Utils.java	Thu Jun 16 09:09:53 2016 -0300
@@ -28,77 +28,85 @@
 import java.net.URI;
 import java.nio.file.FileSystem;
 import java.nio.file.FileSystems;
+import java.nio.file.Path;
 import java.nio.file.PathMatcher;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Comparator;
 import java.util.List;
-import java.util.function.Function;
+import java.util.Objects;
+import java.util.Set;
+import java.util.stream.Collectors;
 import jdk.tools.jlink.plugin.Plugin;
+import jdk.tools.jlink.plugin.Plugin.Category;
 
 public class Utils {
 
     private Utils() {}
 
+    // jrt-fs file system
+    private static FileSystem JRT_FILE_SYSTEM;
+
     // current module
     private static final Module THIS_MODULE = Utils.class.getModule();
 
-    public static final Function<String, String[]> listParser = (argument) -> {
-        String[] arguments = null;
-        if (argument != null) {
-            arguments = argument.split(",");
-            for (int i = 0; i < arguments.length; i++) {
-                arguments[i] = arguments[i].trim();
-            }
-        }
-        return arguments;
-    };
+    public static List<String> parseList(String arguments) {
+        return Arrays.stream(arguments.split(","))
+                     .map((p) -> p.trim())
+                     .filter((p) -> !p.isEmpty())
+                     .collect(Collectors.toList());
+    }
 
-    public static boolean isPostProcessor(Plugin.Category category) {
-        return category.equals(Plugin.Category.VERIFIER)
-                || category.equals(Plugin.Category.PROCESSOR)
-                || category.equals(Plugin.Category.PACKAGER);
+    public static boolean isPostProcessor(Category category) {
+        return category.equals(Category.VERIFIER)
+                || category.equals(Category.PROCESSOR)
+                || category.equals(Category.PACKAGER);
     }
 
-    public static boolean isPreProcessor(Plugin.Category category) {
-        return category.equals(Plugin.Category.COMPRESSOR)
-                || category.equals(Plugin.Category.FILTER)
-                || category.equals(Plugin.Category.MODULEINFO_TRANSFORMER)
-                || category.equals(Plugin.Category.SORTER)
-                || category.equals(Plugin.Category.TRANSFORMER)
-                || category.equals(Plugin.Category.METAINFO_ADDER);
+    public static boolean isPreProcessor(Category category) {
+        return category.equals(Category.COMPRESSOR)
+                || category.equals(Category.FILTER)
+                || category.equals(Category.MODULEINFO_TRANSFORMER)
+                || category.equals(Category.SORTER)
+                || category.equals(Category.TRANSFORMER)
+                || category.equals(Category.METAINFO_ADDER);
     }
 
-    public static boolean isPostProcessor(Plugin prov) {
-        if (prov.getType() != null) {
-            for (Plugin.Category pt : prov.getType()) {
-                if (pt instanceof Plugin.Category) {
-                    return isPostProcessor(pt);
-                }
-            }
+    public static boolean isPostProcessor(Plugin provider) {
+        Set<Category> types = provider.getType();
+        Objects.requireNonNull(types);
+        for (Category pt : types) {
+            return isPostProcessor(pt);
         }
         return false;
     }
 
-    public static boolean isPreProcessor(Plugin prov) {
-        if (prov.getType() != null) {
-            for (Plugin.Category pt : prov.getType()) {
-                if (pt instanceof Plugin.Category) {
-                    return isPreProcessor(pt);
-                }
-            }
+    public static boolean isPreProcessor(Plugin provider) {
+        Set<Category> types = provider.getType();
+        Objects.requireNonNull(types);
+        for (Category pt : types) {
+            return isPreProcessor(pt);
         }
         return false;
     }
 
-    public static Plugin.Category getCategory(Plugin provider) {
-        if (provider.getType() != null) {
-            for (Plugin.Category t : provider.getType()) {
-                if (t instanceof Plugin.Category) {
-                    return t;
-                }
+    public static Category getCategory(Plugin provider) {
+        Set<Category> types = provider.getType();
+        Objects.requireNonNull(types);
+        for (Category t : types) {
+            return t;
+        }
+        return null;
+    }
+
+    public static List<Plugin> getPreProcessors(List<Plugin> plugins) {
+        List<Plugin> res = new ArrayList<>();
+        for (Plugin p : plugins) {
+            if (isPreProcessor(p)) {
+                res.add(p);
             }
         }
-        return null;
+        return res;
     }
 
     public static List<Plugin> getPostProcessors(List<Plugin> plugins) {
@@ -133,16 +141,6 @@
         return res;
     }
 
-    public static List<Plugin> getPreProcessors(List<Plugin> plugins) {
-        List<Plugin> res = new ArrayList<>();
-        for (Plugin p : plugins) {
-            if (isPreProcessor(p)) {
-                res.add(p);
-            }
-        }
-        return res;
-    }
-
     public static boolean isFunctional(Plugin prov) {
         return prov.getState().contains(Plugin.State.FUNCTIONAL);
     }
@@ -161,7 +159,11 @@
     }
 
     public static FileSystem jrtFileSystem() {
-        return FileSystems.getFileSystem(URI.create("jrt:/"));
+        if (JRT_FILE_SYSTEM == null) {
+            JRT_FILE_SYSTEM = FileSystems.getFileSystem(URI.create("jrt:/"));
+        }
+
+        return JRT_FILE_SYSTEM;
     }
 
     public static PathMatcher getPathMatcher(FileSystem fs, String pattern) {
@@ -172,7 +174,11 @@
         return fs.getPathMatcher(pattern);
     }
 
-    public static PathMatcher getPathMatcher(String pattern) {
+    public static PathMatcher getJRTFSPathMatcher(String pattern) {
         return getPathMatcher(jrtFileSystem(), pattern);
     }
+
+    public static Path getJRTFSPath(String first, String... more) {
+        return jrtFileSystem().getPath(first, more);
+    }
 }
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/DefaultCompressPlugin.java	Wed Jun 15 23:24:08 2016 +0000
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/DefaultCompressPlugin.java	Thu Jun 16 09:09:53 2016 -0300
@@ -24,8 +24,6 @@
  */
 package jdk.tools.jlink.internal.plugins;
 
-import java.io.IOException;
-import java.io.UncheckedIOException;
 import java.util.Collections;
 import java.util.HashSet;
 import java.util.Map;
@@ -37,7 +35,6 @@
 import jdk.tools.jlink.internal.ImagePluginStack;
 import jdk.tools.jlink.internal.ResourcePrevisitor;
 import jdk.tools.jlink.internal.StringTable;
-import jdk.tools.jlink.internal.Utils;
 
 /**
  *
@@ -103,33 +100,26 @@
 
     @Override
     public void configure(Map<String, String> config) {
-        try {
-            String filter = config.get(FILTER);
-            String[] patterns = filter == null ? null
-                    : Utils.listParser.apply(filter);
-            ResourceFilter resFilter = new ResourceFilter(patterns);
-            String level = config.get(NAME);
-            if (level != null) {
-                switch (level) {
-                    case LEVEL_0:
-                        ss = new StringSharingPlugin(resFilter);
-                        break;
-                    case LEVEL_1:
-                        zip = new ZipPlugin(resFilter);
-                        break;
-                    case LEVEL_2:
-                        ss = new StringSharingPlugin(resFilter);
-                        zip = new ZipPlugin(resFilter);
-                        break;
-                    default:
-                        throw new IllegalArgumentException("Invalid compression level " + level);
-                }
-            } else {
-                ss = new StringSharingPlugin(resFilter);
-                zip = new ZipPlugin(resFilter);
+        ResourceFilter resFilter = ResourceFilter.includeFilter(config.get(FILTER));
+        String level = config.get(NAME);
+        if (level != null) {
+            switch (level) {
+                case LEVEL_0:
+                    ss = new StringSharingPlugin(resFilter);
+                    break;
+                case LEVEL_1:
+                    zip = new ZipPlugin(resFilter);
+                    break;
+                case LEVEL_2:
+                    ss = new StringSharingPlugin(resFilter);
+                    zip = new ZipPlugin(resFilter);
+                    break;
+                default:
+                    throw new IllegalArgumentException("Invalid compression level " + level);
             }
-        } catch (IOException ex) {
-            throw new UncheckedIOException(ex);
+        } else {
+            ss = new StringSharingPlugin(resFilter);
+            zip = new ZipPlugin(resFilter);
         }
     }
 }
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/ExcludeFilesPlugin.java	Wed Jun 15 23:24:08 2016 +0000
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/ExcludeFilesPlugin.java	Thu Jun 16 09:09:53 2016 -0300
@@ -24,7 +24,6 @@
  */
 package jdk.tools.jlink.internal.plugins;
 
-import java.io.IOException;
 import java.io.UncheckedIOException;
 import java.util.Collections;
 import java.util.HashSet;
@@ -84,11 +83,6 @@
 
     @Override
     public void configure(Map<String, String> config) {
-        try {
-            String value = config.get(NAME);
-            predicate = new ResourceFilter(Utils.listParser.apply(value), true);
-        } catch (IOException ex) {
-            throw new UncheckedIOException(ex);
-        }
+        predicate = ResourceFilter.excludeFilter(config.get(NAME));
     }
 }
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/ExcludePlugin.java	Wed Jun 15 23:24:08 2016 +0000
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/ExcludePlugin.java	Thu Jun 16 09:09:53 2016 -0300
@@ -24,17 +24,14 @@
  */
 package jdk.tools.jlink.internal.plugins;
 
-import java.io.IOException;
 import java.util.Collections;
 import java.util.HashSet;
 import java.util.Map;
 import java.util.Set;
 import java.util.function.Predicate;
-import jdk.tools.jlink.plugin.PluginException;
 import jdk.tools.jlink.plugin.TransformerPlugin;
 import jdk.tools.jlink.plugin.ModuleEntry;
 import jdk.tools.jlink.plugin.ModulePool;
-import jdk.tools.jlink.internal.Utils;
 
 /**
  *
@@ -84,11 +81,6 @@
 
     @Override
     public void configure(Map<String, String> config) {
-        try {
-            String val = config.get(NAME);
-            predicate = new ResourceFilter(Utils.listParser.apply(val), true);
-        } catch (IOException ex) {
-            throw new PluginException(ex);
-        }
+        predicate = ResourceFilter.excludeFilter(config.get(NAME));
     }
 }
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/ExcludeVMPlugin.java	Wed Jun 15 23:24:08 2016 +0000
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/ExcludeVMPlugin.java	Thu Jun 16 09:09:53 2016 -0300
@@ -40,9 +40,7 @@
 import java.util.function.Predicate;
 import java.util.stream.Collectors;
 import jdk.tools.jlink.plugin.TransformerPlugin;
-import jdk.tools.jlink.plugin.ModuleEntry;
 import jdk.tools.jlink.plugin.ModulePool;
-import jdk.tools.jlink.internal.Utils;
 import jdk.tools.jlink.plugin.ModuleEntry;
 import jdk.tools.jlink.plugin.PluginException;
 
@@ -184,38 +182,34 @@
 
     @Override
     public void configure(Map<String, String> config) {
-        try {
-            String value = config.get(NAME);
-            String exclude = "";
-            switch (value) {
-                case ALL: {
-                    // no filter.
-                    keepAll = true;
-                    break;
-                }
-                case CLIENT: {
-                    target = Jvm.CLIENT;
-                    exclude = "/java.base/native*server/*,/java.base/native*minimal/*";
-                    break;
-                }
-                case SERVER: {
-                    target = Jvm.SERVER;
-                    exclude = "/java.base/native*client/*,/java.base/native*minimal/*";
-                    break;
-                }
-                case MINIMAL: {
-                    target = Jvm.MINIMAL;
-                    exclude = "/java.base/native*server/*,/java.base/native*client/*";
-                    break;
-                }
-                default: {
-                    throw new IllegalArgumentException("Unknown exclude VM option: " + value);
-                }
+        String value = config.get(NAME);
+        String exclude = "";
+        switch (value) {
+            case ALL: {
+                // no filter.
+                keepAll = true;
+                break;
+            }
+            case CLIENT: {
+                target = Jvm.CLIENT;
+                exclude = "/java.base/native**server/**,/java.base/native**minimal/**";
+                break;
             }
-            predicate = new ResourceFilter(Utils.listParser.apply(exclude), true);
-        } catch (IOException ex) {
-            throw new UncheckedIOException(ex);
+            case SERVER: {
+                target = Jvm.SERVER;
+                exclude = "/java.base/native**client/**,/java.base/native**minimal/**";
+                break;
+            }
+            case MINIMAL: {
+                target = Jvm.MINIMAL;
+                exclude = "/java.base/native**server/**,/java.base/native**client/**";
+                break;
+            }
+            default: {
+                throw new IllegalArgumentException("Unknown exclude VM option: " + value);
+            }
         }
+        predicate = ResourceFilter.excludeFilter(exclude);
     }
 
     private ModuleEntry handleJvmCfgFile(ModuleEntry orig,
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/FileCopierPlugin.java	Wed Jun 15 23:24:08 2016 +0000
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/FileCopierPlugin.java	Thu Jun 16 09:09:53 2016 -0300
@@ -196,14 +196,13 @@
 
     @Override
     public void configure(Map<String, String> config) {
-        String val = config.get(NAME);
-        String[] argument = Utils.listParser.apply(val);
-        if (argument == null || argument.length == 0) {
+        List<String> arguments = Utils.parseList(config.get(NAME));
+        if (arguments.isEmpty()) {
             throw new RuntimeException("Invalid argument for " + NAME);
         }
 
         String javahome = System.getProperty("java.home");
-        for (String a : argument) {
+        for (String a : arguments) {
             int i = a.indexOf("=");
             CopiedFile cf = new CopiedFile();
             if (i == -1) {
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/IncludeLocalesPlugin.java	Wed Jun 15 23:24:08 2016 +0000
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/IncludeLocalesPlugin.java	Thu Jun 16 09:09:53 2016 -0300
@@ -25,8 +25,6 @@
 package jdk.tools.jlink.internal.plugins;
 
 import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.UncheckedIOException;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashSet;
@@ -44,7 +42,6 @@
 import jdk.internal.org.objectweb.asm.ClassReader;
 import jdk.tools.jlink.internal.ResourcePrevisitor;
 import jdk.tools.jlink.internal.StringTable;
-import jdk.tools.jlink.internal.Utils;
 import jdk.tools.jlink.plugin.LinkModule;
 import jdk.tools.jlink.plugin.ModuleEntry;
 import jdk.tools.jlink.plugin.PluginException;
@@ -209,14 +206,10 @@
                 String.format(PluginsResourceBundle.getMessage(NAME + ".nomatchinglocales"), userParam));
         }
 
-        try {
-            String value = META_FILES + filtered.stream()
-                .map(s -> includeLocaleFilePatterns(s))
-                .collect(Collectors.joining(","));
-            predicate = new ResourceFilter(Utils.listParser.apply(value), false);
-        } catch (IOException ex) {
-            throw new UncheckedIOException(ex);
-        }
+        String value = META_FILES + filtered.stream()
+            .map(s -> includeLocaleFilePatterns(s))
+            .collect(Collectors.joining(","));
+        predicate = ResourceFilter.includeFilter(value);
     }
 
     private String includeLocaleFilePatterns(String tag) {
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/OrderResourcesPlugin.java	Wed Jun 15 23:24:08 2016 +0000
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/OrderResourcesPlugin.java	Thu Jun 16 09:09:53 2016 -0300
@@ -167,8 +167,7 @@
 
     @Override
     public void configure(Map<String, String> config) {
-        String val = config.get(NAME);
-        String[] patterns = Utils.listParser.apply(val);
+        List<String> patterns = Utils.parseList(config.get(NAME));
         int ordinal = 0;
 
         for (String pattern : patterns) {
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/ReleaseInfoPlugin.java	Wed Jun 15 23:24:08 2016 +0000
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/ReleaseInfoPlugin.java	Thu Jun 16 09:09:53 2016 -0300
@@ -97,10 +97,9 @@
 
             case "del": {
                 // --release-info del:keys=openjdk,java_version
-                String[] keys = Utils.listParser.apply(config.get(KEYS));
-                for (String k : keys) {
+                Utils.parseList(config.get(KEYS)).stream().forEach((k) -> {
                     release.remove(k);
-                }
+                });
             }
             break;
 
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/ResourceFilter.java	Wed Jun 15 23:24:08 2016 +0000
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/ResourceFilter.java	Thu Jun 16 09:09:53 2016 -0300
@@ -26,12 +26,13 @@
 
 import java.io.File;
 import java.io.IOException;
-import java.nio.file.FileSystem;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.PathMatcher;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
+import java.util.Objects;
 import java.util.function.Predicate;
 import jdk.tools.jlink.internal.Utils;
 import jdk.tools.jlink.plugin.PluginException;
@@ -41,17 +42,14 @@
  * Filter resource resources using path matcher.
  */
 public class ResourceFilter implements Predicate<String> {
-    private static final FileSystem JRT_FILE_SYSTEM = Utils.jrtFileSystem();
-
-    final boolean negate;
-    final List<PathMatcher> matchers;
+    private final static List<String> EMPTY_LIST = Collections.emptyList();
 
-    public ResourceFilter(String[] patterns) throws IOException {
-        this(patterns, false);
-    }
+    private final List<PathMatcher> matchers;
+    private final boolean include;
+    private final boolean otherwise;
 
-    public ResourceFilter(String[] patterns, boolean negate) throws IOException {
-        this.negate = negate;
+    private ResourceFilter(List<String> patterns, boolean exclude) {
+        Objects.requireNonNull(patterns);
         this.matchers = new ArrayList<>();
 
         for (String pattern : patterns) {
@@ -67,28 +65,59 @@
                         throw new PluginException(ex);
                     }
 
-                    for (String line : lines) {
-                        PathMatcher matcher = Utils.getPathMatcher(JRT_FILE_SYSTEM, line);
-                        matchers.add(matcher);
-                    }
+                    lines.stream().forEach((line) -> {
+                        matchers.add(Utils.getJRTFSPathMatcher(line.trim()));
+                    });
+                } else {
+                    System.err.println("warning - the filter file " + file +
+                                       " is empty or not present.");
                 }
             } else {
-                PathMatcher matcher = Utils.getPathMatcher(JRT_FILE_SYSTEM, pattern);
-                matchers.add(matcher);
+                matchers.add(Utils.getJRTFSPathMatcher(pattern));
             }
         }
+
+        this.include = !exclude;
+        this.otherwise = exclude || this.matchers.isEmpty();
+    }
+
+    public static ResourceFilter includeFilter(List<String> patterns) {
+        Objects.requireNonNull(patterns);
+        return new ResourceFilter(patterns, false);
+    }
+
+    public static ResourceFilter includeFilter(String patterns) {
+        if (patterns == null) {
+            return includeFilter(EMPTY_LIST);
+        }
+
+        return includeFilter(Utils.parseList(patterns));
+    }
+
+    public static ResourceFilter excludeFilter(List<String> patterns) {
+        Objects.requireNonNull(patterns);
+        return new ResourceFilter(patterns, true);
+    }
+
+    public static ResourceFilter excludeFilter(String patterns) {
+        if (patterns == null) {
+            return excludeFilter(EMPTY_LIST);
+        }
+
+        return excludeFilter(Utils.parseList(patterns));
     }
 
     @Override
     public boolean test(String name) {
-        Path path = JRT_FILE_SYSTEM.getPath(name);
+        Objects.requireNonNull(name);
+        Path path = Utils.getJRTFSPath(name);
 
         for (PathMatcher matcher : matchers) {
             if (matcher.matches(path)) {
-                return !negate;
+                return include;
             }
         }
 
-        return negate;
+        return otherwise;
     }
 }
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/StringSharingPlugin.java	Wed Jun 15 23:24:08 2016 +0000
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/StringSharingPlugin.java	Thu Jun 16 09:09:53 2016 -0300
@@ -63,7 +63,6 @@
 import jdk.tools.jlink.plugin.ModulePool;
 import jdk.tools.jlink.internal.ResourcePrevisitor;
 import jdk.tools.jlink.internal.StringTable;
-import jdk.tools.jlink.internal.Utils;
 
 /**
  *
@@ -335,12 +334,8 @@
 
     private Predicate<String> predicate;
 
-    public StringSharingPlugin() throws IOException {
-        this(new String[0]);
-    }
-
-    StringSharingPlugin(String[] patterns) throws IOException {
-        this(new ResourceFilter(patterns));
+    public StringSharingPlugin() {
+        this((path) -> true);
     }
 
     StringSharingPlugin(Predicate<String> predicate) {
@@ -396,12 +391,7 @@
 
     @Override
     public void configure(Map<String, String> config) {
-        try {
-            String val = config.get(NAME);
-            predicate = new ResourceFilter(Utils.listParser.apply(val));
-        } catch (IOException ex) {
-            throw new PluginException(ex);
-        }
+        predicate = ResourceFilter.includeFilter(config.get(NAME));
     }
 
     @Override
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/StripDebugPlugin.java	Wed Jun 15 23:24:08 2016 +0000
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/StripDebugPlugin.java	Thu Jun 16 09:09:53 2016 -0300
@@ -25,8 +25,7 @@
 package jdk.tools.jlink.internal.plugins;
 
 import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.UncheckedIOException;
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashSet;
 import java.util.Set;
@@ -42,15 +41,15 @@
  * 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<String> predicate;
+
     public StripDebugPlugin() {
-        try {
-            predicate = new ResourceFilter(PATTERNS);
-        } catch (IOException ex) {
-            throw new UncheckedIOException(ex);
-        }
+        this((path) -> false);
+    }
+
+    StripDebugPlugin(Predicate<String> predicate) {
+        this.predicate = predicate;
     }
 
     @Override
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/ZipPlugin.java	Wed Jun 15 23:24:08 2016 +0000
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/ZipPlugin.java	Thu Jun 16 09:09:53 2016 -0300
@@ -27,18 +27,17 @@
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.nio.ByteBuffer;
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashSet;
 import java.util.Map;
 import java.util.Set;
 import java.util.function.Predicate;
 import java.util.zip.Deflater;
-import jdk.tools.jlink.plugin.PluginException;
 import jdk.tools.jlink.internal.ModulePoolImpl;
 import jdk.tools.jlink.plugin.ModuleEntry;
 import jdk.tools.jlink.plugin.ModulePool;
 import jdk.tools.jlink.plugin.TransformerPlugin;
-import jdk.tools.jlink.internal.Utils;
 
 /**
  *
@@ -53,8 +52,8 @@
 
     }
 
-    ZipPlugin(String[] patterns) throws IOException {
-        this(new ResourceFilter(patterns));
+    ZipPlugin(String[] patterns) {
+        this(ResourceFilter.includeFilter(Arrays.asList(patterns)));
     }
 
     ZipPlugin(Predicate<String> predicate) {
@@ -90,12 +89,7 @@
 
     @Override
     public void configure(Map<String, String> config) {
-        try {
-            String val = config.get(NAME);
-            predicate = new ResourceFilter(Utils.listParser.apply(val));
-        } catch (IOException ex) {
-            throw new PluginException(ex);
-        }
+        predicate = ResourceFilter.includeFilter(config.get(NAME));
     }
 
     static byte[] compress(byte[] bytesIn) {
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jmod/JmodTask.java	Wed Jun 15 23:24:08 2016 +0000
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jmod/JmodTask.java	Thu Jun 16 09:09:53 2016 -0300
@@ -103,6 +103,7 @@
 import jdk.internal.module.ConfigurableModuleFinder.Phase;
 import jdk.internal.module.ModuleHashes;
 import jdk.internal.module.ModuleInfoExtender;
+import jdk.tools.jlink.internal.Utils;
 
 import static java.util.stream.Collectors.joining;
 
@@ -1091,13 +1092,7 @@
         @Override
         public PathMatcher convert(String pattern) {
             try {
-                if (!pattern.startsWith("glob:") &&
-                    !pattern.startsWith("regex:")) {
-                    pattern = "glob:" + pattern;
-                }
-
-                return FileSystems.getDefault()
-                                  .getPathMatcher("glob:" + pattern);
+                return Utils.getPathMatcher(FileSystems.getDefault(), pattern);
             } catch (PatternSyntaxException e) {
                 throw new CommandException("err.bad.pattern", pattern);
             }
--- a/jdk/test/ProblemList.txt	Wed Jun 15 23:24:08 2016 +0000
+++ b/jdk/test/ProblemList.txt	Thu Jun 16 09:09:53 2016 -0300
@@ -393,28 +393,6 @@
 
 tools/jlink/plugins/IncludeLocalesPluginTest.java               8158272 generic-all
 
-tools/jlink/basic/BasicTest.java                                8159206 generic-all
-
-tools/jlink/IntegrationTest.java                                8159206 generic-all
-
-tools/jlink/JLinkOptimTest.java                                 8159206 generic-all
-
-tools/jlink/JLinkTest.java                                      8159206 generic-all
-
-tools/jlink/plugins/CompressorPluginTest.java                   8159206 generic-all
-
-tools/jlink/plugins/ExcludeFilesPluginTest.java                 8159206 generic-all
-
-tools/jlink/plugins/ExcludePluginTest.java                      8159206 generic-all
-
-tools/jlink/plugins/ExcludeVMPluginTest.java                    8159206 generic-all
-
-tools/jlink/plugins/OrderResourcesPluginTest.java               8159206 generic-all
-
-tools/jlink/plugins/ResourceFilterTest.java                     8159206 generic-all
-
-tools/jlink/plugins/StringSharingPluginTest.java                8159206 generic-all
-
-tools/jmod/JmodTest.java                                        8159206 generic-all
+tools/jlink/JLinkOptimTest.java                                 8159264 generic-all
 
 ############################################################################
--- a/jdk/test/tools/jlink/JLinkOptimTest.java	Wed Jun 15 23:24:08 2016 +0000
+++ b/jdk/test/tools/jlink/JLinkOptimTest.java	Thu Jun 16 09:09:53 2016 -0300
@@ -332,17 +332,6 @@
             helper.checkImage(imageDir, "optim1", null, null);
         }
 
-        /*{
-         Path dir = Paths.get("dir.log");
-         Files.createDirectory(dir);
-         String[] userOptions = {"--class-optim=all:log=" + dir.toString()};
-         helper.generateDefaultImage(userOptions, "optim1")
-         .assertFailure("java.io.FileNotFoundException: dir.log (Is a directory)");
-         }*/
- /*{
-         String[] userOptions = {"--class-optim", "UNKNOWN"};
-         helper.generateDefaultImage(userOptions, "optim1").assertFailure("Unknown optimization");
-         }*/
         {
             String[] userOptions = {"--class-optim=forName-folding:log=./class-optim-log.txt"};
             Path imageDir = helper.generateDefaultImage(userOptions, "optim1").assertSuccess();
--- a/jdk/test/tools/jlink/plugins/CompressorPluginTest.java	Wed Jun 15 23:24:08 2016 +0000
+++ b/jdk/test/tools/jlink/plugins/CompressorPluginTest.java	Thu Jun 16 09:09:53 2016 -0300
@@ -103,13 +103,12 @@
 
         // compress == ZIP + String sharing + filter
         options.setProperty(DefaultCompressPlugin.FILTER,
-                "*Exception.class,^*IOException.class");
+                "**Exception.class");
         checkCompress(classes, new DefaultCompressPlugin(), options,
                 new ResourceDecompressorFactory[]{
                     new ZipDecompressorFactory(),
                     new StringSharingDecompressorFactory()
-                }, Collections.singletonList(".*Exception.class"),
-                Collections.singletonList(".*IOException.class"));
+                }, Collections.singletonList(".*Exception.class"));
 
         // compress level 1 == ZIP
         Properties options1 = new Properties();
@@ -123,13 +122,12 @@
 
         // compress level 1 == ZIP
         options1.setProperty(DefaultCompressPlugin.FILTER,
-                "*Exception.class,^*IOException.class");
+                "**Exception.class");
         checkCompress(classes, new DefaultCompressPlugin(),
                 options1,
                 new ResourceDecompressorFactory[]{
                     new ZipDecompressorFactory()
-                }, Collections.singletonList(".*Exception.class"),
-                Collections.singletonList(".*IOException.class"));
+                }, Collections.singletonList(".*Exception.class"));
 
         // compress level 2 == ZIP + String sharing
         Properties options2 = new Properties();
@@ -144,14 +142,13 @@
 
         // compress level 2 == ZIP + String sharing + filter
         options2.setProperty(DefaultCompressPlugin.FILTER,
-                "*Exception.class,^*IOException.class");
+                "**Exception.class");
         checkCompress(classes, new DefaultCompressPlugin(),
                 options2,
                 new ResourceDecompressorFactory[]{
                     new ZipDecompressorFactory(),
                     new StringSharingDecompressorFactory()
-                }, Collections.singletonList(".*Exception.class"),
-                Collections.singletonList(".*IOException.class"));
+                }, Collections.singletonList(".*Exception.class"));
 
         // compress level 0 == String sharing
         Properties options0 = new Properties();
@@ -164,13 +161,12 @@
 
         // compress level 0 == String sharing + filter
         options0.setProperty(DefaultCompressPlugin.FILTER,
-                "*Exception.class,^*IOException.class");
+                "**Exception.class");
         checkCompress(classes, new DefaultCompressPlugin(),
                 options0,
                 new ResourceDecompressorFactory[]{
                     new StringSharingDecompressorFactory()
-                }, Collections.singletonList(".*Exception.class"),
-                Collections.singletonList(".*IOException.class"));
+                }, Collections.singletonList(".*Exception.class"));
     }
 
     private ModulePool gatherResources(Path module) throws Exception {
@@ -226,23 +222,19 @@
     private void checkCompress(ModulePool resources, Plugin prov,
             Properties config,
             ResourceDecompressorFactory[] factories) throws Exception {
-        checkCompress(resources, prov, config, factories, Collections.emptyList(), Collections.emptyList());
+        checkCompress(resources, prov, config, factories, Collections.emptyList());
     }
 
     private void checkCompress(ModulePool resources, Plugin prov,
             Properties config,
             ResourceDecompressorFactory[] factories,
-            List<String> includes,
-            List<String> excludes) throws Exception {
+            List<String> includes) throws Exception {
         long[] original = new long[1];
         long[] compressed = new long[1];
         resources.entries().forEach(resource -> {
             List<Pattern> includesPatterns = includes.stream()
                     .map(Pattern::compile)
                     .collect(Collectors.toList());
-            List<Pattern> excludesPatterns = excludes.stream()
-                    .map(Pattern::compile)
-                    .collect(Collectors.toList());
 
             Map<String, String> props = new HashMap<>();
             if (config != null) {
@@ -267,10 +259,10 @@
                 }
             });
             inputResources.add(resource);
-            ModulePool compressedResources = applyCompressor(prov, inputResources, resource, includesPatterns, excludesPatterns);
+            ModulePool compressedResources = applyCompressor(prov, inputResources, resource, includesPatterns);
             original[0] += resource.getLength();
             compressed[0] += compressedResources.findEntry(resource.getPath()).get().getLength();
-            applyDecompressors(factories, inputResources, compressedResources, strings, includesPatterns, excludesPatterns);
+            applyDecompressors(factories, inputResources, compressedResources, strings, includesPatterns);
         });
         String compressors = Stream.of(factories)
                 .map(Object::getClass)
@@ -286,8 +278,7 @@
     private ModulePool applyCompressor(Plugin plugin,
             ModulePoolImpl inputResources,
             ModuleEntry res,
-            List<Pattern> includesPatterns,
-            List<Pattern> excludesPatterns) {
+            List<Pattern> includesPatterns) {
         TransformerPlugin compressor = (TransformerPlugin) plugin;
         ModulePool compressedModulePool = new ModulePoolImpl(ByteOrder.nativeOrder(), inputResources.getStringTable());
         compressor.visit(inputResources, compressedModulePool);
@@ -295,7 +286,7 @@
         ModuleEntry compressed = compressedModulePool.findEntry(path).get();
         CompressedResourceHeader header
                 = CompressedResourceHeader.readFromResource(ByteOrder.nativeOrder(), compressed.getBytes());
-        if (isIncluded(includesPatterns, excludesPatterns, path)) {
+        if (isIncluded(includesPatterns, path)) {
             if (header == null) {
                 throw new AssertionError("Path should be compressed: " + path);
             }
@@ -317,14 +308,13 @@
             ModulePool inputResources,
             ModulePool compressedResources,
             Map<Integer, String> strings,
-            List<Pattern> includesPatterns,
-            List<Pattern> excludesPatterns) {
+            List<Pattern> includesPatterns) {
         compressedResources.entries().forEach(compressed -> {
             CompressedResourceHeader header = CompressedResourceHeader.readFromResource(
                     ByteOrder.nativeOrder(), compressed.getBytes());
             String path = compressed.getPath();
             ModuleEntry orig = inputResources.findEntry(path).get();
-            if (!isIncluded(includesPatterns, excludesPatterns, path)) {
+            if (!isIncluded(includesPatterns, path)) {
                 return;
             }
             byte[] decompressed = compressed.getBytes();
@@ -352,9 +342,8 @@
         });
     }
 
-    private boolean isIncluded(List<Pattern> includesPatterns, List<Pattern> excludesPatterns, String path) {
-        return !excludesPatterns.stream().anyMatch((pattern) -> pattern.matcher(path).matches())
-                && (includesPatterns.isEmpty()
-                || includesPatterns.stream().anyMatch((pattern) -> pattern.matcher(path).matches()));
+    private boolean isIncluded(List<Pattern> includesPatterns, String path) {
+        return includesPatterns.isEmpty() ||
+               includesPatterns.stream().anyMatch((pattern) -> pattern.matcher(path).matches());
     }
 }
--- a/jdk/test/tools/jlink/plugins/ExcludeFilesPluginTest.java	Wed Jun 15 23:24:08 2016 +0000
+++ b/jdk/test/tools/jlink/plugins/ExcludeFilesPluginTest.java	Thu Jun 16 09:09:53 2016 -0300
@@ -48,23 +48,23 @@
     }
 
     public void test() throws Exception {
-        checkFiles("*.jcov", "num/toto.jcov", "", true);
-        checkFiles("*.jcov", "/toto.jcov", "", true);
-        checkFiles("*.jcov", "toto.jcov/tutu/tata", "", false);
+        checkFiles("**.jcov", "num/toto.jcov", "", true);
+        checkFiles("**.jcov", "/toto.jcov", "", true);
+        checkFiles("**.jcov", "toto.jcov/tutu/tata", "", false);
         checkFiles("/java.base/*.jcov", "toto.jcov", "java.base", true);
         checkFiles("/java.base/toto.jcov", "iti.jcov", "t/java.base", false);
         checkFiles("/java.base/*/toto.jcov", "toto.jcov", "java.base", false);
         checkFiles("/java.base/*/toto.jcov", "tutu/toto.jcov", "java.base", true);
-        checkFiles("*/java.base/*/toto.jcov", "java.base/tutu/toto.jcov", "/tutu", true);
+        checkFiles("**/java.base/*/toto.jcov", "java.base/tutu/toto.jcov", "/tutu", true);
 
-        checkFiles("/*$*.properties", "tutu/Toto$Titi.properties", "java.base", true);
-        checkFiles("*$*.properties", "tutu/Toto$Titi.properties", "java.base", true);
+        checkFiles("/**$*.properties", "tutu/Toto$Titi.properties", "java.base", true);
+        checkFiles("**$*.properties", "tutu/Toto$Titi.properties", "java.base", true);
 
         // Excluded files list in a file
         File order = new File("files.exc");
         order.createNewFile();
-        Files.write(order.toPath(), "*.jcov".getBytes());
-        checkFiles(order.getAbsolutePath(), "/num/toto.jcov", "", true);
+        Files.write(order.toPath(), "**.jcov".getBytes());
+        checkFiles("@" + order.getAbsolutePath(), "/num/toto.jcov", "", true);
     }
 
     public void checkFiles(String s, String sample, String module, boolean exclude) throws Exception {
--- a/jdk/test/tools/jlink/plugins/ExcludePluginTest.java	Wed Jun 15 23:24:08 2016 +0000
+++ b/jdk/test/tools/jlink/plugins/ExcludePluginTest.java	Thu Jun 16 09:09:53 2016 -0300
@@ -47,27 +47,27 @@
     }
 
     public void test() throws Exception {
-        check("*.jcov", "/num/toto.jcov", true);
-        check("*.jcov", "//toto.jcov", true);
-        check("*.jcov", "/toto.jcov/tutu/tata", false);
+        check("**.jcov", "/num/toto.jcov", true);
+        check("**.jcov", "//toto.jcov", true);
+        check("**.jcov", "/toto.jcov/tutu/tata", false);
         check("/java.base/*.jcov", "/java.base/toto.jcov", true);
         check("/java.base/toto.jcov", "t/java.base/iti.jcov", false);
         check("/java.base/*/toto.jcov", "/java.base/toto.jcov", false);
         check("/java.base/*/toto.jcov", "/java.base/tutu/toto.jcov", true);
-        check("*/java.base/*/toto.jcov", "/tutu/java.base/tutu/toto.jcov", true);
-        check("*/META-INF/*", "/META-INF/services/  MyProvider ", false);
-        check("*/META-INF/*", "/META-INF/services/MyProvider", false);
-        check("*/META-INF", " /META-INF/services/MyProvider", false);
-        check("*/META-INF/*", "/java.base//META-INF/services/MyProvider", true);
+        check("**/java.base/*/toto.jcov", "/tutu/java.base/tutu/toto.jcov", true);
+        check("/META-INF/**", "/META-INF/services/  MyProvider ", true);
+        check("/META-INF/**", "/META-INF/services/MyProvider", true);
+        check("**/META-INF", " /META-INF/services/MyProvider", false);
+        check("**/META-INF/**", "/java.base//META-INF/services/MyProvider", true);
         check("/java.base/*/Toto$Titi.class", "/java.base/tutu/Toto$Titi.class", true);
-        check("/*$*.class", "/java.base/tutu/Toto$Titi.class", true);
-        check("*$*.class", "/java.base/tutu/Toto$Titi.class", true);
+        check("/**$**.class", "/java.base/tutu/Toto$Titi.class", true);
+        check("**$**.class", "/java.base/tutu/Toto$Titi.class", true);
 
         // Excluded resource list in a file
         File order = new File("resources.exc");
         order.createNewFile();
-        Files.write(order.toPath(), "*.jcov".getBytes());
-        check(order.getAbsolutePath(), "/num/toto.jcov", true);
+        Files.write(order.toPath(), "**.jcov".getBytes());
+        check("@" + order.getAbsolutePath(), "/num/toto.jcov", true);
     }
 
     public void check(String s, String sample, boolean exclude) throws Exception {
--- a/jdk/test/tools/jlink/plugins/OrderResourcesPluginTest.java	Wed Jun 15 23:24:08 2016 +0000
+++ b/jdk/test/tools/jlink/plugins/OrderResourcesPluginTest.java	Thu Jun 16 09:09:53 2016 -0300
@@ -92,7 +92,7 @@
         {
             ModulePool out = new ModulePoolImpl();
             Map<String, String> config = new HashMap<>();
-            config.put(OrderResourcesPlugin.NAME, "/zazou/*,*/module-info.class");
+            config.put(OrderResourcesPlugin.NAME, "/zazou/**,**/module-info.class");
             TransformerPlugin p = new OrderResourcesPlugin();
             p.configure(config);
             p.visit(resources, out);
--- a/jdk/test/tools/jlink/plugins/ResourceFilterTest.java	Wed Jun 15 23:24:08 2016 +0000
+++ b/jdk/test/tools/jlink/plugins/ResourceFilterTest.java	Thu Jun 16 09:09:53 2016 -0300
@@ -24,13 +24,13 @@
 /*
  * @test
  * @summary Test ResourceFilter class
- * @author Jean-Francois Denise
  * @modules jdk.jlink/jdk.tools.jlink.internal.plugins
  * @run main ResourceFilterTest
  */
 
 import java.io.File;
 import java.nio.file.Files;
+import java.util.Arrays;
 import jdk.tools.jlink.internal.plugins.ResourceFilter;
 
 public class ResourceFilterTest {
@@ -41,14 +41,16 @@
 
     public void test() throws Exception {
         String[] samples = {"toto.jcov", "/module/META-INF/services/MyProvider"};
-        String[] patterns = {"*.jcov", "*/META-INF/*"};
-        ResourceFilter rf = new ResourceFilter(patterns);
+        String[] patterns = {"*.jcov", "**/META-INF/**",
+                             "glob:*.jcov", "glob:**/META-INF/**",
+                             "regex:.*\\.jcov", "regex:.*/META-INF/.*"};
+        ResourceFilter rf = ResourceFilter.includeFilter(Arrays.asList(patterns));
         for (String s : samples) {
             if (!rf.test(s)) {
                 throw new Exception("Sample " + s + "not accepted");
             }
         }
-        ResourceFilter rf2 = new ResourceFilter(patterns, true);
+        ResourceFilter rf2 = ResourceFilter.excludeFilter(Arrays.asList(patterns));
         for (String s : samples) {
             if (rf2.test(s)) {
                 throw new Exception("Sample " + s + " accepted");
@@ -64,14 +66,14 @@
         }
         Files.write(resources.toPath(), builder.toString().getBytes());
 
-        String[] input = {resources.getAbsolutePath()};
-        ResourceFilter rf3 = new ResourceFilter(input);
+        String[] input = {"@" + resources.getAbsolutePath()};
+        ResourceFilter rf3 = ResourceFilter.includeFilter(Arrays.asList(input));
         for (String s : samples) {
             if (!rf3.test(s)) {
                 throw new Exception("Sample " + s + "not accepted");
             }
         }
-        ResourceFilter rf4 = new ResourceFilter(input, true);
+        ResourceFilter rf4 = ResourceFilter.excludeFilter(Arrays.asList(input));
         for (String s : samples) {
             if (rf4.test(s)) {
                 throw new Exception("Sample " + s + " accepted");