--- old/test/tools/jlink/plugins/SystemModuleDescriptors/src/m4/p4/Main.java 2017-03-21 13:44:35.033617894 +0000 +++ new/test/tools/jlink/plugins/SystemModuleDescriptors/src/m4/p4/Main.java 2017-03-21 13:44:34.836604376 +0000 @@ -36,7 +36,47 @@ import java.util.Collections; import java.util.Set; +import jdk.internal.module.ClassFileAttributes; +import jdk.internal.module.ClassFileAttributes.ModuleTargetAttribute; +import jdk.internal.module.ClassFileConstants; +import jdk.internal.org.objectweb.asm.Attribute; +import jdk.internal.org.objectweb.asm.ClassReader; +import jdk.internal.org.objectweb.asm.ClassVisitor; +import jdk.internal.org.objectweb.asm.Opcodes; + public class Main { + private static boolean hasModuleTarget(InputStream in) throws IOException { + ModuleTargetAttribute[] modTargets = new ModuleTargetAttribute[1]; + ClassVisitor cv = new ClassVisitor(Opcodes.ASM5) { + @Override + public void visitAttribute(Attribute attr) { + if (attr instanceof ModuleTargetAttribute) { + modTargets[0] = (ModuleTargetAttribute)attr; + } + } + }; + + // prototype of attributes that should be parsed + Attribute[] attrs = new Attribute[] { + new ModuleTargetAttribute() + }; + + // parse module-info.class + ClassReader cr = new ClassReader(in); + cr.accept(cv, attrs, 0); + return modTargets[0] != null && + (modTargets[0].osName() != null || modTargets[0].osArch() != null); + } + + private static boolean hasModuleTarget(String modName) throws IOException { + FileSystem fs = FileSystems.newFileSystem(URI.create("jrt:/"), + Collections.emptyMap()); + Path path = fs.getPath("/", "modules", modName, "module-info.class"); + try (InputStream in = Files.newInputStream(path)) { + return hasModuleTarget(in); + } + } + // the system module plugin by default drops ModuleTarget attribute private static boolean expectModuleTarget = false; public static void main(String... args) throws IOException { @@ -49,13 +89,8 @@ } // java.base is packaged with osName/osArch/osVersion - ModuleDescriptor md = Layer.boot().findModule("java.base").get() - .getDescriptor(); - if (!md.osName().isPresent() || - !md.osArch().isPresent() || - !md.osVersion().isPresent()) { - throw new RuntimeException("osName/osArch/osVersion is missing: " + - md.osName() + " " + md.osArch() + " " + md.osVersion()); + if (! hasModuleTarget("java.base")) { + throw new RuntimeException("ModuleTarget absent for java.base"); } // verify module-info.class for m1 and m4 @@ -82,7 +117,7 @@ checkModuleDescriptor(ModuleDescriptor.read(Files.newInputStream(path)), packages); } - static void checkModuleDescriptor(ModuleDescriptor md, String... packages) { + static void checkModuleDescriptor(ModuleDescriptor md, String... packages) throws IOException { String mainClass = md.name().replace('m', 'p') + ".Main"; if (!md.mainClass().get().equals(mainClass)) { throw new RuntimeException(md.mainClass().toString()); @@ -90,22 +125,16 @@ if (expectModuleTarget) { // ModuleTarget attribute is retained - if (!md.osName().isPresent() || !md.osArch().isPresent()) { - throw new RuntimeException("osName or osArch is missing: " + - md.osName() + " " + md.osArch()); + if (! hasModuleTarget(md.name())) { + throw new RuntimeException("ModuleTarget missing for " + md.name()); } } else { // by default ModuleTarget attribute is dropped - if (md.osName().isPresent() || md.osArch().isPresent()) { - throw new RuntimeException("osName and osArch should not be set: " + - md.osName() + " " + md.osArch()); + if (hasModuleTarget(md.name())) { + throw new RuntimeException("ModuleTarget present for " + md.name()); } } - if (md.osVersion().isPresent()) { - throw new RuntimeException("Expected no osVersion set: " + md.osVersion()); - } - Set pkgs = md.packages(); if (!pkgs.equals(Set.of(packages))) { throw new RuntimeException(pkgs + " expected: " + Set.of(packages));