OpenJDK / jigsaw / jake / jdk
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); } }