diff --git a/src/main/java/org/vafer/jdependency/Clazz.java b/src/main/java/org/vafer/jdependency/Clazz.java index 69a0931b..0f6d964d 100644 --- a/src/main/java/org/vafer/jdependency/Clazz.java +++ b/src/main/java/org/vafer/jdependency/Clazz.java @@ -32,16 +32,36 @@ public final class Clazz implements Comparable { private final Set references = new HashSet<>(); private final Map units = new HashMap<>(); + // Usually a class is only in a single file. + // When using MultiRelease Jar files this can be multiple files, one for each java release specified. + // The default filename is under the key "8". + private final Map classFilenames = new HashMap<>(); + + // The name of the class (like "org.vafer.jdependency.Clazz") private final String name; public Clazz( final String pName ) { name = pName; + classFilenames.put("8", pName.replace(".", "/")); + } + + public Clazz( final String pName, final String pForJava, final String pFileName ) { + name = pName; + classFilenames.put(pForJava, pFileName); + } + + public void addMultiReleaseFile(String pForJava, String pFileName) { + classFilenames.put(pForJava, pFileName); } public String getName() { return name; } + public Map getFileNames() { + return classFilenames; + } + public void addClazzpathUnit( final ClazzpathUnit pUnit, final String pDigest ) { units.put(pUnit, pDigest); } @@ -116,7 +136,7 @@ public int compareTo( final Clazz pO ) { } public String toString() { - return name; + return name + " in " + classFilenames; } } diff --git a/src/main/java/org/vafer/jdependency/Clazzpath.java b/src/main/java/org/vafer/jdependency/Clazzpath.java index 12440256..96292eb0 100644 --- a/src/main/java/org/vafer/jdependency/Clazzpath.java +++ b/src/main/java/org/vafer/jdependency/Clazzpath.java @@ -27,6 +27,8 @@ import java.nio.file.Files; import java.nio.file.Path; import java.security.MessageDigest; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import org.objectweb.asm.ClassReader; import org.apache.commons.io.input.MessageDigestCalculatingInputStream; @@ -45,21 +47,35 @@ public final class Clazzpath { private final Map clazzes = new HashMap<>(); private final boolean versions; + private static final Pattern EXTRACT_MULTI_RELEASE_JAVA_VERSION = Pattern.compile("META-INF[/\\\\]versions[/\\\\](\\d+)[/\\\\]([^.]+).class$"); + private abstract static class Resource { private static final int ext = ".class".length(); + public final String fileName; + public final String forJava; public final String name; - Resource( final String pName ) { + Resource( final String pFileName ) { super(); + this.fileName = pFileName; + + final int all = pFileName.length(); + + Matcher matcher = EXTRACT_MULTI_RELEASE_JAVA_VERSION.matcher(pFileName); + if (matcher.find()) { + forJava = matcher.group(1); + this.name = separatorsToUnix(matcher.group(2)) + .replace('/', '.'); + } else { + forJava = "8"; + // foo/bar/Foo.class -> // foo.bar.Foo + this.name = separatorsToUnix(pFileName) + .substring(0, all - ext) + .replace('/', '.'); + } - final int all = pName.length(); - - // foo/bar/Foo.class -> // foo.bar.Foo - this.name = separatorsToUnix(pName) - .substring(0, all - ext) - .replace('/', '.'); } abstract InputStream getInputStream() throws IOException; @@ -68,7 +84,7 @@ private abstract static class Resource { private static boolean isValidResourceName( final String pName ) { return pName != null && pName.endsWith(".class") - && !pName.contains( "-" ); + && ( !pName.contains( "-" ) || pName.contains("META-INF/versions/") ); } public Clazzpath() { @@ -187,8 +203,10 @@ private ClazzpathUnit addClazzpathUnit( final Iterable resources, fina // already marked missing clazz = missing.remove(clazzName); } else { - clazz = new Clazz(clazzName); + clazz = new Clazz(clazzName, resource.forJava, resource.fileName); } + } else { + clazz.addMultiReleaseFile(resource.forJava, resource.fileName); } final String d = Base64.getEncoder().encodeToString(digest.digest()); clazz.addClazzpathUnit(unit, d); diff --git a/src/test/java/org/vafer/jdependency/ClazzpathUnitTestCase.java b/src/test/java/org/vafer/jdependency/ClazzpathUnitTestCase.java index a105035e..5ddcf733 100644 --- a/src/test/java/org/vafer/jdependency/ClazzpathUnitTestCase.java +++ b/src/test/java/org/vafer/jdependency/ClazzpathUnitTestCase.java @@ -179,4 +179,15 @@ public void testDependencies() throws IOException { } + @Test + public void testMultiReleaseJar() throws IOException { + final Clazzpath cp = new Clazzpath(); + final ClazzpathUnit u = cp.addClazzpathUnit(resourceFile("src/test/resources/multi-jdk-1.0.0.jar")); + for (Clazz clazz : u.getClazzes()) { + System.out.println(clazz); + } + } + + + } diff --git a/src/test/resources/multi-jdk-1.0.0.jar b/src/test/resources/multi-jdk-1.0.0.jar new file mode 100644 index 00000000..2eeeb1c6 Binary files /dev/null and b/src/test/resources/multi-jdk-1.0.0.jar differ