下面列出了怎么用java.lang.module.ModuleDescriptor.Requires的API类实例代码及写法,或者点击链接到github查看源代码。
/**
* Returns a {@link Requires} for a dependence on a module with the given
* (and possibly empty) set of modifiers, and optionally the version
* recorded at compile time.
*/
public static Requires newRequires(Set<Requires.Modifier> mods,
String mn,
String compiledVersion)
{
Version version = null;
if (compiledVersion != null) {
// use the cached version if the same version string
Version ver = cachedVersion;
if (ver != null && compiledVersion.equals(ver.toString())) {
version = ver;
} else {
version = Version.parse(compiledVersion);
}
}
return JLMA.newRequires(mods, mn, version);
}
/**
* Returns a {@link Requires} for a dependence on a module with the given
* (and possibly empty) set of modifiers, and optionally the version
* recorded at compile time.
*/
public static Requires newRequires(Set<Requires.Modifier> mods,
String mn,
String compiledVersion)
{
Version version = null;
if (compiledVersion != null) {
// use the cached version if the same version string
Version ver = cachedVersion;
if (ver != null && compiledVersion.equals(ver.toString())) {
version = ver;
} else {
version = Version.parse(compiledVersion);
}
}
return JLMA.newRequires(mods, mn, version);
}
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());
}
/**
* Basic test of "requires static":
* m1 requires static m2
* m2
* resolve m1
*/
public void testRequiresStatic2() {
ModuleDescriptor descriptor1 = newBuilder("m1")
.requires(Set.of(Requires.Modifier.STATIC), "m2")
.build();
ModuleDescriptor descriptor2 = newBuilder("m2")
.build();
ModuleFinder finder = ModuleUtils.finderOf(descriptor1, descriptor2);
Configuration cf = resolve(finder, "m1");
assertTrue(cf.modules().size() == 1);
ResolvedModule m1 = cf.findModule("m1").get();
assertTrue(m1.reads().size() == 0);
}
/**
* Basic test of "requires static":
* m1 requires static m2
* m2
* resolve m1, m2
*/
public void testRequiresStatic3() {
ModuleDescriptor descriptor1 = newBuilder("m1")
.requires(Set.of(Requires.Modifier.STATIC), "m2")
.build();
ModuleDescriptor descriptor2 = newBuilder("m2")
.build();
ModuleFinder finder = ModuleUtils.finderOf(descriptor1, descriptor2);
Configuration cf = resolve(finder, "m1", "m2");
assertTrue(cf.modules().size() == 2);
ResolvedModule m1 = cf.findModule("m1").get();
ResolvedModule m2 = cf.findModule("m2").get();
assertTrue(m1.reads().size() == 1);
assertTrue(m1.reads().contains(m2));
assertTrue(m2.reads().size() == 0);
}
/**
* Basic test to detect reading a module with the same name as itself
*
* The test consists of three configurations:
* - Configuration cf1: m1, m2 requires transitive m1
* - Configuration cf2: m1 requires m2
*/
@Test(expectedExceptions = { ResolutionException.class })
public void testReadModuleWithSameNameAsSelf() {
ModuleDescriptor descriptor1_v1 = newBuilder("m1")
.build();
ModuleDescriptor descriptor2 = newBuilder("m2")
.requires(Set.of(Requires.Modifier.TRANSITIVE), "m1")
.build();
ModuleDescriptor descriptor1_v2 = newBuilder("m1")
.requires("m2")
.build();
ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1_v1, descriptor2);
Configuration cf1 = resolve(finder1, "m2");
assertTrue(cf1.modules().size() == 2);
// resolve should throw ResolutionException
ModuleFinder finder2 = ModuleUtils.finderOf(descriptor1_v2);
resolve(cf1, finder2, "m1");
}
/**
* Basic test for requiring a module with an unparseable version recorded
* at compile version.
*/
@Test(dataProvider = "unparseableVersions")
public void testUnparseableCompiledVersion(String vs1, String vs2) {
Requires r1 = newRequires("m", vs1);
Requires r2 = newRequires("m", vs2);
if (vs1 != null && !isParsableVersion(vs1)) {
assertFalse(r1.compiledVersion().isPresent());
assertTrue(r1.rawCompiledVersion().isPresent());
assertEquals(r1.rawCompiledVersion().get(), vs1);
}
if (vs2 != null && !isParsableVersion(vs2)) {
assertFalse(r2.compiledVersion().isPresent());
assertTrue(r2.rawCompiledVersion().isPresent());
assertEquals(r2.rawCompiledVersion().get(), vs2);
}
assertFalse(r1.equals(r2));
assertFalse(r2.equals(r1));
assertTrue(r1.compareTo(r2) == -1);
assertTrue(r2.compareTo(r1) == 1);
}
public void testAutomaticModule() {
ModuleDescriptor descriptor = ModuleDescriptor.newAutomaticModule("foo")
.packages(Set.of("p"))
.provides("p.Service", List.of("q.ServiceImpl"))
.build();
// modifiers
assertTrue(descriptor.modifiers().contains(ModuleDescriptor.Modifier.AUTOMATIC));
assertTrue(descriptor.isAutomatic());
// requires
assertTrue(descriptor.requires().size() == 1);
Set<String> names = descriptor.requires()
.stream()
.map(Requires::name)
.collect(Collectors.toSet());
assertEquals(names, Set.of("java.base"));
// packages
assertEquals(descriptor.packages(), Set.of("p", "q"));
assertTrue(descriptor.exports().isEmpty());
assertTrue(descriptor.opens().isEmpty());
}
/**
* 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);
public void printModuleDescriptor(Module module) {
if (!module.isNamed())
return;
writer.format("%s%s%n", module.name(), module.isAutomatic() ? " automatic" : "");
writer.format(" [%s]%n", module.location());
module.descriptor().requires()
.stream()
.sorted(Comparator.comparing(Requires::name))
.forEach(req -> writer.format(" requires %s%n", req));
}
/**
* 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);
void newRequires(Set<Requires.Modifier> mods, String name, String compiledVersion) {
int varIndex = dedupSetBuilder.indexOfRequiresModifiers(mods);
mv.visitVarInsn(ALOAD, varIndex);
mv.visitLdcInsn(name);
if (compiledVersion != null) {
mv.visitLdcInsn(compiledVersion);
mv.visitMethodInsn(INVOKESTATIC, MODULE_DESCRIPTOR_BUILDER,
"newRequires", REQUIRES_SET_STRING_STRING_SIG, false);
} else {
mv.visitMethodInsn(INVOKESTATIC, MODULE_DESCRIPTOR_BUILDER,
"newRequires", REQUIRES_SET_STRING_SIG, false);
}
}
/**
* Basic test of "requires static":
* m1 requires static m2
* m2 is not observable
* resolve m1
*/
public void testRequiresStatic1() {
ModuleDescriptor descriptor1 = newBuilder("m1")
.requires(Set.of(Requires.Modifier.STATIC), "m2")
.build();
ModuleFinder finder = ModuleUtils.finderOf(descriptor1);
Configuration cf = resolve(finder, "m1");
assertTrue(cf.modules().size() == 1);
ResolvedModule m1 = cf.findModule("m1").get();
assertTrue(m1.reads().size() == 0);
}
/**
* Basic test of "requires static":
* m1 requires m2, m3
* m2 requires static m2
* m3
*/
public void testRequiresStatic4() {
ModuleDescriptor descriptor1 = newBuilder("m1")
.requires("m2")
.requires("m3")
.build();
ModuleDescriptor descriptor2 = newBuilder("m2")
.requires(Set.of(Requires.Modifier.STATIC), "m3")
.build();
ModuleDescriptor descriptor3 = newBuilder("m3")
.build();
ModuleFinder finder
= ModuleUtils.finderOf(descriptor1, descriptor2, descriptor3);
Configuration cf = resolve(finder, "m1");
assertTrue(cf.modules().size() == 3);
ResolvedModule m1 = cf.findModule("m1").get();
ResolvedModule m2 = cf.findModule("m2").get();
ResolvedModule m3 = cf.findModule("m3").get();
assertTrue(m1.reads().size() == 2);
assertTrue(m1.reads().contains(m2));
assertTrue(m1.reads().contains(m3));
assertTrue(m2.reads().size() == 1);
assertTrue(m2.reads().contains(m3));
assertTrue(m3.reads().size() == 0);
}
/**
* Basic test of "requires static":
* The test consists of three configurations:
* - Configuration cf1: m1, m2
* - Configuration cf2: m3 requires m1, requires static m2
*/
public void testRequiresStatic5() {
ModuleDescriptor descriptor1 = newBuilder("m1")
.build();
ModuleDescriptor descriptor2 = newBuilder("m2")
.build();
ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1, descriptor2);
Configuration cf1 = resolve(finder1, "m1", "m2");
assertTrue(cf1.modules().size() == 2);
assertTrue(cf1.findModule("m1").isPresent());
assertTrue(cf1.findModule("m2").isPresent());
ModuleDescriptor descriptor3 = newBuilder("m3")
.requires("m1")
.requires(Set.of(Requires.Modifier.STATIC), "m2")
.build();
ModuleFinder finder2 = ModuleUtils.finderOf(descriptor3);
Configuration cf2 = resolve(cf1, finder2, "m3");
assertTrue(cf2.modules().size() == 1);
assertTrue(cf2.findModule("m3").isPresent());
ResolvedModule m1 = cf1.findModule("m1").get();
ResolvedModule m2 = cf1.findModule("m2").get();
ResolvedModule m3 = cf2.findModule("m3").get();
assertTrue(m3.reads().size() == 2);
assertTrue(m3.reads().contains(m1));
assertTrue(m3.reads().contains(m2));
}
/**
* Basic test of "requires static":
* The test consists of three configurations:
* - Configuration cf1: m1
* - Configuration cf2: m3 requires m1, requires static m2
*/
public void testRequiresStatic6() {
ModuleDescriptor descriptor1 = newBuilder("m1")
.build();
ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1);
Configuration cf1 = resolve(finder1, "m1");
assertTrue(cf1.modules().size() == 1);
assertTrue(cf1.findModule("m1").isPresent());
ModuleDescriptor descriptor3 = newBuilder("m3")
.requires("m1")
.requires(Set.of(Requires.Modifier.STATIC), "m2")
.build();
ModuleFinder finder2 = ModuleUtils.finderOf(descriptor3);
Configuration cf2 = resolve(cf1, finder2, "m3");
assertTrue(cf2.modules().size() == 1);
assertTrue(cf2.findModule("m3").isPresent());
ResolvedModule m1 = cf1.findModule("m1").get();
ResolvedModule m3 = cf2.findModule("m3").get();
assertTrue(m3.reads().size() == 1);
assertTrue(m3.reads().contains(m1));
}
/**
* Basic test of "requires static":
* (m1 not observable)
* m2 requires transitive static m1
* m3 requires m2
*/
public void testRequiresStatic7() {
ModuleDescriptor descriptor1 = null; // not observable
ModuleDescriptor descriptor2 = newBuilder("m2")
.requires(Set.of(Requires.Modifier.TRANSITIVE,
Requires.Modifier.STATIC),
"m1")
.build();
ModuleDescriptor descriptor3 = newBuilder("m3")
.requires("m2")
.build();
ModuleFinder finder = ModuleUtils.finderOf(descriptor2, descriptor3);
Configuration cf = resolve(finder, "m3");
assertTrue(cf.modules().size() == 2);
assertTrue(cf.findModule("m2").isPresent());
assertTrue(cf.findModule("m3").isPresent());
ResolvedModule m2 = cf.findModule("m2").get();
ResolvedModule m3 = cf.findModule("m3").get();
assertTrue(m2.reads().isEmpty());
assertTrue(m3.reads().size() == 1);
assertTrue(m3.reads().contains(m2));
}
/**
* Basic test of "requires static":
* - Configuration cf1: m2 requires transitive static m1
* - Configuration cf2: m3 requires m2
*/
public void testRequiresStatic8() {
ModuleDescriptor descriptor1 = null; // not observable
ModuleDescriptor descriptor2 = newBuilder("m2")
.requires(Set.of(Requires.Modifier.TRANSITIVE,
Requires.Modifier.STATIC),
"m1")
.build();
ModuleFinder finder1 = ModuleUtils.finderOf(descriptor2);
Configuration cf1 = resolve(finder1, "m2");
assertTrue(cf1.modules().size() == 1);
assertTrue(cf1.findModule("m2").isPresent());
ResolvedModule m2 = cf1.findModule("m2").get();
assertTrue(m2.reads().isEmpty());
ModuleDescriptor descriptor3 = newBuilder("m3")
.requires("m2")
.build();
ModuleFinder finder2 = ModuleUtils.finderOf(descriptor3);
Configuration cf2 = resolve(cf1, finder2, "m3");
assertTrue(cf2.modules().size() == 1);
assertTrue(cf2.findModule("m3").isPresent());
ResolvedModule m3 = cf2.findModule("m3").get();
assertTrue(m3.reads().size() == 1);
assertTrue(m3.reads().contains(m2));
}
/**
* Basic test to detect reading two modules with the same name
*
* The test consists of three configurations:
* - Configuration cf1: m1, m2 requires transitive m1
* - Configuration cf2: m1, m3 requires transitive m1
* - Configuration cf3(cf1,cf2): m4 requires m2, m3
*/
@Test(expectedExceptions = { ResolutionException.class })
public void testReadTwoModuleWithSameName() {
ModuleDescriptor descriptor1 = newBuilder("m1")
.build();
ModuleDescriptor descriptor2 = newBuilder("m2")
.requires(Set.of(Requires.Modifier.TRANSITIVE), "m1")
.build();
ModuleDescriptor descriptor3 = newBuilder("m3")
.requires(Set.of(Requires.Modifier.TRANSITIVE), "m1")
.build();
ModuleDescriptor descriptor4 = newBuilder("m4")
.requires("m2")
.requires("m3")
.build();
ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1, descriptor2);
Configuration cf1 = resolve(finder1, "m2");
assertTrue(cf1.modules().size() == 2);
ModuleFinder finder2 = ModuleUtils.finderOf(descriptor1, descriptor3);
Configuration cf2 = resolve(finder2, "m3");
assertTrue(cf2.modules().size() == 2);
// should throw ResolutionException as m4 will read modules named "m1".
ModuleFinder finder3 = ModuleUtils.finderOf(descriptor4);
Configuration.resolve(finder3, List.of(cf1, cf2), ModuleFinder.of(), Set.of("m4"));
}
public void testRequiresWithNoModifiers() {
Requires r = requires(EnumSet.noneOf(Requires.Modifier.class), "foo");
assertEquals(r, r);
assertTrue(r.compareTo(r) == 0);
assertTrue(r.modifiers().isEmpty());
assertEquals(r.name(), "foo");
assertFalse(r.compiledVersion().isPresent());
}
public void testRequiresWithOneModifier() {
Requires r = requires(EnumSet.of(TRANSITIVE), "foo");
assertEquals(r, r);
assertTrue(r.compareTo(r) == 0);
assertEquals(r.modifiers(), EnumSet.of(TRANSITIVE));
assertEquals(r.name(), "foo");
assertFalse(r.compiledVersion().isPresent());
}
public void testRequiresWithTwoModifiers() {
Requires r = requires(EnumSet.of(TRANSITIVE, SYNTHETIC), "foo");
assertEquals(r, r);
assertTrue(r.compareTo(r) == 0);
assertEquals(r.modifiers(), EnumSet.of(TRANSITIVE, SYNTHETIC));
assertEquals(r.name(), "foo");
assertFalse(r.compiledVersion().isPresent());
}
public void testRequiresWithAllModifiers() {
Requires r = requires(EnumSet.allOf(Modifier.class), "foo");
assertEquals(r, r);
assertTrue(r.compareTo(r) == 0);
assertEquals(r.modifiers(), EnumSet.of(TRANSITIVE, STATIC, SYNTHETIC, MANDATED));
assertEquals(r.name(), "foo");
assertFalse(r.compiledVersion().isPresent());
}
public void testRequiresWithCompiledVersion() {
Version v = Version.parse("1.0");
Requires r = requires(Set.of(), "foo", v);
assertEquals(r, r);
assertTrue(r.compareTo(r) == 0);
assertEquals(r.modifiers(), Set.of());
assertEquals(r.name(), "foo");
assertTrue(r.compiledVersion().isPresent());
assertEquals(r.compiledVersion().get().toString(), "1.0");
}
public void testRequiresCompare() {
Requires r1 = requires(EnumSet.noneOf(Modifier.class), "foo");
Requires r2 = requires(EnumSet.noneOf(Modifier.class), "bar");
int n = "foo".compareTo("bar");
assertTrue(r1.compareTo(r2) == n);
assertTrue(r2.compareTo(r1) == -n);
}
public void testRequiresCompareWithDifferentModifiers() {
Requires r1 = requires(EnumSet.of(TRANSITIVE), "foo");
Requires r2 = requires(EnumSet.of(SYNTHETIC), "foo");
int n = Integer.compare(1 << TRANSITIVE.ordinal(), 1 << SYNTHETIC.ordinal());
assertTrue(r1.compareTo(r2) == n);
assertTrue(r2.compareTo(r1) == -n);
}
public void testRequiresEqualsAndHashCode() {
Requires r1 = requires("foo");
Requires r2 = requires("foo");
assertEquals(r1, r2);
assertTrue(r1.hashCode() == r2.hashCode());
r1 = requires(EnumSet.allOf(Requires.Modifier.class), "foo");
r2 = requires(EnumSet.allOf(Requires.Modifier.class), "foo");
assertEquals(r1, r2);
assertTrue(r1.hashCode() == r2.hashCode());
r1 = requires("foo");
r2 = requires("bar");
assertNotEquals(r1, r2);
r1 = requires(EnumSet.allOf(Requires.Modifier.class), "foo");
r2 = requires(Set.of(), "foo");
assertNotEquals(r1, r2);
Version v1 = Version.parse("1.0");
r1 = requires(EnumSet.allOf(Requires.Modifier.class), "foo", v1);
r2 = requires(EnumSet.allOf(Requires.Modifier.class), "foo", v1);
assertEquals(r1, r2);
assertTrue(r1.hashCode() == r2.hashCode());
Version v2 = Version.parse("2.0");
r1 = requires(EnumSet.allOf(Requires.Modifier.class), "foo", v1);
r2 = requires(EnumSet.allOf(Requires.Modifier.class), "foo", v2);
assertNotEquals(r1, r2);
}
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());
}
/**
* Test layers with a qualified export. The module exporting the package
* reads the target module in the parent layer (due to requires transitive).
*
* - Configuration/layer1: m1, m2 { requires transitive m1; }
* - Configuration/layer2: m1, m3 { requires m2; exports p to m1; }
*/
public void testQualifiedExports6() {
// create layer1 with m1 and m2
ModuleDescriptor descriptor1 = newBuilder("m1").build();
ModuleDescriptor descriptor2 = newBuilder("m2")
.requires(Set.of(Requires.Modifier.TRANSITIVE), "m1")
.build();
ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1, descriptor2);
Configuration cf1 = resolve(finder1, "m2");
ClassLoader loader1 = new ClassLoader() { };
ModuleLayer layer1 = ModuleLayer.empty().defineModules(cf1, mn -> loader1);
assertTrue(layer1.modules().size() == 2);
// create layer2 with m1 and m3
ModuleDescriptor descriptor3 = newBuilder("m3")
.requires("m2")
.exports("p", Set.of("m1"))
.build();
ModuleFinder finder2 = ModuleUtils.finderOf(descriptor1, descriptor3);
Configuration cf2 = resolve(cf1, finder2, "m1", "m3");
ClassLoader loader2 = new ClassLoader() { };
ModuleLayer layer2 = layer1.defineModules(cf2, mn -> loader2);
assertTrue(layer2.modules().size() == 2);
Module m1_v1 = layer1.findModule("m1").get();
Module m2 = layer1.findModule("m2").get();
Module m1_v2 = layer2.findModule("m1").get();
Module m3 = layer2.findModule("m3").get();
assertTrue(m3.canRead(m1_v1));
assertFalse(m3.canRead(m1_v2));
assertFalse(m3.isExported("p"));
assertTrue(m3.isExported("p", m1_v1));
assertFalse(m3.isExported("p", m1_v2));
assertFalse(m3.isExported("p", m2));
}
private static Set<Requires.Modifier> requireModifiers(int modifiers) {
return Map.of(
ACC_MANDATED, Requires.Modifier.MANDATED,
ACC_SYNTHETIC, Requires.Modifier.SYNTHETIC,
ACC_TRANSITIVE, Requires.Modifier.TRANSITIVE,
ACC_STATIC_PHASE, Requires.Modifier.STATIC)
.entrySet()
.stream()
.map(entry -> (modifiers & entry.getKey()) != 0? entry.getValue(): null)
.filter(Objects::nonNull)
.collect(Collectors.toSet());
}