/** * Returns the non-exported packages of the specified module. */ private static Set<String> nonExportedPkgs(ModuleDescriptor md) { // start with all packages in the module Set<String> pkgs = new HashSet<>(md.packages()); // remove the non-qualified exported packages md.exports().stream() .filter(p -> !p.isQualified()) .map(Exports::source) .forEach(pkgs::remove); // remove the non-qualified open packages md.opens().stream() .filter(p -> !p.isQualified()) .map(Opens::source) .forEach(pkgs::remove); return pkgs; }
/** * Validates if exported and open packages are present */ void validatePackages() { Set<String> nonExistPackages = new TreeSet<>(); descriptor.exports().stream() .map(Exports::source) .filter(pn -> !packages.contains(pn)) .forEach(nonExistPackages::add); descriptor.opens().stream() .map(Opens::source) .filter(pn -> !packages.contains(pn)) .forEach(nonExistPackages::add); if (!nonExistPackages.isEmpty()) { throw new PluginException("Packages that are exported or open in " + descriptor.name() + " are not present: " + nonExistPackages); } }
private void dedups(ModuleDescriptor md) { // exports for (Exports e : md.exports()) { dedupSetBuilder.stringSet(e.targets()); dedupSetBuilder.exportsModifiers(e.modifiers()); } // opens for (Opens opens : md.opens()) { dedupSetBuilder.stringSet(opens.targets()); dedupSetBuilder.opensModifiers(opens.modifiers()); } // requires for (Requires r : md.requires()) { dedupSetBuilder.requiresModifiers(r.modifiers()); } // uses dedupSetBuilder.stringSet(md.uses()); }
void newExports(Set<Exports.Modifier> ms, String pn, Set<String> targets) { int modifiersSetIndex = dedupSetBuilder.indexOfExportsModifiers(ms); if (!targets.isEmpty()) { int stringSetIndex = dedupSetBuilder.indexOfStringSet(targets); mv.visitVarInsn(ALOAD, modifiersSetIndex); mv.visitLdcInsn(pn); mv.visitVarInsn(ALOAD, stringSetIndex); mv.visitMethodInsn(INVOKESTATIC, MODULE_DESCRIPTOR_BUILDER, "newExports", EXPORTS_MODIFIER_SET_STRING_SET_SIG, false); } else { mv.visitVarInsn(ALOAD, modifiersSetIndex); mv.visitLdcInsn(pn); mv.visitMethodInsn(INVOKESTATIC, MODULE_DESCRIPTOR_BUILDER, "newExports", EXPORTS_MODIFIER_SET_STRING_SIG, false); } }
private void validatePackages(ModuleDescriptor descriptor, Set<String> packages) { Set<String> nonExistPackages = new TreeSet<>(); descriptor.exports().stream() .map(Exports::source) .filter(pn -> !packages.contains(pn)) .forEach(nonExistPackages::add); descriptor.opens().stream() .map(Opens::source) .filter(pn -> !packages.contains(pn)) .forEach(nonExistPackages::add); if (!nonExistPackages.isEmpty()) { throw new CommandException("err.missing.export.or.open.packages", descriptor.name(), nonExistPackages); } }
public void testExportsToTargets() { Set<String> targets = new HashSet<>(); targets.add("bar"); targets.add("gus"); Exports e = ModuleDescriptor.newModule("foo") .exports("p", targets) .build() .exports() .iterator() .next(); assertEquals(e, e); assertTrue(e.modifiers().isEmpty()); assertEquals(e.source(), "p"); assertTrue(e.isQualified()); assertTrue(e.targets().size() == 2); assertTrue(e.targets().contains("bar")); assertTrue(e.targets().contains("gus")); }
private void printModuleInfo(PrintWriter writer, ModuleDescriptor descriptor) { writer.format("module %s {%n", descriptor.name()); Map<String, Module> modules = configuration.getModules(); // first print the JDK modules descriptor.requires().stream() .filter(req -> !req.name().equals("java.base")) // implicit requires .sorted(Comparator.comparing(Requires::name)) .forEach(req -> writer.format(" requires %s;%n", req)); descriptor.exports().stream() .peek(exp -> { if (exp.targets().size() > 0) throw new InternalError(descriptor.name() + " qualified exports: " + exp); }) .sorted(Comparator.comparing(Exports::source)) .forEach(exp -> writer.format(" exports %s;%n", exp.source())); descriptor.provides().values().stream() .sorted(Comparator.comparing(Provides::service)) .forEach(p -> p.providers().stream() .sorted() .forEach(impl -> writer.format(" provides %s with %s;%n", p.service(), impl))); writer.println("}"); }
/** * Returns a new {@code ModuleDescriptor} instance. */ ModuleDescriptor newModuleDescriptor(String name, boolean automatic, boolean synthetic, Set<Requires> requires, Set<String> uses, Set<Exports> exports, Map<String, Provides> provides, Version version, String mainClass, String osName, String osArch, String osVersion, Set<String> conceals, Set<String> packages, ModuleHashes hashes);
public void testExportsToTargets() { Set<String> targets = new HashSet<>(); targets.add("bar"); targets.add("gus"); Exports e = new Builder("foo") .exports("p", targets) .build() .exports() .iterator() .next(); assertEquals(e, e); assertEquals(e.source(), "p"); assertTrue(e.isQualified()); assertTrue(e.targets().size() == 2); assertTrue(e.targets().contains("bar")); assertTrue(e.targets().contains("gus")); }
/** * Test all packages are exported */ public void testExports() throws IOException { Path dir = Files.createTempDirectory(USER_DIR, "mods"); createJarFile(dir.resolve("m1.jar"), "p/C1.class", "p/C2.class", "q/C1.class"); ModuleFinder finder = ModuleFinder.of(dir); Configuration parent = Layer.boot().configuration(); Configuration cf = resolve(parent, finder, "m1"); ModuleDescriptor m1 = findDescriptor(cf, "m1"); Set<String> exports = m1.exports().stream().map(Exports::source).collect(Collectors.toSet()); assertTrue(exports.size() == 2); assertTrue(exports.contains("p")); assertTrue(exports.contains("q")); assertTrue(m1.conceals().isEmpty()); }
private static int modifierToInt(Exports.Modifier modifier) { switch(modifier) { case MANDATED: return ACC_MANDATED; case SYNTHETIC: return ACC_SYNTHETIC; default: throw new IllegalStateException("unknown modifier " + modifier); } }
private void printModuleInfo(PrintWriter writer, ModuleDescriptor md) { writer.format("%smodule %s {%n", open ? "open " : "", md.name()); Map<String, Module> modules = configuration.getModules(); // first print requires Set<Requires> reqs = md.requires().stream() .filter(req -> !req.name().equals("java.base") && req.modifiers().isEmpty()) .collect(Collectors.toSet()); reqs.stream() .sorted(Comparator.comparing(Requires::name)) .forEach(req -> writer.format(" requires %s;%n", toString(req.modifiers(), req.name()))); if (!reqs.isEmpty()) { writer.println(); } // requires transitive reqs = md.requires().stream() .filter(req -> !req.name().equals("java.base") && !req.modifiers().isEmpty()) .collect(Collectors.toSet()); reqs.stream() .sorted(Comparator.comparing(Requires::name)) .forEach(req -> writer.format(" requires %s;%n", toString(req.modifiers(), req.name()))); if (!reqs.isEmpty()) { writer.println(); } if (!open) { md.exports().stream() .peek(exp -> { if (exp.isQualified()) throw new InternalError(md.name() + " qualified exports: " + exp); }) .sorted(Comparator.comparing(Exports::source)) .forEach(exp -> writer.format(" exports %s;%n", exp.source())); if (!md.exports().isEmpty()) { writer.println(); } } md.provides().stream() .sorted(Comparator.comparing(Provides::service)) .map(p -> p.providers().stream() .map(impl -> " " + impl.replace('$', '.')) .collect(joining(",\n", String.format(" provides %s with%n", p.service().replace('$', '.')), ";"))) .forEach(writer::println); if (!md.provides().isEmpty()) { writer.println(); } writer.println("}"); }
/** * Initialize/setup a module's exports. * * @param m the module * @param nameToModule map of module name to Module (for qualified exports) */ private static void initExports(Module m, Map<String, Module> nameToModule) { Map<String, Set<Module>> exportedPackages = new HashMap<>(); for (Exports exports : m.getDescriptor().exports()) { String source = exports.source(); if (exports.isQualified()) { // qualified exports Set<Module> targets = new HashSet<>(); for (String target : exports.targets()) { Module m2 = nameToModule.get(target); if (m2 != null) { addExports0(m, source, m2); targets.add(m2); } } if (!targets.isEmpty()) { exportedPackages.put(source, targets); } } else { // unqualified exports addExportsToAll0(m, source); exportedPackages.put(source, EVERYONE_SET); } } if (!exportedPackages.isEmpty()) m.exportedPackages = exportedPackages; }
/** * Returns a new {@code ModuleDescriptor} instance. */ ModuleDescriptor newModuleDescriptor(String name, Version version, Set<ModuleDescriptor.Modifier> ms, Set<Requires> requires, Set<Exports> exports, Set<Opens> opens, Set<String> uses, Set<Provides> provides, Set<String> packages, String mainClass, int hashCode);
@Test(dataProvider = "legalModuleNames") public void testLegalExports(String mn, String expected) throws Exception { ModuleDescriptor md = newBuilder("m") .requires("java.base") .exports("p", Set.of(mn)) .build(); ByteBuffer bb = toBuffer(md); ModuleDescriptor descriptor = ModuleDescriptor.read(bb); Optional<Exports> export = descriptor.exports().stream().findAny(); assertTrue(export.isPresent()); assertTrue(export.get().targets().contains(expected)); }
private Exports exports(Set<Exports.Modifier> mods, String pn) { return ModuleDescriptor.newModule("foo") .exports(mods, pn) .build() .exports() .iterator() .next(); }
private Exports exports(Set<Exports.Modifier> mods, String pn, String target) { return ModuleDescriptor.newModule("foo") .exports(mods, pn, Set.of(target)) .build() .exports() .iterator() .next(); }
public void testExportsToAll() { Exports e = exports("p"); assertEquals(e, e); assertTrue(e.modifiers().isEmpty()); assertEquals(e.source(), "p"); assertFalse(e.isQualified()); assertTrue(e.targets().isEmpty()); }
public void testExportsToTarget() { Exports e = exports("p", "bar"); assertEquals(e, e); assertTrue(e.modifiers().isEmpty()); assertEquals(e.source(), "p"); assertTrue(e.isQualified()); assertTrue(e.targets().size() == 1); assertTrue(e.targets().contains("bar")); }
public void testExportsToAllWithModifier() { Exports e = exports(Set.of(Exports.Modifier.SYNTHETIC), "p"); assertEquals(e, e); assertTrue(e.modifiers().size() == 1); assertTrue(e.modifiers().contains(Exports.Modifier.SYNTHETIC)); assertEquals(e.source(), "p"); assertFalse(e.isQualified()); assertTrue(e.targets().isEmpty()); }
public void testExportsToTargetWithModifier() { Exports e = exports(Set.of(Exports.Modifier.SYNTHETIC), "p", "bar"); assertEquals(e, e); assertTrue(e.modifiers().size() == 1); assertTrue(e.modifiers().contains(Exports.Modifier.SYNTHETIC)); assertEquals(e.source(), "p"); assertTrue(e.isQualified()); assertTrue(e.targets().size() == 1); assertTrue(e.targets().contains("bar")); }
public void testExportsCompare() { Exports e1 = exports("p"); Exports e2 = exports("p"); assertEquals(e1, e2); assertTrue(e1.hashCode() == e2.hashCode()); assertTrue(e1.compareTo(e2) == 0); assertTrue(e2.compareTo(e1) == 0); }
public void testExportsCompareWithSameModifiers() { Exports e1 = exports(Set.of(Exports.Modifier.SYNTHETIC), "p"); Exports e2 = exports(Set.of(Exports.Modifier.SYNTHETIC), "p"); assertEquals(e1, e2); assertTrue(e1.hashCode() == e2.hashCode()); assertTrue(e1.compareTo(e2) == 0); assertTrue(e2.compareTo(e1) == 0); }
public void testExportsCompareWithDifferentModifiers() { Exports e1 = exports(Set.of(Exports.Modifier.SYNTHETIC), "p"); Exports e2 = exports("p"); assertNotEquals(e1, e2); assertTrue(e1.compareTo(e2) == 1); assertTrue(e2.compareTo(e1) == -1); }
public void testExportsCompareWithSameTargets() { Exports e1 = exports("p", "x"); Exports e2 = exports("p", "x"); assertEquals(e1, e2); assertTrue(e1.hashCode() == e2.hashCode()); assertTrue(e1.compareTo(e2) == 0); assertTrue(e2.compareTo(e1) == 0); }
public void testExportsCompareWithDifferentTargets() { Exports e1 = exports("p", "y"); Exports e2 = exports("p", "x"); assertNotEquals(e1, e2); assertTrue(e1.compareTo(e2) == 1); assertTrue(e2.compareTo(e1) == -1); }
public void testOpenModule() { ModuleDescriptor descriptor = ModuleDescriptor.newOpenModule("foo") .requires("bar") .exports("p") .provides("p.Service", List.of("q.ServiceImpl")) .build(); // modifiers assertTrue(descriptor.modifiers().contains(ModuleDescriptor.Modifier.OPEN)); assertTrue(descriptor.isOpen()); // requires assertTrue(descriptor.requires().size() == 2); Set<String> names = descriptor.requires() .stream() .map(Requires::name) .collect(Collectors.toSet()); assertEquals(names, Set.of("bar", "java.base")); // packages assertEquals(descriptor.packages(), Set.of("p", "q")); // exports assertTrue(descriptor.exports().size() == 1); names = descriptor.exports() .stream() .map(Exports::source) .collect(Collectors.toSet()); assertEquals(names, Set.of("p")); // opens assertTrue(descriptor.opens().isEmpty()); }
/** * Returns the set of packages that is the union of the exported and * concealed packages. */ private Set<String> computePackages(Set<Exports> exports, Set<String> conceals) { if (exports.isEmpty()) return conceals; Set<String> pkgs = new HashSet<>(numPackages); pkgs.addAll(conceals); for (Exports e : exports) { pkgs.add(e.source()); } return pkgs; }
@Override public Set<String> getAccessiblePackages(String module) { AsmModulePool p = pools.get(module); if (p == null) { return null; } ModuleDescriptor desc = p.getDescriptor(); Set<String> packages = new HashSet<>(); packages.addAll(p.getAllPackages()); // Retrieve direct dependencies and indirect ones (public) Set<String> modules = new HashSet<>(); for (Requires req : desc.requires()) { modules.add(req.name()); addAllRequirePublicModules(req.name(), modules); } // Add exported packages of readable modules for (String readable : modules) { AsmModulePool mp = pools.get(readable); if (mp != null) { for (Exports e : mp.getDescriptor().exports()) { // exported to all or to the targeted module if (e.targets().isEmpty() || e.targets().contains(module)) { packages.add(e.source().replaceAll("\\.", "/")); } } } } return packages; }
/** * Lookup the class in the exported packages of this module. "public * requires" modules are looked up. NB: static module readability can be * different at execution time. * * @param callerModule Name of calling module. * @param binaryName The class to lookup. * @return The reader or null if not found */ @Override public ClassReader getExportedClassReader(String callerModule, String binaryName) { Objects.requireNonNull(callerModule); Objects.requireNonNull(binaryName); boolean exported = false; ClassReader clazz = null; for (Exports e : descriptor.exports()) { String pkg = e.source(); Set<String> targets = e.targets(); System.out.println("PKG " + pkg); if (targets.isEmpty() || targets.contains(callerModule)) { if (binaryName.startsWith(pkg)) { String className = binaryName.substring(pkg.length()); System.out.println("CLASS " + className); exported = !className.contains("."); } if (exported) { break; } } } // public requires (re-export) if (!exported) { for (Requires requires : descriptor.requires()) { if (requires.modifiers().contains(Modifier.PUBLIC)) { AsmModulePool pool = pools.getModulePool(requires.name()); clazz = pool.getExportedClassReader(moduleName, binaryName); if (clazz != null) { break; } } } } else { clazz = getClassReader(binaryName); } return clazz; }
private Exports exports(String pn) { return new Builder("foo") .exports(pn) .build() .exports() .iterator() .next(); }
private Exports exports(String pn, String target) { return new Builder("foo") .exports(pn, target) .build() .exports() .iterator() .next(); }
public void testExportsToAll() { Exports e = exports("p"); assertEquals(e, e); assertEquals(e.source(), "p"); assertFalse(e.isQualified()); assertTrue(e.targets().isEmpty()); }
public void testExportsToTarget() { Exports e = exports("p", "bar"); assertEquals(e, e); assertEquals(e.source(), "p"); assertTrue(e.isQualified()); assertTrue(e.targets().size() == 1); assertTrue(e.targets().contains("bar")); }
public static void main(String[] args) throws Exception { System.out.println("message:" + Message.get()); ModuleDescriptor md = Bar.class.getModule().getDescriptor(); System.out.println("nameAndVersion:" + md.toNameAndVersion()); md.mainClass().ifPresent(mc -> System.out.println("mainClass:" + mc)); StringJoiner sj = new StringJoiner(","); md.requires().stream().map(ModuleDescriptor.Requires::name).sorted().forEach(sj::add); System.out.println("requires:" + sj.toString()); sj = new StringJoiner(","); md.exports().stream().map(ModuleDescriptor.Exports::source).sorted().forEach(sj::add); if (!sj.toString().equals("")) System.out.println("exports:" + sj.toString()); sj = new StringJoiner(","); md.uses().stream().sorted().forEach(sj::add); if (!sj.toString().equals("")) System.out.println("uses:" + sj.toString()); sj = new StringJoiner(","); md.provides().keySet().stream().sorted().forEach(sj::add); if (!sj.toString().equals("")) System.out.println("provides:" + sj.toString()); sj = new StringJoiner(","); md.conceals().forEach(sj::add); if (!sj.toString().equals("")) System.out.println("conceals:" + sj.toString()); Method m = ModuleDescriptor.class.getDeclaredMethod("hashes"); m.setAccessible(true); ModuleDescriptor foo = jdk.test.foo.Foo.class.getModule().getDescriptor(); Optional<ModuleHashes> oHashes = (Optional<ModuleHashes>) m.invoke(foo); System.out.println("hashes:" + oHashes.get().hashFor("bar")); }
public static void main(String[] args) { System.out.println("message:" + Message.get()); ModuleDescriptor md = Foo.class.getModule().getDescriptor(); System.out.println("nameAndVersion:" + md.toNameAndVersion()); md.mainClass().ifPresent(mc -> System.out.println("mainClass:" + mc)); StringJoiner sj = new StringJoiner(","); md.requires().stream().map(Requires::name).sorted().forEach(sj::add); System.out.println("requires:" + sj.toString()); sj = new StringJoiner(","); md.exports().stream().map(Exports::source).sorted().forEach(sj::add); if (!sj.toString().equals("")) System.out.println("exports:" + sj.toString()); sj = new StringJoiner(","); md.uses().stream().sorted().forEach(sj::add); if (!sj.toString().equals("")) System.out.println("uses:" + sj.toString()); sj = new StringJoiner(","); md.provides().keySet().stream().sorted().forEach(sj::add); if (!sj.toString().equals("")) System.out.println("provides:" + sj.toString()); sj = new StringJoiner(","); md.conceals().forEach(sj::add); if (!sj.toString().equals("")) System.out.println("conceals:" + sj.toString()); }
/** * Returns a {@link Exports} for a qualified export, with * the given (and possibly empty) set of modifiers, * to a set of target modules. */ public static Exports newExports(Set<Exports.Modifier> ms, String pn, Set<String> targets) { return JLMA.newExports(ms, pn, targets); }
void exportsModifiers(Set<Exports.Modifier> mods) { exportsModifiersSets.computeIfAbsent(mods, s -> new EnumSetBuilder<>(s, EXPORTS_MODIFIER_CLASSNAME, enumSetVar, localVarSupplier) ).increment(); }
int indexOfExportsModifiers(Set<Exports.Modifier> mods) { return exportsModifiersSets.get(mods).build(); }