changeset 12929:f62697faac4c

asm memory leak
author jfdenise
date Wed, 10 Jun 2015 16:27:29 -0300
parents 01bfebec1fb9
children e05a7819423e
files src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/asm/AsmPool.java src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/asm/AsmPoolImpl.java src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/asm/AsmPools.java test/jdk/jigsaw/tools/jlink/AsmPluginTest.java test/jdk/jigsaw/tools/jlink/PluginsTest.java
diffstat 5 files changed, 230 insertions(+), 132 deletions(-) [+]
line wrap: on
line diff
--- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/asm/AsmPool.java	Wed Jun 10 16:26:11 2015 -0300
+++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/asm/AsmPool.java	Wed Jun 10 16:27:29 2015 -0300
@@ -26,10 +26,12 @@
 
 import java.io.IOException;
 import java.nio.ByteBuffer;
+import java.util.Collection;
 import java.util.List;
 import jdk.internal.org.objectweb.asm.ClassReader;
 import jdk.internal.org.objectweb.asm.ClassWriter;
 import jdk.tools.jlink.plugins.ResourcePool;
+import jdk.tools.jlink.plugins.ResourcePool.Resource;
 
 /**
  * A pool of ClassReader and other resource files.
@@ -126,15 +128,25 @@
          *
          * @param binaryName The java class binary name
          * @return The ClassReader or null if the class is not found.
+         * @throws java.io.IOException
          */
-        public ClassReader getClassReader(String binaryName);
+        public ClassReader getClassReader(String binaryName) throws IOException;
+
+        /**
+         * Get a transformed class.
+         *
+         * @param res A class resource.
+         * @return The ClassReader or null if the class is not found.
+         * @throws java.io.IOException
+         */
+        public ClassReader getClassReader(Resource res) throws IOException;
 
         /**
          * Returns all the classes contained in the writable pool.
          *
-         * @return The array of transformed classes.
+         * @return The collection of classes.
          */
-        public ClassReader[] getClassReaders();
+        public Collection<Resource> getClasses();
     }
 
     /**
@@ -166,12 +178,21 @@
          * @return The Resource or 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.
+         */
+        public ResourceFile getResourceFile(Resource res);
+
         /**
          * Returns all the resources contained in the writable pool.
          *
-         * @return The array of transformed classes.
+         * @return The array of resources.
          */
-        public ResourceFile[] getResourceFiles();
+        public Collection<Resource> getResourceFiles();
     }
 
     /**
@@ -214,17 +235,17 @@
     /**
      * Returns the classes contained in the pool.
      *
-     * @return The array of classes.
+     * @return The classes.
      */
-    public ClassReader[] getClassReaders();
+    public Collection<Resource> getClasses();
 
     /**
      * 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.
+     * @return The array of resource files.
      */
-    public ResourceFile[] getResourceFiles();
+    public Collection<Resource> getResourceFiles();
 
     /**
      * Retrieves a resource based on the binary name. This name doesn't contain
@@ -240,6 +261,14 @@
     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.
+     */
+    public ResourceFile getResourceFile(Resource res);
+
+    /**
      * Retrieve a ClassReader from the pool.
      *
      * @param binaryName Class binary name
@@ -249,6 +278,15 @@
     public ClassReader getClassReader(String binaryName) throws IOException;
 
     /**
+     * Retrieve a ClassReader from the pool.
+     *
+     * @param res A resource.
+     * @return A reader or null if the class is unknown
+     * @throws IOException
+     */
+    public ClassReader getClassReader(Resource res) throws IOException;
+
+    /**
      * To visit the set of ClassReaders.
      *
      * @param visitor The visitor.
--- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/asm/AsmPoolImpl.java	Wed Jun 10 16:26:11 2015 -0300
+++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/asm/AsmPoolImpl.java	Wed Jun 10 16:27:29 2015 -0300
@@ -28,6 +28,7 @@
 import java.io.IOException;
 import java.nio.ByteBuffer;
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.LinkedHashMap;
@@ -98,8 +99,7 @@
 
             byte[] content = writer.toByteArray();
             Resource res = new Resource(path, ByteBuffer.wrap(content));
-            addResource(res);
-            transformedClasses.put(className, reader);
+            transformedClasses.put(className, res);
         }
 
         /**
@@ -110,15 +110,15 @@
         @Override
         public void forgetClass(String className) throws IOException {
             Objects.requireNonNull(className);
-            String path = toClassNamePath(className);
             // do we have a resource?
-            ClassReader res = transformedClasses.get(className);
+            Resource res = transformedClasses.get(className);
             if (res == null) {
                 res = inputClasses.get(className);
                 if (res == null) {
                     throw new IOException("Unknown class " + className);
                 }
             }
+            String path = toClassNamePath(className);
             forgetResources.add(path);
             // Just in case it has been added.
             transformedClasses.remove(className);
@@ -131,9 +131,14 @@
          * @return The ClassReader or null if the class is not found.
          */
         @Override
-        public ClassReader getClassReader(String binaryName) {
+        public ClassReader getClassReader(String binaryName) throws IOException {
             Objects.requireNonNull(binaryName);
-            return transformedClasses.get(binaryName);
+            Resource res = transformedClasses.get(binaryName);
+            ClassReader reader = null;
+            if (res != null) {
+                reader = getClassReader(res);
+            }
+            return reader;
         }
 
         /**
@@ -142,14 +147,17 @@
          * @return The array of transformed classes.
          */
         @Override
-        public ClassReader[] getClassReaders() {
-            ClassReader[] readers = new ClassReader[transformedClasses.size()];
-            int i = 0;
-            for (Entry<String, ClassReader> entry : transformedClasses.entrySet()) {
-                readers[i] = entry.getValue();
-                i += 1;
+        public Collection<Resource> getClasses() {
+            List<Resource> classes = new ArrayList<>();
+            for (Entry<String, Resource> entry : transformedClasses.entrySet()) {
+                classes.add(entry.getValue());
             }
-            return readers;
+            return classes;
+        }
+
+        @Override
+        public ClassReader getClassReader(Resource res) throws IOException {
+            return newClassReader(res.getByteArray());
         }
     }
 
@@ -173,7 +181,7 @@
             Objects.requireNonNull(resFile);
             String path = toResourceNamePath(resFile.getPath());
             Resource res = new Resource(path, resFile.getContent());
-            addResource(res);
+            transformedResources.put(resFile.getPath(), res);
         }
 
         /**
@@ -187,7 +195,7 @@
             Objects.requireNonNull(resourceName);
             String path = toResourceNamePath(resourceName);
             // do we have a resource?
-            ResourceFile res = transformedResources.get(resourceName);
+            Resource res = transformedResources.get(resourceName);
             if (res == null) {
                 res = inputResources.get(resourceName);
                 if (res == null) {
@@ -208,7 +216,12 @@
         @Override
         public ResourceFile getResourceFile(String name) {
             Objects.requireNonNull(name);
-            return transformedResources.get(name);
+            Resource res = transformedResources.get(name);
+            ResourceFile resFile = null;
+            if (res != null) {
+                resFile = getResourceFile(res);
+            }
+            return resFile;
         }
 
         /**
@@ -217,37 +230,37 @@
          * @return The array of transformed classes.
          */
         @Override
-        public ResourceFile[] getResourceFiles() {
-            ResourceFile[] resources = new ResourceFile[transformedResources.size()];
-            int i = 0;
-            for (Entry<String, ResourceWrapper> entry : transformedResources.entrySet()) {
-                resources[i] = entry.getValue();
-                i += 1;
+        public Collection<Resource> getResourceFiles() {
+            List<Resource> resources = new ArrayList<>();
+            for (Entry<String, Resource> entry : transformedResources.entrySet()) {
+                resources.add(entry.getValue());
             }
             return resources;
         }
+
+        @Override
+        public ResourceFile getResourceFile(Resource res) {
+            return new ResourceWrapper(res);
+        }
     }
 
     private final ResourcePool jimageResources;
-    private final Map<String, ClassReader> inputClasses;
-    private final Map<String, ResourceFile> inputResources;
+    private final Map<String, Resource> inputClasses;
+    private final Map<String, Resource> inputResources;
     private final Map<String, String> inputClassPackageMapping;
     private final Map<String, String> inputOtherPackageMapping;
 
-    private final ClassReader[] inputReadersArray;
-    private final ResourceFile[] inputResourcesArray;
-
-    private final WritableClassPool transClassesPool =
-            new WritableClassPoolImpl();
-    private final WritableResourcePool transResourcesPool =
-            new WritableResourcePoolImpl();
+    private final WritableClassPool transClassesPool
+            = new WritableClassPoolImpl();
+    private final WritableResourcePool transResourcesPool
+            = new WritableResourcePoolImpl();
 
     private Sorter sorter;
 
-    private final Map<String, ClassReader> transformedClasses =
-            new LinkedHashMap<>();
-    private final Map<String, ResourceWrapper> transformedResources =
-            new LinkedHashMap<>();
+    private final Map<String, Resource> transformedClasses
+            =            new LinkedHashMap<>();
+    private final Map<String, Resource> transformedResources
+            =            new LinkedHashMap<>();
     private final List<String> forgetResources = new ArrayList<>();
     private final Map<String, String> newPackageMapping = new HashMap<>();
 
@@ -266,22 +279,19 @@
         Objects.requireNonNull(moduleName);
         this.jimageResources = inputResources;
         this.moduleName = moduleName;
-        List<ClassReader> readers = new ArrayList<>();
-        List<ResourceFile> resList = new ArrayList<>();
-        Map<String, ClassReader> classes = new HashMap<>();
-        Map<String, ResourceFile> resources = new HashMap<>();
+        List<Resource> readers = new ArrayList<>();
+        List<Resource> resList = new ArrayList<>();
+        Map<String, Resource> classes = new LinkedHashMap<>();
+        Map<String, Resource> resources = new LinkedHashMap<>();
         Map<String, String> packageClassToModule = new HashMap<>();
         Map<String, String> packageOtherToModule = new HashMap<>();
         for (Resource res : inputResources.getResources()) {
             if (res.getPath().endsWith(".class")) {
-                String name = toJavaBinaryClassName(res.getPath());
-                ClassReader cr = newClassReader(res.getByteArray());
-                classes.put(name, cr);
-                readers.add(cr);
+                classes.put(toJavaBinaryClassName(res.getPath()), res);
+                readers.add(res);
             } else {
-                ResourceFile resFile = new ResourceWrapper(res);
-                resList.add(resFile);
-                resources.put(resFile.getPath(), resFile);
+                resources.put(toJavaBinaryResourceName(res.getPath()), res);
+                resList.add(res);
             }
             String[] split = ImageFileCreator.splitPath(res.getPath());
             if (ImageFileCreator.isClassPackage(res.getPath())) {
@@ -294,12 +304,7 @@
                 }
             }
         }
-        this.inputReadersArray = new ClassReader[readers.size()];
-        readers.toArray(this.inputReadersArray);
         this.inputClasses = Collections.unmodifiableMap(classes);
-
-        this.inputResourcesArray = new ResourceFile[resList.size()];
-        resList.toArray(this.inputResourcesArray);
         this.inputResources = Collections.unmodifiableMap(resources);
 
         this.inputClassPackageMapping = Collections.unmodifiableMap(packageClassToModule);
@@ -349,8 +354,8 @@
      * @return The array of classes.
      */
     @Override
-    public ClassReader[] getClassReaders() {
-        return inputReadersArray;
+    public Collection<Resource> getClasses() {
+        return inputClasses.values();
     }
 
     /**
@@ -360,8 +365,8 @@
      * @return The array of classes.
      */
     @Override
-    public ResourceFile[] getResourceFiles() {
-        return inputResourcesArray;
+    public Collection<Resource> getResourceFiles() {
+        return inputResources.values();
     }
 
     /**
@@ -378,7 +383,12 @@
     @Override
     public ResourceFile getResourceFile(String binaryName) {
         Objects.requireNonNull(binaryName);
-        return inputResources.get(binaryName);
+        Resource res = inputResources.get(binaryName);
+        ResourceFile resFile = null;
+        if (res != null) {
+            resFile = getResourceFile(res);
+        }
+        return resFile;
     }
 
     /**
@@ -391,7 +401,22 @@
     @Override
     public ClassReader getClassReader(String binaryName) throws IOException {
         Objects.requireNonNull(binaryName);
-        return inputClasses.get(binaryName);
+        Resource res = inputClasses.get(binaryName);
+        ClassReader reader = null;
+        if (res != null) {
+            reader = getClassReader(res);
+        }
+        return reader;
+    }
+
+    @Override
+    public ResourceFile getResourceFile(Resource res) {
+        return new ResourceWrapper(res);
+    }
+
+    @Override
+    public ClassReader getClassReader(Resource res) throws IOException {
+        return newClassReader(res.getByteArray());
     }
 
     /**
@@ -403,9 +428,14 @@
     @Override
     public void visitClassReaders(ClassReaderVisitor visitor) throws IOException {
         Objects.requireNonNull(visitor);
-        for (ClassReader reader : getClassReaders()) {
+        System.out.println("VISIT CLASSES ");
+        for (Resource res : getClasses()) {
+            System.out.println("VISIT " + res.getPath());
+            ClassReader reader = newClassReader(res.getByteArray());
             ClassWriter writer = visitor.visit(reader);
+            System.out.println("RETURNED WRITER " + writer);
             if (writer != null) {
+
                 getTransformedClasses().addClass(writer);
             }
         }
@@ -421,8 +451,9 @@
     public void visitResourceFiles(ResourceFileVisitor visitor)
             throws IOException {
         Objects.requireNonNull(visitor);
-        for (ResourceFile reader : getResourceFiles()) {
-            ResourceFile res = visitor.visit(reader);
+        for (Resource resource : getResourceFiles()) {
+            ResourceFile resFile = new ResourceWrapper(resource);
+            ResourceFile res = visitor.visit(resFile);
             if (res != null) {
                 getTransformedResourceFiles().addResourceFile(res);
             }
@@ -445,21 +476,26 @@
         ResourcePool output = new ResourcePoolImpl(outputResources.getByteOrder());
         for (Resource inResource : jimageResources.getResources()) {
             if (!forgetResources.contains(inResource.getPath())) {
-                String internalName = toJavaBinaryResourceName(inResource.getPath());
                 Resource resource = inResource;
                 // Do we have a transformed class with the same name?
-                ResourceWrapper res = transformedResources.get(internalName);
+                Resource res = transformedResources.
+                        get(toJavaBinaryResourceName(inResource.getPath()));
                 if (res != null) {
-                    resource = res.getWrappedResource();
+                    resource = res;
+                } else {
+                    res = transformedClasses.
+                            get(toJavaBinaryClassName(inResource.getPath()));
+                    if (res != null) {
+                        resource = res;
+                    }
                 }
                 output.addResource(resource);
                 added.add(resource.getPath());
             }
         }
         // Then new resources
-        for (Map.Entry<String, ResourceWrapper> entry : transformedResources.entrySet()) {
-            ResourceWrapper res = entry.getValue();
-            Resource resource = res.getWrappedResource();
+        for (Map.Entry<String, Resource> entry : transformedResources.entrySet()) {
+            Resource resource = entry.getValue();
             if (!forgetResources.contains(resource.getPath())) {
                 if (!added.contains(resource.getPath())) {
                     output.addResource(resource);
@@ -470,6 +506,10 @@
         AsmPools.sort(outputResources, output, sorter);
     }
 
+    private static void addResources(String name, Map<String, Resource> map) {
+
+    }
+
     /**
      * 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
@@ -491,11 +531,6 @@
         newPackageMapping.put(pkg, moduleName);
     }
 
-    private void addResource(Resource res) throws IOException {
-        ResourceWrapper resFile = new ResourceWrapper(res);
-        transformedResources.put(resFile.getPath(), resFile);
-    }
-
     private static ClassReader newClassReader(byte[] bytes) throws IOException {
         ByteArrayInputStream stream = new ByteArrayInputStream(bytes);
         ClassReader reader = new ClassReader(stream);
--- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/asm/AsmPools.java	Wed Jun 10 16:26:11 2015 -0300
+++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/asm/AsmPools.java	Wed Jun 10 16:27:29 2015 -0300
@@ -26,6 +26,7 @@
 
 import java.io.IOException;
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
@@ -62,8 +63,6 @@
 
     private class AsmGlobalPoolImpl implements AsmGlobalPool {
 
-        private ClassReader[] allReaders = null;
-        private ResourceFile[] allFiles = null;
         private Sorter sorter = null;
 
         private class GlobalWritableClassPool implements WritableClassPool {
@@ -90,16 +89,21 @@
             }
 
             @Override
-            public ClassReader[] getClassReaders() {
-                List<ClassReader> all = new ArrayList<>();
+            public Collection<Resource> getClasses() {
+                List<Resource> all = new ArrayList<>();
                 visitAllPools((AsmModulePool pool) -> {
-                    for (ClassReader rf : pool.getTransformedClasses().getClassReaders()) {
+                    for (Resource rf : pool.getTransformedClasses().getClasses()) {
                         all.add(rf);
                     }
                 });
-                ClassReader[] ret = new ClassReader[all.size()];
-                all.toArray(ret);
-                return ret;
+                return all;
+            }
+
+            @Override
+            public ClassReader getClassReader(Resource res) {
+                return visitPools((AsmModulePool pool) -> {
+                    return pool.getTransformedClasses().getClassReader(res);
+                });
             }
 
         }
@@ -128,16 +132,21 @@
             }
 
             @Override
-            public ResourceFile[] getResourceFiles() {
-                List<ResourceFile> all = new ArrayList<>();
+            public Collection<Resource> getResourceFiles() {
+                List<Resource> all = new ArrayList<>();
                 visitAllPools((AsmModulePool pool) -> {
-                    for (ResourceFile rf : pool.getTransformedResourceFiles().getResourceFiles()) {
+                    for (Resource rf : pool.getTransformedResourceFiles().getResourceFiles()) {
                         all.add(rf);
                     }
                 });
-                ResourceFile[] ret = new ResourceFile[all.size()];
-                all.toArray(ret);
-                return ret;
+                return all;
+            }
+
+            @Override
+            public ResourceFile getResourceFile(Resource res) {
+                return visitPools((AsmModulePool pool) -> {
+                    return pool.getTransformedResourceFiles().getResourceFile(res);
+                });
             }
 
         }
@@ -158,33 +167,25 @@
         }
 
         @Override
-        public ClassReader[] getClassReaders() {
-            if (allReaders == null) {
-                List<ClassReader> all = new ArrayList<>();
-                visitAllPools((AsmModulePool pool) -> {
-                    for (ClassReader rf : pool.getClassReaders()) {
-                        all.add(rf);
-                    }
-                });
-                allReaders = new ClassReader[all.size()];
-                all.toArray(allReaders);
-            }
-            return allReaders;
+        public Collection<Resource> getClasses() {
+            List<Resource> all = new ArrayList<>();
+            visitAllPools((AsmModulePool pool) -> {
+                for (Resource rf : pool.getClasses()) {
+                    all.add(rf);
+                }
+            });
+            return all;
         }
 
         @Override
-        public AsmPool.ResourceFile[] getResourceFiles() {
-            if (allFiles == null) {
-                List<ResourceFile> all = new ArrayList<>();
-                visitAllPools((AsmModulePool pool) -> {
-                    for (ResourceFile rf : pool.getResourceFiles()) {
-                        all.add(rf);
-                    }
-                });
-                allFiles = new ResourceFile[all.size()];
-                all.toArray(allFiles);
-            }
-            return allFiles;
+        public Collection<Resource> getResourceFiles() {
+            List<Resource> all = new ArrayList<>();
+            visitAllPools((AsmModulePool pool) -> {
+                for (Resource rf : pool.getResourceFiles()) {
+                    all.add(rf);
+                }
+            });
+            return all;
         }
 
         @Override
@@ -202,6 +203,20 @@
         }
 
         @Override
+        public ResourceFile getResourceFile(Resource res) {
+            return visitPools((AsmModulePool pool) -> {
+                return pool.getResourceFile(res);
+            });
+        }
+
+        @Override
+        public ClassReader getClassReader(Resource res) throws IOException {
+            return visitPoolsEx((AsmModulePool pool) -> {
+                return pool.getClassReader(res);
+            });
+        }
+
+        @Override
         public void visitClassReaders(AsmPool.ClassReaderVisitor visitor)
                 throws IOException {
             visitAllPoolsEx((AsmModulePool pool) -> {
@@ -248,7 +263,6 @@
         P visit(AsmModulePool pool) throws IOException;
     }
 
-    private final ResourcePool inputResources;
     private final Map<String, AsmModulePool> pools = new LinkedHashMap<>();
     private final AsmModulePool[] poolsArray;
     private final AsmGlobalPoolImpl global;
@@ -263,7 +277,6 @@
      */
     public AsmPools(ResourcePool inputResources) throws Exception {
         Objects.requireNonNull(inputResources);
-        this.inputResources = inputResources;
         Map<String, ResourcePool> resPools = new LinkedHashMap<>();
         for (Resource res : inputResources.getResources()) {
             ResourcePool p = resPools.get(res.getModule());
--- a/test/jdk/jigsaw/tools/jlink/AsmPluginTest.java	Wed Jun 10 16:26:11 2015 -0300
+++ b/test/jdk/jigsaw/tools/jlink/AsmPluginTest.java	Wed Jun 10 16:27:29 2015 -0300
@@ -90,11 +90,11 @@
                     throw new IOException("Invalid module name " +
                             pool.getModuleName() + " should be "+ m);
                 }
-                if(pool.getClassReaders().length == 0 && !m.equals(TEST_MODULE)) {
+                if (pool.getClasses().size() == 0 && !m.equals(TEST_MODULE)) {
                     throw new IOException("Empty pool " + m);
                 }
                 pool.addPackage("toto");
-                if(pool.getTransformedClasses().getClassReaders().length != 0) {
+                if (pool.getTransformedClasses().getClasses().size() != 0) {
                     throw new IOException("Should be empty");
                 }
                 for(String res : MODULES.get(m)) {
@@ -118,7 +118,8 @@
                 {
                     List<String> remain = new ArrayList<>();
                     remain.addAll(expected);
-                    for (ClassReader reader : pools.getGlobalPool().getClassReaders()) {
+                    for (Resource res : pools.getGlobalPool().getClasses()) {
+                        ClassReader reader = pools.getGlobalPool().getClassReader(res);
                         if (!expected.contains(reader.getClassName())) {
                             throw new IOException("Class is not expected " +
                                     reader.getClassName() + " expected " + expected);
@@ -200,7 +201,8 @@
         public void visit(AsmPools pools, StringTable strings) throws IOException {
             this.pools = pools;
 
-            for (ClassReader reader : pools.getGlobalPool().getClassReaders()) {
+            for (Resource res : pools.getGlobalPool().getClasses()) {
+                ClassReader reader = pools.getGlobalPool().getClassReader(res);
                 ClassWriter writer = new ClassWriter(reader,
                         ClassWriter.COMPUTE_FRAMES);
                 IdentityClassVisitor visitor = new IdentityClassVisitor(writer);
@@ -242,7 +244,8 @@
                 throws IOException {
             this.pools = pools;
 
-            for (ClassReader reader : pools.getGlobalPool().getClassReaders()) {
+            for (Resource res : pools.getGlobalPool().getClasses()) {
+                ClassReader reader = pools.getGlobalPool().getClassReader(res);
                 ClassWriter writer = new ClassWriter(reader,
                         ClassWriter.COMPUTE_FRAMES);
                 RenamerClassVisitor visitor = new RenamerClassVisitor(writer);
@@ -257,7 +260,8 @@
             }
             // Rename the resource Files
             for (Entry<String, List<String>> mod : MODULES.entrySet()) {
-                for (ResourceFile resFile : pools.getModulePool(mod.getKey()).getResourceFiles()) {
+                for (Resource res : pools.getModulePool(mod.getKey()).getResourceFiles()) {
+                    ResourceFile resFile = pools.getModulePool(mod.getKey()).getResourceFile(res);
                     if (resFile.getPath().startsWith("META-INF/services/")) {
                         ByteBuffer content = resFile.getContent();
                         content.rewind();
@@ -426,7 +430,7 @@
             throw new Exception("Resources not visited");
         }
         if (testAsm2.pools.getGlobalPool().getTransformedClasses().
-                getClassReaders().length != expected.size()) {
+                getClasses().size() != expected.size()) {
             throw new Exception("Number of transformed classes not equal to expected");
         }
         for (String className : expected) {
@@ -463,7 +467,7 @@
             throw new Exception("Resources not visited");
         }
         if (testAsm3.pools.getGlobalPool().getTransformedClasses().
-                getClassReaders().length != expected.size()) {
+                getClasses().size() != expected.size()) {
             throw new Exception("Number of transformed classes not equal to expected");
         }
         // Check that only renamed classes and resource files are in the result.
--- a/test/jdk/jigsaw/tools/jlink/PluginsTest.java	Wed Jun 10 16:26:11 2015 -0300
+++ b/test/jdk/jigsaw/tools/jlink/PluginsTest.java	Wed Jun 10 16:27:29 2015 -0300
@@ -441,12 +441,13 @@
             System.out.println("zipped/unzipped " + covered.size() + " classes");
         }
 
-        // Strip debug
-        List<Path> covered2 = new ArrayList<>();
         JImageGenerator helper = new JImageGenerator(new File("."), jdkHome);
         String[] classes = {"toto.Main", "toto.com.foo.bar.X"};
-        File moduleFile = helper.generateModuleCompiledClasses("leaf1", classes);
+        File moduleFile = helper.generateModuleCompiledClasses("composite2", classes);
+
+        // Strip debug
         // Classes have been compiled in debug.
+        List<Path> covered2 = new ArrayList<>();
         try (java.util.stream.Stream<Path> stream = Files.walk(moduleFile.toPath())) {
             stream.forEach((p) -> {
                 if (Files.isRegularFile(p) && p.toString().endsWith(".class")) {
@@ -496,6 +497,9 @@
                 }
             }
         };
+        try (java.util.stream.Stream<Path> stream = Files.walk(moduleFile.toPath())) {
+            stream.forEach(c);
+        }
         ResourcePlugin plugin = new StringSharingProvider().newPlugins(null, null)[0];
         Map<String, Integer> map = new HashMap<>();
         Map<Integer, String> reversedmap = new HashMap<>();
@@ -520,11 +524,15 @@
             }
         });
 
+        if (result.isEmpty()) {
+            throw new Exception("No result");
+        }
+
         for (Resource res : result.getResources()) {
             if (res.getPath().endsWith(".class")) {
                 byte[] uncompacted = StringSharingDecompressor.normalize((int offset) -> {
                     return reversedmap.get(offset);
-                }, res.getByteArray(), 0);
+                }, res.getByteArray(), CompressedResourceHeader.getSize());
                 JImageValidator.readClass(uncompacted);
             }
         }