undefect. CWE-407 — 63 sites patched across 27 ecosystems
Authors: russell@unturf.com · brackishbert@gmail.com · foxhop.net · TimeHexOn.com Patches, unit tests, benchmarks, whitepaper, and outreach briefs. Public domain — no copyright claimed. Use freely.
This commit is contained in:
commit
0a580b313d
70422 changed files with 17213626 additions and 0 deletions
1199
test/jdk/java/lang/module/AutomaticModulesTest.java
Normal file
1199
test/jdk/java/lang/module/AutomaticModulesTest.java
Normal file
File diff suppressed because it is too large
Load diff
157
test/jdk/java/lang/module/ClassFileVersionsTest.java
Normal file
157
test/jdk/java/lang/module/ClassFileVersionsTest.java
Normal file
|
|
@ -0,0 +1,157 @@
|
|||
/*
|
||||
* Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @modules java.base/jdk.internal.module
|
||||
* @library /test/lib
|
||||
* @build jdk.test.lib.util.ModuleInfoWriter
|
||||
* @run testng ClassFileVersionsTest
|
||||
* @summary Test parsing of module-info.class with different class file versions
|
||||
*/
|
||||
|
||||
import java.lang.classfile.ClassFile;
|
||||
import java.lang.module.InvalidModuleDescriptorException;
|
||||
import java.lang.module.ModuleDescriptor;
|
||||
import java.lang.module.ModuleDescriptor.Requires.Modifier;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import static java.lang.module.ModuleDescriptor.Requires.Modifier.*;
|
||||
|
||||
import jdk.test.lib.util.ModuleInfoWriter;
|
||||
|
||||
import org.testng.annotations.DataProvider;
|
||||
import org.testng.annotations.Test;
|
||||
import static org.testng.Assert.*;
|
||||
|
||||
public class ClassFileVersionsTest {
|
||||
private static final int PREVIEW_MINOR_VERSION =
|
||||
ClassFile.PREVIEW_MINOR_VERSION;
|
||||
private static final int FEATURE;
|
||||
static {
|
||||
FEATURE = Runtime.version().feature();
|
||||
assert FEATURE >= 10;
|
||||
}
|
||||
|
||||
// major, minor, modifiers for requires java.base
|
||||
@DataProvider(name = "supported")
|
||||
public Object[][] supported() {
|
||||
/*
|
||||
* There are four test cases for JDK 9, one test case
|
||||
* for each subsequent JDK version from JDK 10 to the current
|
||||
* feature release, and two tests for the current release with
|
||||
* a preview flag set, for a total of (4 + (FEATURE - 9) + 2)
|
||||
* rows.
|
||||
*/
|
||||
List<Object[]> result = new ArrayList<>(4 + (FEATURE - 9) + 2);
|
||||
|
||||
// Class file version of JDK 9 is 53.0
|
||||
result.add(new Object[]{ 53, 0, Set.of()});
|
||||
result.add(new Object[]{ 53, 0, Set.of(STATIC) });
|
||||
result.add(new Object[]{ 53, 0, Set.of(TRANSITIVE) });
|
||||
result.add(new Object[]{ 53, 0, Set.of(STATIC, TRANSITIVE) });
|
||||
|
||||
// Major class file version of JDK N is 44 + n. Create rows
|
||||
// for JDK 10 through FEATURE.
|
||||
for (int i = 10; i <= FEATURE; i++) {
|
||||
result.add(new Object[]{ 44 + i, 0, Set.of()});
|
||||
result.add(new Object[]{ 44 + i, 0, Set.of(TRANSITIVE)});
|
||||
}
|
||||
|
||||
result.add(new Object[]{ 44 + FEATURE,
|
||||
PREVIEW_MINOR_VERSION,
|
||||
Set.of()});
|
||||
result.add(new Object[]{ 44 + FEATURE,
|
||||
PREVIEW_MINOR_VERSION,
|
||||
Set.of(TRANSITIVE) });
|
||||
|
||||
return result.toArray(s -> new Object[s][]);
|
||||
}
|
||||
|
||||
// major, minor, modifiers for requires java.base
|
||||
@DataProvider(name = "unsupported")
|
||||
public Object[][] unsupported() {
|
||||
/*
|
||||
* There are three test cases for releases prior to JDK 9,
|
||||
* three test cases for each JDK version from JDK 10 to the
|
||||
* current feature release, two tests for the current release with
|
||||
* the preview flag set, plus one addition test case for
|
||||
* the next release for a total of (3 + (FEATURE - 9) * 3 + 2 + 1)
|
||||
* rows.
|
||||
*/
|
||||
List<Object[]> result = new ArrayList<>(3 + (FEATURE - 9) * 3 + 2 + 1);
|
||||
|
||||
result.add(new Object[]{50, 0, Set.of()}); // JDK 6
|
||||
result.add(new Object[]{51, 0, Set.of()}); // JDK 7
|
||||
result.add(new Object[]{52, 0, Set.of()}); // JDK 8
|
||||
|
||||
for (int i = 10; i <= FEATURE ; i++) {
|
||||
// Major class file version of JDK N is 44+n
|
||||
result.add(new Object[]{i + 44, 0, Set.of(STATIC)});
|
||||
result.add(new Object[]{i + 44, 0, Set.of(STATIC, TRANSITIVE)});
|
||||
}
|
||||
|
||||
result.add(new Object[]{FEATURE + 44,
|
||||
PREVIEW_MINOR_VERSION,
|
||||
Set.of(STATIC)});
|
||||
result.add(new Object[]{FEATURE + 44,
|
||||
PREVIEW_MINOR_VERSION,
|
||||
Set.of(STATIC, TRANSITIVE)});
|
||||
|
||||
result.add(new Object[]{FEATURE+1+44, 0, Set.of()});
|
||||
|
||||
return result.toArray(s -> new Object[s][]);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "supported")
|
||||
public void testSupported(int major, int minor, Set<Modifier> ms) {
|
||||
ModuleDescriptor descriptor = ModuleDescriptor.newModule("foo")
|
||||
.requires(ms, "java.base")
|
||||
.build();
|
||||
ByteBuffer bb = ModuleInfoWriter.toByteBuffer(descriptor);
|
||||
classFileVersion(bb, major, minor);
|
||||
descriptor = ModuleDescriptor.read(bb);
|
||||
assertEquals(descriptor.name(), "foo");
|
||||
}
|
||||
|
||||
@Test(dataProvider = "unsupported",
|
||||
expectedExceptions = InvalidModuleDescriptorException.class)
|
||||
public void testUnsupported(int major, int minor, Set<Modifier> ms) {
|
||||
ModuleDescriptor descriptor = ModuleDescriptor.newModule("foo")
|
||||
.requires(ms, "java.base")
|
||||
.build();
|
||||
ByteBuffer bb = ModuleInfoWriter.toByteBuffer(descriptor);
|
||||
classFileVersion(bb, major, minor);
|
||||
|
||||
// throws InvalidModuleDescriptorException
|
||||
ModuleDescriptor.read(bb);
|
||||
}
|
||||
|
||||
private void classFileVersion(ByteBuffer bb, int major, int minor) {
|
||||
bb.putShort(4, (short) minor);
|
||||
bb.putShort(6, (short) major);
|
||||
}
|
||||
}
|
||||
2292
test/jdk/java/lang/module/ConfigurationTest.java
Normal file
2292
test/jdk/java/lang/module/ConfigurationTest.java
Normal file
File diff suppressed because it is too large
Load diff
190
test/jdk/java/lang/module/ModuleDescriptorHashCodeTest.java
Normal file
190
test/jdk/java/lang/module/ModuleDescriptorHashCodeTest.java
Normal file
|
|
@ -0,0 +1,190 @@
|
|||
/*
|
||||
* Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.lang.module.ModuleDescriptor;
|
||||
import java.lang.module.ModuleDescriptor.Exports;
|
||||
import java.lang.module.ModuleDescriptor.Opens;
|
||||
import java.lang.module.ModuleDescriptor.Requires;
|
||||
import java.util.Set;
|
||||
|
||||
import org.testng.annotations.Test;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertNotSame;
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 8275509 8290041
|
||||
* @summary Tests the ModuleDescriptor.hashCode()
|
||||
* @run testng ModuleDescriptorHashCodeTest
|
||||
* @run testng/othervm -Xshare:off ModuleDescriptorHashCodeTest
|
||||
*/
|
||||
public class ModuleDescriptorHashCodeTest {
|
||||
|
||||
/**
|
||||
* Verifies that the ModuleDescriptor.hashCode() returned by a boot layer module is
|
||||
* the same as that returned by a ModuleDescriptor constructed from the ModuleDescriptor.Builder
|
||||
* for the same module.
|
||||
*/
|
||||
@Test
|
||||
public void testBootModuleDescriptor() throws Exception {
|
||||
Set<Module> bootModules = ModuleLayer.boot().modules();
|
||||
for (Module bootModule : bootModules) {
|
||||
System.out.println("Testing module descriptor of boot module " + bootModule);
|
||||
ModuleDescriptor bootMD = bootModule.getDescriptor();
|
||||
ModuleDescriptor mdFromBuilder = fromModuleInfoClass(bootModule);
|
||||
// verify that this object is indeed a different object instance than the boot module descriptor
|
||||
// to prevent any artificial passing of the test
|
||||
assertNotSame(mdFromBuilder, bootMD, "ModuleDescriptor loaded from boot layer and " +
|
||||
"one created from module-info.class unexpectedly returned the same instance");
|
||||
assertEquals(mdFromBuilder.hashCode(), bootMD.hashCode(),
|
||||
"Unexpected ModuleDescriptor.hashCode() for " + mdFromBuilder);
|
||||
assertEquals(mdFromBuilder.compareTo(bootMD), 0,
|
||||
"Unexpected ModuleDescriptor.compareTo() for " + mdFromBuilder);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that two "equal" module descriptors which only differ in the order of
|
||||
* {@link ModuleDescriptor.Opens.Modifier opens modifiers}, that were used to construct the
|
||||
* descriptors, have the same hashcode.
|
||||
*/
|
||||
@Test
|
||||
public void testOpensModifiersOrdering() throws Exception {
|
||||
// important to use Set.of() (i.e. backed by immutable set) to reproduce the issue
|
||||
final Set<Opens.Modifier> mods1 = Set.of(Opens.Modifier.SYNTHETIC, Opens.Modifier.MANDATED);
|
||||
final ModuleDescriptor desc1 = createModuleDescriptor(mods1, null, null);
|
||||
|
||||
// create the same module descriptor again and this time just change the order of the
|
||||
// "opens" modifiers' Set.
|
||||
|
||||
// important to use Set.of() (i.e. backed by immutable set) to reproduce the issue
|
||||
final Set<Opens.Modifier> mods2 = Set.of(Opens.Modifier.MANDATED, Opens.Modifier.SYNTHETIC);
|
||||
final ModuleDescriptor desc2 = createModuleDescriptor(mods2, null, null);
|
||||
|
||||
// basic verification of the modifiers themselves before we check the module descriptors
|
||||
assertEquals(mods1, mods2, "Modifiers were expected to be equal");
|
||||
|
||||
// now verify the module descriptors
|
||||
assertEquals(desc1, desc2, "Module descriptors were expected to be equal");
|
||||
assertEquals(desc1.compareTo(desc2), 0, "compareTo was expected to return" +
|
||||
" 0 for module descriptors that are equal");
|
||||
System.out.println(desc1 + " hashcode = " + desc1.hashCode());
|
||||
System.out.println(desc2 + " hashcode = " + desc2.hashCode());
|
||||
assertEquals(desc1.hashCode(), desc2.hashCode(), "Module descriptor hashcodes" +
|
||||
" were expected to be equal");
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that two "equal" module descriptors which only differ in the order of
|
||||
* {@link ModuleDescriptor.Exports.Modifier exports modifiers}, that were used to construct the
|
||||
* descriptors, have the same hashcode.
|
||||
*/
|
||||
@Test
|
||||
public void testExportsModifiersOrdering() throws Exception {
|
||||
// important to use Set.of() (i.e. backed by immutable set) to reproduce the issue
|
||||
final Set<Exports.Modifier> mods1 = Set.of(Exports.Modifier.SYNTHETIC, Exports.Modifier.MANDATED);
|
||||
final ModuleDescriptor desc1 = createModuleDescriptor(null, null, mods1);
|
||||
|
||||
// create the same module descriptor again and this time just change the order of the
|
||||
// "exports" modifiers' Set.
|
||||
|
||||
// important to use Set.of() (i.e. backed by immutable set) to reproduce the issue
|
||||
final Set<Exports.Modifier> mods2 = Set.of(Exports.Modifier.MANDATED, Exports.Modifier.SYNTHETIC);
|
||||
final ModuleDescriptor desc2 = createModuleDescriptor(null, null, mods2);
|
||||
|
||||
// basic verification of the modifiers themselves before we check the module descriptors
|
||||
assertEquals(mods1, mods2, "Modifiers were expected to be equal");
|
||||
|
||||
// now verify the module descriptors
|
||||
assertEquals(desc1, desc2, "Module descriptors were expected to be equal");
|
||||
assertEquals(desc1.compareTo(desc2), 0, "compareTo was expected to return" +
|
||||
" 0 for module descriptors that are equal");
|
||||
System.out.println(desc1 + " hashcode = " + desc1.hashCode());
|
||||
System.out.println(desc2 + " hashcode = " + desc2.hashCode());
|
||||
assertEquals(desc1.hashCode(), desc2.hashCode(), "Module descriptor hashcodes" +
|
||||
" were expected to be equal");
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that two "equal" module descriptors which only differ in the order of
|
||||
* {@link ModuleDescriptor.Requires.Modifier requires modifiers}, that were used to construct the
|
||||
* descriptors, have the same hashcode.
|
||||
*/
|
||||
@Test
|
||||
public void testRequiresModifiersOrdering() throws Exception {
|
||||
// important to use Set.of() (i.e. backed by immutable set) to reproduce the issue
|
||||
final Set<Requires.Modifier> mods1 = Set.of(Requires.Modifier.SYNTHETIC, Requires.Modifier.MANDATED);
|
||||
final ModuleDescriptor desc1 = createModuleDescriptor(null, mods1, null);
|
||||
|
||||
// create the same module descriptor again and this time just change the order of the
|
||||
// "exports" modifiers' Set.
|
||||
|
||||
// important to use Set.of() (i.e. backed by immutable set) to reproduce the issue
|
||||
final Set<Requires.Modifier> mods2 = Set.of(Requires.Modifier.MANDATED, Requires.Modifier.SYNTHETIC);
|
||||
final ModuleDescriptor desc2 = createModuleDescriptor(null, mods2, null);
|
||||
|
||||
// basic verification of the modifiers themselves before we check the module descriptors
|
||||
assertEquals(mods1, mods2, "Modifiers were expected to be equal");
|
||||
|
||||
// now verify the module descriptors
|
||||
assertEquals(desc1, desc2, "Module descriptors were expected to be equal");
|
||||
assertEquals(desc1.compareTo(desc2), 0, "compareTo was expected to return" +
|
||||
" 0 for module descriptors that are equal");
|
||||
System.out.println(desc1 + " hashcode = " + desc1.hashCode());
|
||||
System.out.println(desc2 + " hashcode = " + desc2.hashCode());
|
||||
assertEquals(desc1.hashCode(), desc2.hashCode(), "Module descriptor hashcodes" +
|
||||
" were expected to be equal");
|
||||
}
|
||||
|
||||
// Returns a ModuleDescriptor parsed out of the module-info.class of the passed Module
|
||||
private static ModuleDescriptor fromModuleInfoClass(Module module) throws IOException {
|
||||
try (InputStream moduleInfo = module.getResourceAsStream("module-info.class")) {
|
||||
if (moduleInfo == null) {
|
||||
throw new RuntimeException("Could not locate module-info.class in " + module);
|
||||
}
|
||||
// internally calls ModuleDescriptor.Builder
|
||||
return ModuleDescriptor.read(moduleInfo);
|
||||
}
|
||||
}
|
||||
|
||||
// creates a module descriptor with passed (optional) opens/exports/requires modifiers
|
||||
private static ModuleDescriptor createModuleDescriptor(
|
||||
Set<Opens.Modifier> opensModifiers,
|
||||
Set<Requires.Modifier> reqsModifiers,
|
||||
Set<Exports.Modifier> expsModifiers) {
|
||||
|
||||
final ModuleDescriptor.Builder builder = ModuleDescriptor.newModule("foobar");
|
||||
if (opensModifiers != null) {
|
||||
builder.opens(opensModifiers, "a.p1", Set.of("a.m1"));
|
||||
}
|
||||
if (reqsModifiers != null) {
|
||||
builder.requires(reqsModifiers, "a.m2");
|
||||
}
|
||||
if (expsModifiers != null) {
|
||||
builder.exports(expsModifiers, "a.b.c", Set.of("a.m3"));
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
}
|
||||
1588
test/jdk/java/lang/module/ModuleDescriptorTest.java
Normal file
1588
test/jdk/java/lang/module/ModuleDescriptorTest.java
Normal file
File diff suppressed because it is too large
Load diff
829
test/jdk/java/lang/module/ModuleFinderTest.java
Normal file
829
test/jdk/java/lang/module/ModuleFinderTest.java
Normal file
|
|
@ -0,0 +1,829 @@
|
|||
/*
|
||||
* Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @modules java.base/jdk.internal.module
|
||||
* @library /test/lib
|
||||
* @build ModuleFinderTest jdk.test.lib.util.ModuleInfoWriter
|
||||
* @run testng ModuleFinderTest
|
||||
* @summary Basic tests for java.lang.module.ModuleFinder
|
||||
*/
|
||||
|
||||
import java.io.File;
|
||||
import java.io.OutputStream;
|
||||
import java.lang.module.FindException;
|
||||
import java.lang.module.InvalidModuleDescriptorException;
|
||||
import java.lang.module.ModuleDescriptor;
|
||||
import java.lang.module.ModuleFinder;
|
||||
import java.lang.module.ModuleReference;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.jar.JarEntry;
|
||||
import java.util.jar.JarOutputStream;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import jdk.test.lib.util.ModuleInfoWriter;
|
||||
|
||||
import org.testng.annotations.Test;
|
||||
import static org.testng.Assert.*;
|
||||
|
||||
@Test
|
||||
public class ModuleFinderTest {
|
||||
|
||||
private static final Path USER_DIR
|
||||
= Paths.get(System.getProperty("user.dir"));
|
||||
|
||||
|
||||
/**
|
||||
* Test ModuleFinder.ofSystem
|
||||
*/
|
||||
public void testOfSystem() {
|
||||
ModuleFinder finder = ModuleFinder.ofSystem();
|
||||
|
||||
assertTrue(finder.find("java.se").isPresent());
|
||||
assertTrue(finder.find("java.base").isPresent());
|
||||
assertFalse(finder.find("java.rhubarb").isPresent());
|
||||
|
||||
Set<String> names = finder.findAll().stream()
|
||||
.map(ModuleReference::descriptor)
|
||||
.map(ModuleDescriptor::name)
|
||||
.collect(Collectors.toSet());
|
||||
assertTrue(names.contains("java.se"));
|
||||
assertTrue(names.contains("java.base"));
|
||||
assertFalse(names.contains("java.rhubarb"));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test ModuleFinder.of with no entries
|
||||
*/
|
||||
public void testOfNoEntries() {
|
||||
ModuleFinder finder = ModuleFinder.of();
|
||||
assertTrue(finder.findAll().isEmpty());
|
||||
assertFalse(finder.find("java.rhubarb").isPresent());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test ModuleFinder.of with one directory of modules
|
||||
*/
|
||||
public void testOfOneDirectory() throws Exception {
|
||||
Path dir = Files.createTempDirectory(USER_DIR, "mods");
|
||||
createExplodedModule(dir.resolve("m1"), "m1");
|
||||
createModularJar(dir.resolve("m2.jar"), "m2");
|
||||
|
||||
ModuleFinder finder = ModuleFinder.of(dir);
|
||||
assertTrue(finder.findAll().size() == 2);
|
||||
assertTrue(finder.find("m1").isPresent());
|
||||
assertTrue(finder.find("m2").isPresent());
|
||||
assertFalse(finder.find("java.rhubarb").isPresent());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test ModuleFinder.of with two directories
|
||||
*/
|
||||
public void testOfTwoDirectories() throws Exception {
|
||||
Path dir1 = Files.createTempDirectory(USER_DIR, "mods1");
|
||||
createExplodedModule(dir1.resolve("m1"), "m1@1.0");
|
||||
createModularJar(dir1.resolve("m2.jar"), "m2@1.0");
|
||||
|
||||
Path dir2 = Files.createTempDirectory(USER_DIR, "mods2");
|
||||
createExplodedModule(dir2.resolve("m1"), "m1@2.0");
|
||||
createModularJar(dir2.resolve("m2.jar"), "m2@2.0");
|
||||
createExplodedModule(dir2.resolve("m3"), "m3");
|
||||
createModularJar(dir2.resolve("m4.jar"), "m4");
|
||||
|
||||
ModuleFinder finder = ModuleFinder.of(dir1, dir2);
|
||||
assertTrue(finder.findAll().size() == 4);
|
||||
assertTrue(finder.find("m1").isPresent());
|
||||
assertTrue(finder.find("m2").isPresent());
|
||||
assertTrue(finder.find("m3").isPresent());
|
||||
assertTrue(finder.find("m4").isPresent());
|
||||
assertFalse(finder.find("java.rhubarb").isPresent());
|
||||
|
||||
// check that m1@1.0 (and not m1@2.0) is found
|
||||
ModuleDescriptor m1 = finder.find("m1").get().descriptor();
|
||||
assertEquals(m1.version().get().toString(), "1.0");
|
||||
|
||||
// check that m2@1.0 (and not m2@2.0) is found
|
||||
ModuleDescriptor m2 = finder.find("m2").get().descriptor();
|
||||
assertEquals(m2.version().get().toString(), "1.0");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test ModuleFinder.of with one JAR file
|
||||
*/
|
||||
public void testOfOneJarFile() throws Exception {
|
||||
Path dir = Files.createTempDirectory(USER_DIR, "mods");
|
||||
Path jar1 = createModularJar(dir.resolve("m1.jar"), "m1");
|
||||
|
||||
ModuleFinder finder = ModuleFinder.of(jar1);
|
||||
assertTrue(finder.findAll().size() == 1);
|
||||
assertTrue(finder.find("m1").isPresent());
|
||||
assertFalse(finder.find("java.rhubarb").isPresent());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test ModuleFinder.of with two JAR files
|
||||
*/
|
||||
public void testOfTwoJarFiles() throws Exception {
|
||||
Path dir = Files.createTempDirectory(USER_DIR, "mods");
|
||||
|
||||
Path jar1 = createModularJar(dir.resolve("m1.jar"), "m1");
|
||||
Path jar2 = createModularJar(dir.resolve("m2.jar"), "m2");
|
||||
|
||||
ModuleFinder finder = ModuleFinder.of(jar1, jar2);
|
||||
assertTrue(finder.findAll().size() == 2);
|
||||
assertTrue(finder.find("m1").isPresent());
|
||||
assertTrue(finder.find("m2").isPresent());
|
||||
assertFalse(finder.find("java.rhubarb").isPresent());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test ModuleFinder.of with many JAR files
|
||||
*/
|
||||
public void testOfManyJarFiles() throws Exception {
|
||||
Path dir = Files.createTempDirectory(USER_DIR, "mods");
|
||||
|
||||
Path jar1 = createModularJar(dir.resolve("m1@1.0.jar"), "m1@1.0");
|
||||
Path jar2 = createModularJar(dir.resolve("m2@1.0.jar"), "m2");
|
||||
Path jar3 = createModularJar(dir.resolve("m1@2.0.jar"), "m1@2.0"); // shadowed
|
||||
Path jar4 = createModularJar(dir.resolve("m3@1.0.jar"), "m3");
|
||||
|
||||
ModuleFinder finder = ModuleFinder.of(jar1, jar2, jar3, jar4);
|
||||
assertTrue(finder.findAll().size() == 3);
|
||||
assertTrue(finder.find("m1").isPresent());
|
||||
assertTrue(finder.find("m2").isPresent());
|
||||
assertTrue(finder.find("m3").isPresent());
|
||||
assertFalse(finder.find("java.rhubarb").isPresent());
|
||||
|
||||
// check that m1@1.0 (and not m1@2.0) is found
|
||||
ModuleDescriptor m1 = finder.find("m1").get().descriptor();
|
||||
assertEquals(m1.version().get().toString(), "1.0");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test ModuleFinder.of with one exploded module.
|
||||
*/
|
||||
public void testOfOneExplodedModule() throws Exception {
|
||||
Path dir = Files.createTempDirectory(USER_DIR, "mods");
|
||||
Path m1_dir = createExplodedModule(dir.resolve("m1"), "m1");
|
||||
|
||||
ModuleFinder finder = ModuleFinder.of(m1_dir);
|
||||
assertTrue(finder.findAll().size() == 1);
|
||||
assertTrue(finder.find("m1").isPresent());
|
||||
assertFalse(finder.find("java.rhubarb").isPresent());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test ModuleFinder.of with two exploded modules.
|
||||
*/
|
||||
public void testOfTwoExplodedModules() throws Exception {
|
||||
Path dir = Files.createTempDirectory(USER_DIR, "mods");
|
||||
Path m1_dir = createExplodedModule(dir.resolve("m1"), "m1");
|
||||
Path m2_dir = createExplodedModule(dir.resolve("m2"), "m2");
|
||||
|
||||
ModuleFinder finder = ModuleFinder.of(m1_dir, m2_dir);
|
||||
assertTrue(finder.findAll().size() == 2);
|
||||
assertTrue(finder.find("m1").isPresent());
|
||||
assertTrue(finder.find("m2").isPresent());
|
||||
assertFalse(finder.find("java.rhubarb").isPresent());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test ModuleFinder.of with a mix of module directories and JAR files.
|
||||
*/
|
||||
public void testOfMixDirectoriesAndJars() throws Exception {
|
||||
|
||||
// directory with m1@1.0 and m2@1.0
|
||||
Path dir1 = Files.createTempDirectory(USER_DIR, "mods1");
|
||||
createExplodedModule(dir1.resolve("m1"), "m1@1.0");
|
||||
createModularJar(dir1.resolve("m2.jar"), "m2@1.0");
|
||||
|
||||
// JAR files: m1@2.0, m2@2.0, m3@2.0, m4@2.0
|
||||
Path dir2 = Files.createTempDirectory(USER_DIR, "mods2");
|
||||
Path jar1 = createModularJar(dir2.resolve("m1.jar"), "m1@2.0");
|
||||
Path jar2 = createModularJar(dir2.resolve("m2.jar"), "m2@2.0");
|
||||
Path jar3 = createModularJar(dir2.resolve("m3.jar"), "m3@2.0");
|
||||
Path jar4 = createModularJar(dir2.resolve("m4.jar"), "m4@2.0");
|
||||
|
||||
// directory with m3@3.0 and m4@3.0
|
||||
Path dir3 = Files.createTempDirectory(USER_DIR, "mods3");
|
||||
createExplodedModule(dir3.resolve("m3"), "m3@3.0");
|
||||
createModularJar(dir3.resolve("m4.jar"), "m4@3.0");
|
||||
|
||||
// JAR files: m5 and m6
|
||||
Path dir4 = Files.createTempDirectory(USER_DIR, "mods4");
|
||||
Path jar5 = createModularJar(dir4.resolve("m5.jar"), "m5@4.0");
|
||||
Path jar6 = createModularJar(dir4.resolve("m6.jar"), "m6@4.0");
|
||||
|
||||
|
||||
ModuleFinder finder
|
||||
= ModuleFinder.of(dir1, jar1, jar2, jar3, jar4, dir3, jar5, jar6);
|
||||
assertTrue(finder.findAll().size() == 6);
|
||||
assertTrue(finder.find("m1").isPresent());
|
||||
assertTrue(finder.find("m2").isPresent());
|
||||
assertTrue(finder.find("m3").isPresent());
|
||||
assertTrue(finder.find("m4").isPresent());
|
||||
assertTrue(finder.find("m5").isPresent());
|
||||
assertTrue(finder.find("m6").isPresent());
|
||||
assertFalse(finder.find("java.rhubarb").isPresent());
|
||||
|
||||
// m1 and m2 should be located in dir1
|
||||
ModuleDescriptor m1 = finder.find("m1").get().descriptor();
|
||||
assertEquals(m1.version().get().toString(), "1.0");
|
||||
ModuleDescriptor m2 = finder.find("m2").get().descriptor();
|
||||
assertEquals(m2.version().get().toString(), "1.0");
|
||||
|
||||
// m3 and m4 should be located in JAR files
|
||||
ModuleDescriptor m3 = finder.find("m3").get().descriptor();
|
||||
assertEquals(m3.version().get().toString(), "2.0");
|
||||
ModuleDescriptor m4 = finder.find("m4").get().descriptor();
|
||||
assertEquals(m4.version().get().toString(), "2.0");
|
||||
|
||||
// m5 and m6 should be located in JAR files
|
||||
ModuleDescriptor m5 = finder.find("m5").get().descriptor();
|
||||
assertEquals(m5.version().get().toString(), "4.0");
|
||||
ModuleDescriptor m6 = finder.find("m6").get().descriptor();
|
||||
assertEquals(m6.version().get().toString(), "4.0");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test ModuleFinder.of with a mix of module directories and exploded
|
||||
* modules.
|
||||
*/
|
||||
public void testOfMixDirectoriesAndExplodedModules() throws Exception {
|
||||
// directory with m1@1.0 and m2@1.0
|
||||
Path dir1 = Files.createTempDirectory(USER_DIR, "mods1");
|
||||
createExplodedModule(dir1.resolve("m1"), "m1@1.0");
|
||||
createModularJar(dir1.resolve("m2.jar"), "m2@1.0");
|
||||
|
||||
// exploded modules: m1@2.0, m2@2.0, m3@2.0, m4@2.0
|
||||
Path dir2 = Files.createTempDirectory(USER_DIR, "mods2");
|
||||
Path m1_dir = createExplodedModule(dir2.resolve("m1"), "m1@2.0");
|
||||
Path m2_dir = createExplodedModule(dir2.resolve("m2"), "m2@2.0");
|
||||
Path m3_dir = createExplodedModule(dir2.resolve("m3"), "m3@2.0");
|
||||
Path m4_dir = createExplodedModule(dir2.resolve("m4"), "m4@2.0");
|
||||
|
||||
ModuleFinder finder = ModuleFinder.of(dir1, m1_dir, m2_dir, m3_dir, m4_dir);
|
||||
assertTrue(finder.findAll().size() == 4);
|
||||
assertTrue(finder.find("m1").isPresent());
|
||||
assertTrue(finder.find("m2").isPresent());
|
||||
assertTrue(finder.find("m3").isPresent());
|
||||
assertTrue(finder.find("m4").isPresent());
|
||||
assertFalse(finder.find("java.rhubarb").isPresent());
|
||||
|
||||
// m1 and m2 should be located in dir1
|
||||
ModuleDescriptor m1 = finder.find("m1").get().descriptor();
|
||||
assertEquals(m1.version().get().toString(), "1.0");
|
||||
ModuleDescriptor m2 = finder.find("m2").get().descriptor();
|
||||
assertEquals(m2.version().get().toString(), "1.0");
|
||||
|
||||
// m3 and m4 should be located in dir2
|
||||
ModuleDescriptor m3 = finder.find("m3").get().descriptor();
|
||||
assertEquals(m3.version().get().toString(), "2.0");
|
||||
ModuleDescriptor m4 = finder.find("m4").get().descriptor();
|
||||
assertEquals(m4.version().get().toString(), "2.0");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test ModuleFinder with a JAR file containing a mix of class and
|
||||
* non-class resources.
|
||||
*/
|
||||
public void testOfOneJarFileWithResources() throws Exception {
|
||||
Path dir = Files.createTempDirectory(USER_DIR, "mods");
|
||||
Path jar = createModularJar(dir.resolve("m.jar"), "m",
|
||||
"LICENSE",
|
||||
"README",
|
||||
"WEB-INF/tags",
|
||||
"p/Type.class",
|
||||
"p/resources/m.properties",
|
||||
"q-/Type.class", // not a legal package name
|
||||
"q-/resources/m/properties");
|
||||
|
||||
ModuleFinder finder = ModuleFinder.of(jar);
|
||||
Optional<ModuleReference> mref = finder.find("m");
|
||||
assertTrue(mref.isPresent(), "m1 not found");
|
||||
|
||||
ModuleDescriptor descriptor = mref.get().descriptor();
|
||||
|
||||
assertTrue(descriptor.packages().size() == 2);
|
||||
assertTrue(descriptor.packages().contains("p"));
|
||||
assertTrue(descriptor.packages().contains("p.resources"));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test ModuleFinder with an exploded module containing a mix of class
|
||||
* and non-class resources
|
||||
*/
|
||||
public void testOfOneExplodedModuleWithResources() throws Exception {
|
||||
Path dir = Files.createTempDirectory(USER_DIR, "mods");
|
||||
Path m_dir = createExplodedModule(dir.resolve("m"), "m",
|
||||
"LICENSE",
|
||||
"README",
|
||||
"WEB-INF/tags",
|
||||
"p/Type.class",
|
||||
"p/resources/m.properties",
|
||||
"q-/Type.class", // not a legal package name
|
||||
"q-/resources/m/properties");
|
||||
|
||||
ModuleFinder finder = ModuleFinder.of(m_dir);
|
||||
Optional<ModuleReference> mref = finder.find("m");
|
||||
assertTrue(mref.isPresent(), "m not found");
|
||||
|
||||
ModuleDescriptor descriptor = mref.get().descriptor();
|
||||
|
||||
assertTrue(descriptor.packages().size() == 2);
|
||||
assertTrue(descriptor.packages().contains("p"));
|
||||
assertTrue(descriptor.packages().contains("p.resources"));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test ModuleFinder with a JAR file containing a .class file in the top
|
||||
* level directory.
|
||||
*/
|
||||
public void testOfOneJarFileWithTopLevelClass() throws Exception {
|
||||
Path dir = Files.createTempDirectory(USER_DIR, "mods");
|
||||
Path jar = createModularJar(dir.resolve("m.jar"), "m", "Mojo.class");
|
||||
|
||||
ModuleFinder finder = ModuleFinder.of(jar);
|
||||
try {
|
||||
finder.find("m");
|
||||
assertTrue(false);
|
||||
} catch (FindException e) {
|
||||
assertTrue(e.getCause() instanceof InvalidModuleDescriptorException);
|
||||
assertTrue(e.getCause().getMessage().contains("Mojo.class"));
|
||||
}
|
||||
|
||||
finder = ModuleFinder.of(jar);
|
||||
try {
|
||||
finder.findAll();
|
||||
assertTrue(false);
|
||||
} catch (FindException e) {
|
||||
assertTrue(e.getCause() instanceof InvalidModuleDescriptorException);
|
||||
assertTrue(e.getCause().getMessage().contains("Mojo.class"));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test ModuleFinder with a JAR file containing a .class file in the top
|
||||
* level directory.
|
||||
*/
|
||||
public void testOfOneExplodedModuleWithTopLevelClass() throws Exception {
|
||||
Path dir = Files.createTempDirectory(USER_DIR, "mods");
|
||||
Path m_dir = createExplodedModule(dir.resolve("m"), "m", "Mojo.class");
|
||||
|
||||
ModuleFinder finder = ModuleFinder.of(m_dir);
|
||||
try {
|
||||
finder.find("m");
|
||||
assertTrue(false);
|
||||
} catch (FindException e) {
|
||||
assertTrue(e.getCause() instanceof InvalidModuleDescriptorException);
|
||||
assertTrue(e.getCause().getMessage().contains("Mojo.class"));
|
||||
}
|
||||
|
||||
finder = ModuleFinder.of(m_dir);
|
||||
try {
|
||||
finder.findAll();
|
||||
assertTrue(false);
|
||||
} catch (FindException e) {
|
||||
assertTrue(e.getCause() instanceof InvalidModuleDescriptorException);
|
||||
assertTrue(e.getCause().getMessage().contains("Mojo.class"));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test ModuleFinder.of with a path to a file that does not exist.
|
||||
*/
|
||||
public void testOfWithDoesNotExistEntry() throws Exception {
|
||||
Path dir1 = Files.createTempDirectory(USER_DIR, "mods1");
|
||||
|
||||
Path dir2 = Files.createTempDirectory(USER_DIR, "mods2");
|
||||
createModularJar(dir2.resolve("m2.jar"), "m2@1.0");
|
||||
|
||||
Files.delete(dir1);
|
||||
|
||||
ModuleFinder finder = ModuleFinder.of(dir1, dir2);
|
||||
|
||||
assertTrue(finder.find("m2").isPresent());
|
||||
assertTrue(finder.findAll().size() == 1);
|
||||
assertFalse(finder.find("java.rhubarb").isPresent());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test ModuleFinder.of with a file path to an unrecognized file type.
|
||||
*/
|
||||
public void testOfWithUnrecognizedEntry() throws Exception {
|
||||
Path dir = Files.createTempDirectory(USER_DIR, "mods");
|
||||
Path mod = Files.createTempFile(dir, "m", ".junk");
|
||||
|
||||
ModuleFinder finder = ModuleFinder.of(mod);
|
||||
try {
|
||||
finder.find("java.rhubarb");
|
||||
assertTrue(false);
|
||||
} catch (FindException e) {
|
||||
// expected
|
||||
}
|
||||
|
||||
finder = ModuleFinder.of(mod);
|
||||
try {
|
||||
finder.findAll();
|
||||
assertTrue(false);
|
||||
} catch (FindException e) {
|
||||
// expected
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test ModuleFinder.of with a file path to a directory containing a file
|
||||
* that will not be recognized as a module.
|
||||
*/
|
||||
public void testOfWithUnrecognizedEntryInDirectory1() throws Exception {
|
||||
Path dir = Files.createTempDirectory(USER_DIR, "mods");
|
||||
Files.createTempFile(dir, "m", ".junk");
|
||||
|
||||
ModuleFinder finder = ModuleFinder.of(dir);
|
||||
assertFalse(finder.find("java.rhubarb").isPresent());
|
||||
|
||||
finder = ModuleFinder.of(dir);
|
||||
assertTrue(finder.findAll().isEmpty());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test ModuleFinder.of with a file path to a directory containing a file
|
||||
* that will not be recognized as a module.
|
||||
*/
|
||||
public void testOfWithUnrecognizedEntryInDirectory2() throws Exception {
|
||||
Path dir = Files.createTempDirectory(USER_DIR, "mods");
|
||||
createModularJar(dir.resolve("m1.jar"), "m1");
|
||||
Files.createTempFile(dir, "m2", ".junk");
|
||||
|
||||
ModuleFinder finder = ModuleFinder.of(dir);
|
||||
assertTrue(finder.find("m1").isPresent());
|
||||
assertFalse(finder.find("m2").isPresent());
|
||||
|
||||
finder = ModuleFinder.of(dir);
|
||||
assertTrue(finder.findAll().size() == 1);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test ModuleFinder.of with a directory that contains two
|
||||
* versions of the same module
|
||||
*/
|
||||
public void testOfDuplicateModulesInDirectory() throws Exception {
|
||||
Path dir = Files.createTempDirectory(USER_DIR, "mods");
|
||||
createModularJar(dir.resolve("m1@1.0.jar"), "m1");
|
||||
createModularJar(dir.resolve("m1@2.0.jar"), "m1");
|
||||
|
||||
ModuleFinder finder = ModuleFinder.of(dir);
|
||||
try {
|
||||
finder.find("m1");
|
||||
assertTrue(false);
|
||||
} catch (FindException expected) { }
|
||||
|
||||
finder = ModuleFinder.of(dir);
|
||||
try {
|
||||
finder.findAll();
|
||||
assertTrue(false);
|
||||
} catch (FindException expected) { }
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test ModuleFinder.of with a directory containing hidden files
|
||||
*/
|
||||
public void testOfWithHiddenFiles() throws Exception {
|
||||
Path dir = Files.createTempDirectory(USER_DIR, "mods");
|
||||
createExplodedModule(dir.resolve("m"), "m",
|
||||
"com/.ignore",
|
||||
"com/foo/.ignore",
|
||||
"com/foo/foo.properties");
|
||||
|
||||
ModuleFinder finder = ModuleFinder.of(dir);
|
||||
ModuleReference mref = finder.find("m").orElse(null);
|
||||
assertNotNull(mref);
|
||||
|
||||
Set<String> expectedPackages;
|
||||
if (System.getProperty("os.name").startsWith("Windows")) {
|
||||
expectedPackages = Set.of("com", "com.foo");
|
||||
} else {
|
||||
expectedPackages = Set.of("com.foo");
|
||||
}
|
||||
assertEquals(mref.descriptor().packages(), expectedPackages);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test ModuleFinder.of with a truncated module-info.class
|
||||
*/
|
||||
public void testOfWithTruncatedModuleInfo() throws Exception {
|
||||
Path dir = Files.createTempDirectory(USER_DIR, "mods");
|
||||
|
||||
// create an empty <dir>/rhubarb/module-info.class
|
||||
Path subdir = Files.createDirectory(dir.resolve("rhubarb"));
|
||||
Files.createFile(subdir.resolve("module-info.class"));
|
||||
|
||||
ModuleFinder finder = ModuleFinder.of(dir);
|
||||
try {
|
||||
finder.find("rhubarb");
|
||||
assertTrue(false);
|
||||
} catch (FindException e) {
|
||||
assertTrue(e.getCause() instanceof InvalidModuleDescriptorException);
|
||||
}
|
||||
|
||||
finder = ModuleFinder.of(dir);
|
||||
try {
|
||||
finder.findAll();
|
||||
assertTrue(false);
|
||||
} catch (FindException e) {
|
||||
assertTrue(e.getCause() instanceof InvalidModuleDescriptorException);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test ModuleFinder.compose with no module finders
|
||||
*/
|
||||
public void testComposeOfNone() throws Exception {
|
||||
ModuleFinder finder = ModuleFinder.of();
|
||||
assertTrue(finder.findAll().isEmpty());
|
||||
assertFalse(finder.find("java.rhubarb").isPresent());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test ModuleFinder.compose with one module finder
|
||||
*/
|
||||
public void testComposeOfOne() throws Exception {
|
||||
Path dir = Files.createTempDirectory(USER_DIR, "mods");
|
||||
createModularJar(dir.resolve("m1.jar"), "m1");
|
||||
createModularJar(dir.resolve("m2.jar"), "m2");
|
||||
|
||||
ModuleFinder finder1 = ModuleFinder.of(dir);
|
||||
|
||||
ModuleFinder finder = ModuleFinder.compose(finder1);
|
||||
assertTrue(finder.findAll().size() == 2);
|
||||
assertTrue(finder.find("m1").isPresent());
|
||||
assertTrue(finder.find("m2").isPresent());
|
||||
assertFalse(finder.find("java.rhubarb").isPresent());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test ModuleFinder.compose with two module finders
|
||||
*/
|
||||
public void testComposeOfTwo() throws Exception {
|
||||
Path dir1 = Files.createTempDirectory(USER_DIR, "mods1");
|
||||
createModularJar(dir1.resolve("m1.jar"), "m1@1.0");
|
||||
createModularJar(dir1.resolve("m2.jar"), "m2@1.0");
|
||||
|
||||
Path dir2 = Files.createTempDirectory(USER_DIR, "mods2");
|
||||
createModularJar(dir2.resolve("m1.jar"), "m1@2.0");
|
||||
createModularJar(dir2.resolve("m2.jar"), "m2@2.0");
|
||||
createModularJar(dir2.resolve("m3.jar"), "m3");
|
||||
createModularJar(dir2.resolve("m4.jar"), "m4");
|
||||
|
||||
ModuleFinder finder1 = ModuleFinder.of(dir1);
|
||||
ModuleFinder finder2 = ModuleFinder.of(dir2);
|
||||
|
||||
ModuleFinder finder = ModuleFinder.compose(finder1, finder2);
|
||||
assertTrue(finder.findAll().size() == 4);
|
||||
assertTrue(finder.find("m1").isPresent());
|
||||
assertTrue(finder.find("m2").isPresent());
|
||||
assertTrue(finder.find("m3").isPresent());
|
||||
assertTrue(finder.find("m4").isPresent());
|
||||
assertFalse(finder.find("java.rhubarb").isPresent());
|
||||
|
||||
// check that m1@1.0 is found
|
||||
ModuleDescriptor m1 = finder.find("m1").get().descriptor();
|
||||
assertEquals(m1.version().get().toString(), "1.0");
|
||||
|
||||
// check that m2@1.0 is found
|
||||
ModuleDescriptor m2 = finder.find("m2").get().descriptor();
|
||||
assertEquals(m2.version().get().toString(), "1.0");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test ModuleFinder.compose with three module finders
|
||||
*/
|
||||
public void testComposeOfThree() throws Exception {
|
||||
Path dir1 = Files.createTempDirectory(USER_DIR, "mods1");
|
||||
createModularJar(dir1.resolve("m1.jar"), "m1@1.0");
|
||||
createModularJar(dir1.resolve("m2.jar"), "m2@1.0");
|
||||
|
||||
Path dir2 = Files.createTempDirectory(USER_DIR, "mods2");
|
||||
createModularJar(dir2.resolve("m1.jar"), "m1@2.0");
|
||||
createModularJar(dir2.resolve("m2.jar"), "m2@2.0");
|
||||
createModularJar(dir2.resolve("m3.jar"), "m3@2.0");
|
||||
createModularJar(dir2.resolve("m4.jar"), "m4@2.0");
|
||||
|
||||
Path dir3 = Files.createTempDirectory(USER_DIR, "mods3");
|
||||
createModularJar(dir3.resolve("m3.jar"), "m3@3.0");
|
||||
createModularJar(dir3.resolve("m4.jar"), "m4@3.0");
|
||||
createModularJar(dir3.resolve("m5.jar"), "m5");
|
||||
createModularJar(dir3.resolve("m6.jar"), "m6");
|
||||
|
||||
ModuleFinder finder1 = ModuleFinder.of(dir1);
|
||||
ModuleFinder finder2 = ModuleFinder.of(dir2);
|
||||
ModuleFinder finder3 = ModuleFinder.of(dir3);
|
||||
|
||||
ModuleFinder finder = ModuleFinder.compose(finder1, finder2, finder3);
|
||||
assertTrue(finder.findAll().size() == 6);
|
||||
assertTrue(finder.find("m1").isPresent());
|
||||
assertTrue(finder.find("m2").isPresent());
|
||||
assertTrue(finder.find("m3").isPresent());
|
||||
assertTrue(finder.find("m4").isPresent());
|
||||
assertTrue(finder.find("m5").isPresent());
|
||||
assertTrue(finder.find("m6").isPresent());
|
||||
assertFalse(finder.find("java.rhubarb").isPresent());
|
||||
|
||||
// check that m1@1.0 is found
|
||||
ModuleDescriptor m1 = finder.find("m1").get().descriptor();
|
||||
assertEquals(m1.version().get().toString(), "1.0");
|
||||
|
||||
// check that m2@1.0 is found
|
||||
ModuleDescriptor m2 = finder.find("m2").get().descriptor();
|
||||
assertEquals(m2.version().get().toString(), "1.0");
|
||||
|
||||
// check that m3@2.0 is found
|
||||
ModuleDescriptor m3 = finder.find("m3").get().descriptor();
|
||||
assertEquals(m3.version().get().toString(), "2.0");
|
||||
|
||||
// check that m4@2.0 is found
|
||||
ModuleDescriptor m4 = finder.find("m4").get().descriptor();
|
||||
assertEquals(m4.version().get().toString(), "2.0");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test null handling
|
||||
*/
|
||||
public void testNulls() {
|
||||
|
||||
// ofSystem
|
||||
try {
|
||||
ModuleFinder.ofSystem().find(null);
|
||||
assertTrue(false);
|
||||
} catch (NullPointerException expected) { }
|
||||
|
||||
// of
|
||||
Path dir = Paths.get("d");
|
||||
try {
|
||||
ModuleFinder.of().find(null);
|
||||
assertTrue(false);
|
||||
} catch (NullPointerException expected) { }
|
||||
try {
|
||||
ModuleFinder.of((Path)null);
|
||||
assertTrue(false);
|
||||
} catch (NullPointerException expected) { }
|
||||
try {
|
||||
ModuleFinder.of((Path[])null);
|
||||
assertTrue(false);
|
||||
} catch (NullPointerException expected) { }
|
||||
try {
|
||||
ModuleFinder.of(dir, null);
|
||||
assertTrue(false);
|
||||
} catch (NullPointerException expected) { }
|
||||
try {
|
||||
ModuleFinder.of(null, dir);
|
||||
assertTrue(false);
|
||||
} catch (NullPointerException expected) { }
|
||||
|
||||
// compose
|
||||
ModuleFinder finder = ModuleFinder.of();
|
||||
try {
|
||||
ModuleFinder.compose((ModuleFinder)null);
|
||||
assertTrue(false);
|
||||
} catch (NullPointerException expected) { }
|
||||
try {
|
||||
ModuleFinder.compose((ModuleFinder[])null);
|
||||
assertTrue(false);
|
||||
} catch (NullPointerException expected) { }
|
||||
try {
|
||||
ModuleFinder.compose(finder, null);
|
||||
assertTrue(false);
|
||||
} catch (NullPointerException expected) { }
|
||||
try {
|
||||
ModuleFinder.compose(null, finder);
|
||||
assertTrue(false);
|
||||
} catch (NullPointerException expected) { }
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Parses a string of the form {@code name[@version]} and returns a
|
||||
* ModuleDescriptor with that name and version. The ModuleDescriptor
|
||||
* will have a requires on java.base.
|
||||
*/
|
||||
static ModuleDescriptor newModuleDescriptor(String mid) {
|
||||
String mn;
|
||||
String vs;
|
||||
int i = mid.indexOf("@");
|
||||
if (i == -1) {
|
||||
mn = mid;
|
||||
vs = null;
|
||||
} else {
|
||||
mn = mid.substring(0, i);
|
||||
vs = mid.substring(i+1);
|
||||
}
|
||||
ModuleDescriptor.Builder builder
|
||||
= ModuleDescriptor.newModule(mn).requires("java.base");
|
||||
if (vs != null)
|
||||
builder.version(vs);
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an exploded module in the given directory and containing a
|
||||
* module descriptor with the given module name/version.
|
||||
*/
|
||||
static Path createExplodedModule(Path dir, String mid, String... entries)
|
||||
throws Exception
|
||||
{
|
||||
ModuleDescriptor descriptor = newModuleDescriptor(mid);
|
||||
Files.createDirectories(dir);
|
||||
Path mi = dir.resolve("module-info.class");
|
||||
try (OutputStream out = Files.newOutputStream(mi)) {
|
||||
ModuleInfoWriter.write(descriptor, out);
|
||||
}
|
||||
|
||||
for (String entry : entries) {
|
||||
Path file = dir.resolve(entry.replace('/', File.separatorChar));
|
||||
Files.createDirectories(file.getParent());
|
||||
Files.createFile(file);
|
||||
}
|
||||
|
||||
return dir;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a JAR file with the given file path and containing a module
|
||||
* descriptor with the given module name/version.
|
||||
*/
|
||||
static Path createModularJar(Path file, String mid, String ... entries)
|
||||
throws Exception
|
||||
{
|
||||
ModuleDescriptor descriptor = newModuleDescriptor(mid);
|
||||
try (OutputStream out = Files.newOutputStream(file)) {
|
||||
try (JarOutputStream jos = new JarOutputStream(out)) {
|
||||
|
||||
JarEntry je = new JarEntry("module-info.class");
|
||||
jos.putNextEntry(je);
|
||||
ModuleInfoWriter.write(descriptor, jos);
|
||||
jos.closeEntry();
|
||||
|
||||
for (String entry : entries) {
|
||||
je = new JarEntry(entry);
|
||||
jos.putNextEntry(je);
|
||||
jos.closeEntry();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return file;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
264
test/jdk/java/lang/module/ModuleNamesTest.java
Normal file
264
test/jdk/java/lang/module/ModuleNamesTest.java
Normal file
|
|
@ -0,0 +1,264 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @modules java.base/jdk.internal.access
|
||||
* java.base/jdk.internal.module
|
||||
* @library /test/lib
|
||||
* @build jdk.test.lib.util.ModuleInfoWriter
|
||||
* @run testng ModuleNamesTest
|
||||
* @summary Basic test of reading a module-info.class with module names that
|
||||
* are legal in class files but not legal in the Java Language
|
||||
*/
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.lang.module.InvalidModuleDescriptorException;
|
||||
import java.lang.module.ModuleDescriptor;
|
||||
import java.lang.module.ModuleDescriptor.Builder;
|
||||
import java.lang.module.ModuleDescriptor.Exports;
|
||||
import java.lang.module.ModuleDescriptor.Opens;
|
||||
import java.lang.module.ModuleDescriptor.Requires;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
import jdk.internal.access.SharedSecrets;
|
||||
|
||||
import jdk.test.lib.util.ModuleInfoWriter;
|
||||
|
||||
import org.testng.annotations.DataProvider;
|
||||
import org.testng.annotations.Test;
|
||||
import static org.testng.Assert.*;
|
||||
|
||||
@Test
|
||||
public class ModuleNamesTest {
|
||||
|
||||
@DataProvider(name = "legalModuleNames")
|
||||
public Object[][] legalModuleNames() {
|
||||
return new Object[][] {
|
||||
|
||||
{ ".", "." },
|
||||
{ ".foo", ".foo" },
|
||||
{ "foo.", "foo." },
|
||||
{ "foo.bar", "foo.bar" },
|
||||
|
||||
{ "..", ".." },
|
||||
{ "..foo", "..foo" },
|
||||
{ "foo..", "foo.." },
|
||||
{ "foo..bar", "foo..bar" },
|
||||
|
||||
{ "[", "[" },
|
||||
{ "[foo", "[foo" },
|
||||
{ "foo[", "foo[" },
|
||||
{ "foo[bar", "foo[bar" },
|
||||
|
||||
{ ";", ";" },
|
||||
{ ";foo", ";foo" },
|
||||
{ "foo;", "foo;" },
|
||||
{ "foo;bar", "foo;bar" },
|
||||
|
||||
{ "\\\\", "\\" },
|
||||
{ "\\\\foo", "\\foo" },
|
||||
{ "foo\\\\", "foo\\" },
|
||||
{ "foo\\\\bar", "foo\\bar" },
|
||||
|
||||
{ "\\\\\\\\", "\\\\" },
|
||||
{ "\\\\\\\\foo", "\\\\foo" },
|
||||
{ "foo\\\\\\\\", "foo\\\\" },
|
||||
{ "foo\\\\\\\\bar", "foo\\\\bar" },
|
||||
|
||||
{ "\\:", ":" },
|
||||
{ "\\:foo", ":foo" },
|
||||
{ "foo\\:", "foo:" },
|
||||
{ "foo\\:bar", "foo:bar" },
|
||||
|
||||
{ "\\:\\:", "::" },
|
||||
{ "\\:\\:foo", "::foo" },
|
||||
{ "foo\\:\\:", "foo::" },
|
||||
{ "foo\\:\\:bar", "foo::bar" },
|
||||
|
||||
{ "\\@", "@" },
|
||||
{ "\\@foo", "@foo" },
|
||||
{ "foo\\@", "foo@" },
|
||||
{ "foo\\@bar", "foo@bar" },
|
||||
|
||||
{ "\\@\\@", "@@" },
|
||||
{ "\\@\\@foo", "@@foo" },
|
||||
{ "foo\\@\\@", "foo@@" },
|
||||
{ "foo\\@\\@bar", "foo@@bar" },
|
||||
|
||||
{ makeString("", 0x20, ""), " " },
|
||||
{ makeString("foo", 0x20, ""), "foo " },
|
||||
{ makeString("", 0x20, "foo"), " foo" },
|
||||
{ makeString("foo", 0x20, "bar"), "foo bar" },
|
||||
};
|
||||
}
|
||||
|
||||
@DataProvider(name = "illegalModuleNames")
|
||||
public Object[][] illegalModuleNames() {
|
||||
return new Object[][] {
|
||||
|
||||
{ "", null },
|
||||
|
||||
{ ":", null },
|
||||
{ ":foo", null },
|
||||
{ "foo:", null },
|
||||
{ "foo:bar", null },
|
||||
|
||||
{ "@", null },
|
||||
{ "@foo", null },
|
||||
{ "foo@", null },
|
||||
{ "foo@bar", null },
|
||||
|
||||
{ "\\", null },
|
||||
{ "\\foo", null },
|
||||
{ "foo\\", null },
|
||||
{ "foo\\bar", null },
|
||||
|
||||
{ makeString("", 0x00, ""), null },
|
||||
{ makeString("", 0x00, "foo"), null },
|
||||
{ makeString("foo", 0x00, ""), null },
|
||||
{ makeString("foo", 0x00, "bar"), null },
|
||||
|
||||
{ makeString("", 0x1f, ""), null },
|
||||
{ makeString("", 0x1f, "foo"), null },
|
||||
{ makeString("foo", 0x1f, ""), null },
|
||||
{ makeString("foo", 0x1f, "bar"), null },
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
@Test(dataProvider = "legalModuleNames")
|
||||
public void testLegalModuleName(String mn, String expected) throws Exception {
|
||||
ModuleDescriptor md = newBuilder(mn).requires("java.base").build();
|
||||
ByteBuffer bb = toBuffer(md);
|
||||
String name = ModuleDescriptor.read(bb).name();
|
||||
assertEquals(name, expected);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "illegalModuleNames",
|
||||
expectedExceptions = InvalidModuleDescriptorException.class)
|
||||
public void testIllegalModuleName(String mn, String ignore) throws Exception {
|
||||
ModuleDescriptor md = newBuilder(mn).requires("java.base").build();
|
||||
ByteBuffer bb = toBuffer(md);
|
||||
ModuleDescriptor.read(bb); // throws InvalidModuleDescriptorException
|
||||
}
|
||||
|
||||
@Test(dataProvider = "legalModuleNames")
|
||||
public void testLegalRequires(String mn, String expected) throws Exception {
|
||||
ModuleDescriptor md = newBuilder("m").requires("java.base").requires(mn).build();
|
||||
ByteBuffer bb = toBuffer(md);
|
||||
ModuleDescriptor descriptor = ModuleDescriptor.read(bb);
|
||||
Optional<Requires> requires = descriptor.requires().stream()
|
||||
.filter(r -> !r.name().equals("java.base"))
|
||||
.findAny();
|
||||
assertTrue(requires.isPresent());
|
||||
assertEquals(requires.get().name(), expected);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "illegalModuleNames",
|
||||
expectedExceptions = InvalidModuleDescriptorException.class)
|
||||
public void testIllegalRequires(String mn, String ignore) throws Exception {
|
||||
ModuleDescriptor md = newBuilder("m").requires("java.base").requires(mn).build();
|
||||
ByteBuffer bb = toBuffer(md);
|
||||
ModuleDescriptor.read(bb); // throws InvalidModuleDescriptorException
|
||||
}
|
||||
|
||||
@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));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "illegalModuleNames",
|
||||
expectedExceptions = InvalidModuleDescriptorException.class)
|
||||
public void testIllegalExports(String mn, String ignore) throws Exception {
|
||||
ModuleDescriptor md = newBuilder("m")
|
||||
.requires("java.base")
|
||||
.exports("p", Set.of(mn))
|
||||
.build();
|
||||
ByteBuffer bb = toBuffer(md);
|
||||
ModuleDescriptor.read(bb); // throws InvalidModuleDescriptorException
|
||||
}
|
||||
|
||||
@Test(dataProvider = "legalModuleNames")
|
||||
public void testLegalOpens(String mn, String expected) throws Exception {
|
||||
ModuleDescriptor md = newBuilder("m")
|
||||
.requires("java.base")
|
||||
.opens("p", Set.of(mn))
|
||||
.build();
|
||||
ByteBuffer bb = toBuffer(md);
|
||||
ModuleDescriptor descriptor = ModuleDescriptor.read(bb);
|
||||
Optional<Opens> opens = descriptor.opens().stream().findAny();
|
||||
assertTrue(opens.isPresent());
|
||||
assertTrue(opens.get().targets().contains(expected));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "illegalModuleNames",
|
||||
expectedExceptions = InvalidModuleDescriptorException.class)
|
||||
public void testIllegalOpens(String mn, String ignore) throws Exception {
|
||||
ModuleDescriptor md = newBuilder("m")
|
||||
.requires("java.base")
|
||||
.opens("p", Set.of(mn))
|
||||
.build();
|
||||
ByteBuffer bb = toBuffer(md);
|
||||
ModuleDescriptor.read(bb); // throws InvalidModuleDescriptorException
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a Builder that does not validate module names.
|
||||
*/
|
||||
private Builder newBuilder(String mn) {
|
||||
return SharedSecrets.getJavaLangModuleAccess()
|
||||
.newModuleBuilder(mn, false, Set.of());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@code ByteBuffer} containing the given module descriptor
|
||||
* in module-info.class format.
|
||||
*/
|
||||
private ByteBuffer toBuffer(ModuleDescriptor descriptor) throws Exception {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
ModuleInfoWriter.write(descriptor, baos);
|
||||
return ByteBuffer.wrap(baos.toByteArray());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string containing a given code point.
|
||||
*/
|
||||
private String makeString(String prefix, int codePoint, String suffix) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(prefix);
|
||||
sb.appendCodePoint(codePoint);
|
||||
sb.append(suffix);
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
391
test/jdk/java/lang/module/ModuleReader/ModuleReaderTest.java
Normal file
391
test/jdk/java/lang/module/ModuleReader/ModuleReaderTest.java
Normal file
|
|
@ -0,0 +1,391 @@
|
|||
/*
|
||||
* Copyright (c) 2015, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 8142968 8300228
|
||||
* @library /test/lib
|
||||
* @modules java.base/jdk.internal.module
|
||||
* jdk.compiler
|
||||
* jdk.jlink
|
||||
* @build ModuleReaderTest
|
||||
* jdk.test.lib.compiler.CompilerUtils
|
||||
* jdk.test.lib.util.JarUtils
|
||||
* @run junit ModuleReaderTest
|
||||
* @summary Basic tests for java.lang.module.ModuleReader
|
||||
*/
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.lang.module.ModuleFinder;
|
||||
import java.lang.module.ModuleReader;
|
||||
import java.lang.module.ModuleReference;
|
||||
import java.net.URI;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.spi.ToolProvider;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import jdk.internal.module.ModulePath;
|
||||
import jdk.test.lib.compiler.CompilerUtils;
|
||||
import jdk.test.lib.util.JarUtils;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
public class ModuleReaderTest {
|
||||
private static final String TEST_SRC = System.getProperty("test.src");
|
||||
|
||||
private static final Path USER_DIR = Paths.get(System.getProperty("user.dir"));
|
||||
private static final Path SRC_DIR = Paths.get(TEST_SRC, "src");
|
||||
private static final Path MODS_DIR = Paths.get("mods");
|
||||
|
||||
// the module name of the base module
|
||||
private static final String BASE_MODULE = "java.base";
|
||||
|
||||
// the module name of the test module
|
||||
private static final String TEST_MODULE = "m";
|
||||
|
||||
// resources in the base module
|
||||
private static final String[] BASE_RESOURCES = {
|
||||
"java/lang/Object.class"
|
||||
};
|
||||
|
||||
// (directory) resources that may be in the base module
|
||||
private static final String[] MAYBE_BASE_RESOURCES = {
|
||||
"java",
|
||||
"java/",
|
||||
"java/lang",
|
||||
"java/lang/",
|
||||
};
|
||||
|
||||
// resource names that should not be found in the base module
|
||||
private static final String[] NOT_BASE_RESOURCES = {
|
||||
"NotFound",
|
||||
"/java",
|
||||
"//java",
|
||||
"/java/lang",
|
||||
"//java/lang",
|
||||
"java//lang",
|
||||
"/java/lang/Object.class",
|
||||
"//java/lang/Object.class",
|
||||
"java/lang/Object.class/",
|
||||
"java//lang//Object.class",
|
||||
"./java/lang/Object.class",
|
||||
"java/./lang/Object.class",
|
||||
"java/lang/./Object.class",
|
||||
"../java/lang/Object.class",
|
||||
"java/../lang/Object.class",
|
||||
"java/lang/../Object.class",
|
||||
|
||||
// junk resource names
|
||||
"java\u0000",
|
||||
"C:java",
|
||||
"C:\\java",
|
||||
"java\\lang\\Object.class"
|
||||
};
|
||||
|
||||
// resources in test module (can't use module-info.class as a test
|
||||
// resource as it will be modified by the jmod tool)
|
||||
private static final String[] TEST_RESOURCES = {
|
||||
"p/Main.class"
|
||||
};
|
||||
|
||||
// (directory) resources that may be in the test module
|
||||
private static final String[] MAYBE_TEST_RESOURCES = {
|
||||
"p",
|
||||
"p/"
|
||||
};
|
||||
|
||||
// resource names that should not be found in the test module
|
||||
private static final String[] NOT_TEST_RESOURCES = {
|
||||
"NotFound",
|
||||
"/p",
|
||||
"//p",
|
||||
"/p/Main.class",
|
||||
"//p/Main.class",
|
||||
"p/Main.class/",
|
||||
"p//Main.class",
|
||||
"./p/Main.class",
|
||||
"p/./Main.class",
|
||||
"../p/Main.class",
|
||||
"p/../p/Main.class",
|
||||
|
||||
// junk resource names
|
||||
"p\u0000",
|
||||
"C:p",
|
||||
"C:\\p",
|
||||
"p\\Main.class"
|
||||
};
|
||||
|
||||
@BeforeAll
|
||||
public static void compileTestModule() throws Exception {
|
||||
// javac -d mods/$TESTMODULE src/$TESTMODULE/**
|
||||
boolean compiled = CompilerUtils.compile(SRC_DIR.resolve(TEST_MODULE),
|
||||
MODS_DIR.resolve(TEST_MODULE));
|
||||
assertTrue(compiled, "test module did not compile");
|
||||
}
|
||||
|
||||
/**
|
||||
* Test ModuleReader with module in runtime image.
|
||||
*/
|
||||
@Test
|
||||
public void testImage() throws IOException {
|
||||
ModuleFinder finder = ModuleFinder.ofSystem();
|
||||
ModuleReference mref = finder.find(BASE_MODULE).get();
|
||||
ModuleReader reader = mref.open();
|
||||
|
||||
try (reader) {
|
||||
|
||||
for (String name : BASE_RESOURCES) {
|
||||
byte[] expectedBytes;
|
||||
Module baseModule = Object.class.getModule();
|
||||
try (InputStream in = baseModule.getResourceAsStream(name)) {
|
||||
expectedBytes = in.readAllBytes();
|
||||
}
|
||||
|
||||
testFind(reader, name, expectedBytes);
|
||||
testOpen(reader, name, expectedBytes);
|
||||
testRead(reader, name, expectedBytes);
|
||||
testList(reader, name);
|
||||
}
|
||||
|
||||
// test resources that may be in the base module
|
||||
for (String name : MAYBE_BASE_RESOURCES) {
|
||||
Optional<URI> ouri = reader.find(name);
|
||||
ouri.ifPresent(uri -> {
|
||||
if (name.endsWith("/"))
|
||||
assertTrue(uri.toString().endsWith("/"),
|
||||
"mismatched directory URI for '" + name + "': " + uri);
|
||||
});
|
||||
}
|
||||
|
||||
// test "not found" in java.base module
|
||||
for (String name : NOT_BASE_RESOURCES) {
|
||||
assertFalse(reader.find(name).isPresent(), "Unexpected resource found: " + name);
|
||||
assertFalse(reader.open(name).isPresent(), "Unexpected resource opened: " + name);
|
||||
assertFalse(reader.read(name).isPresent(), "Unexpected resource read: " + name);
|
||||
}
|
||||
|
||||
// test nulls
|
||||
assertThrows(NullPointerException.class, () -> reader.find(null));
|
||||
assertThrows(NullPointerException.class, () -> reader.open(null));
|
||||
assertThrows(NullPointerException.class, () -> reader.read(null));
|
||||
assertThrows(NullPointerException.class, () -> reader.release(null));
|
||||
}
|
||||
|
||||
// test closed ModuleReader
|
||||
assertThrows(IOException.class, () -> reader.open(BASE_RESOURCES[0]));
|
||||
assertThrows(IOException.class, () -> reader.read(BASE_RESOURCES[0]));
|
||||
assertThrows(IOException.class, reader::list);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test ModuleReader with exploded module.
|
||||
*/
|
||||
@Test
|
||||
public void testExplodedModule() throws IOException {
|
||||
test(MODS_DIR);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test ModuleReader with module in modular JAR.
|
||||
*/
|
||||
@Test
|
||||
public void testModularJar() throws IOException {
|
||||
Path dir = Files.createTempDirectory(USER_DIR, "mlib");
|
||||
|
||||
// jar cf mlib/${TESTMODULE}.jar -C mods .
|
||||
JarUtils.createJarFile(dir.resolve("m.jar"),
|
||||
MODS_DIR.resolve(TEST_MODULE));
|
||||
|
||||
test(dir);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test ModuleReader with module in a JMOD file.
|
||||
*/
|
||||
@Test
|
||||
public void testJMod() throws IOException {
|
||||
Path dir = Files.createTempDirectory(USER_DIR, "mlib");
|
||||
|
||||
// jmod create --class-path mods/${TESTMODULE} mlib/${TESTMODULE}.jmod
|
||||
String cp = MODS_DIR.resolve(TEST_MODULE).toString();
|
||||
String jmod = dir.resolve("m.jmod").toString();
|
||||
String[] args = { "create", "--class-path", cp, jmod };
|
||||
ToolProvider jmodTool = ToolProvider.findFirst("jmod")
|
||||
.orElseThrow(() ->
|
||||
new RuntimeException("jmod tool not found")
|
||||
);
|
||||
assertEquals(0, jmodTool.run(System.out, System.out, args), "jmod tool failed");
|
||||
|
||||
test(dir);
|
||||
}
|
||||
|
||||
/**
|
||||
* The test module is found on the given module path. Open a ModuleReader
|
||||
* to the test module and test the reader.
|
||||
*/
|
||||
void test(Path mp) throws IOException {
|
||||
ModuleFinder finder = ModulePath.of(Runtime.version(), true, mp);
|
||||
ModuleReference mref = finder.find(TEST_MODULE).get();
|
||||
ModuleReader reader = mref.open();
|
||||
|
||||
try (reader) {
|
||||
|
||||
// test resources in test module
|
||||
for (String name : TEST_RESOURCES) {
|
||||
System.out.println("resource: " + name);
|
||||
byte[] expectedBytes
|
||||
= Files.readAllBytes(MODS_DIR
|
||||
.resolve(TEST_MODULE)
|
||||
.resolve(name.replace('/', File.separatorChar)));
|
||||
|
||||
testFind(reader, name, expectedBytes);
|
||||
testOpen(reader, name, expectedBytes);
|
||||
testRead(reader, name, expectedBytes);
|
||||
testList(reader, name);
|
||||
}
|
||||
|
||||
// test resources that may be in the test module
|
||||
for (String name : MAYBE_TEST_RESOURCES) {
|
||||
System.out.println("resource: " + name);
|
||||
Optional<URI> ouri = reader.find(name);
|
||||
ouri.ifPresent(uri -> {
|
||||
if (name.endsWith("/"))
|
||||
assertTrue(uri.toString().endsWith("/"),
|
||||
"mismatched directory URI for '" + name + "': " + uri);
|
||||
});
|
||||
}
|
||||
|
||||
// test "not found" in test module
|
||||
for (String name : NOT_TEST_RESOURCES) {
|
||||
System.out.println("resource: " + name);
|
||||
assertFalse(reader.find(name).isPresent(), "Unexpected resource found: " + name);
|
||||
assertFalse(reader.open(name).isPresent(), "Unexpected resource open: " + name);
|
||||
assertFalse(reader.read(name).isPresent(), "Unexpected resource read: " + name);
|
||||
}
|
||||
|
||||
// test nulls
|
||||
assertThrows(NullPointerException.class, () -> reader.find(null));
|
||||
assertThrows(NullPointerException.class, () -> reader.open(null));
|
||||
assertThrows(NullPointerException.class, () -> reader.read(null));
|
||||
assertThrows(NullPointerException.class, () -> reader.release(null));
|
||||
}
|
||||
|
||||
// test closed ModuleReader
|
||||
assertThrows(IOException.class, () -> reader.open(BASE_RESOURCES[0]));
|
||||
assertThrows(IOException.class, () -> reader.read(BASE_RESOURCES[0]));
|
||||
assertThrows(IOException.class, reader::list);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test ModuleReader#find
|
||||
*/
|
||||
void testFind(ModuleReader reader, String name, byte[] expectedBytes)
|
||||
throws IOException
|
||||
{
|
||||
Optional<URI> ouri = reader.find(name);
|
||||
assertTrue(ouri.isPresent(), "missing URI for: " + name);
|
||||
|
||||
URL url = ouri.get().toURL();
|
||||
if (!url.getProtocol().equalsIgnoreCase("jmod")) {
|
||||
URLConnection uc = url.openConnection();
|
||||
uc.setUseCaches(false);
|
||||
try (InputStream in = uc.getInputStream()) {
|
||||
byte[] bytes = in.readAllBytes();
|
||||
assertArrayEquals(expectedBytes, bytes, "resource bytes differ for: " + name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test ModuleReader#open
|
||||
*/
|
||||
void testOpen(ModuleReader reader, String name, byte[] expectedBytes)
|
||||
throws IOException
|
||||
{
|
||||
Optional<InputStream> oin = reader.open(name);
|
||||
assertTrue(oin.isPresent(), "missing input stream for: " + name);
|
||||
try (InputStream in = oin.get()) {
|
||||
byte[] bytes = in.readAllBytes();
|
||||
assertArrayEquals(expectedBytes, bytes, "resource bytes differ for: " + name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test ModuleReader#read
|
||||
*/
|
||||
void testRead(ModuleReader reader, String name, byte[] expectedBytes)
|
||||
throws IOException
|
||||
{
|
||||
Optional<ByteBuffer> obb = reader.read(name);
|
||||
assertTrue(obb.isPresent());
|
||||
|
||||
ByteBuffer bb = obb.get();
|
||||
try {
|
||||
int rem = bb.remaining();
|
||||
assertEquals(expectedBytes.length, rem, "resource lengths differ: " + name);
|
||||
byte[] bytes = new byte[rem];
|
||||
bb.get(bytes);
|
||||
assertArrayEquals(expectedBytes, bytes, "resource bytes differ: " + name);
|
||||
} finally {
|
||||
reader.release(bb);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test ModuleReader#list
|
||||
*/
|
||||
void testList(ModuleReader reader, String name) throws IOException {
|
||||
final List<String> list;
|
||||
try (Stream<String> stream = reader.list()) {
|
||||
list = stream.toList();
|
||||
}
|
||||
Set<String> names = new HashSet<>(list);
|
||||
assertEquals(names.size(), list.size(), "resource list contains duplicates: " + list);
|
||||
|
||||
assertTrue(names.contains("module-info.class"), "resource list did not contain 'module-info.class': " + list);
|
||||
assertTrue(names.contains(name), "resource list did not contain '" + name + "'" + list);
|
||||
|
||||
// all resources should be locatable via find
|
||||
for (String e : names) {
|
||||
assertTrue(reader.find(e).isPresent(), "resource not found: " + name);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,132 @@
|
|||
/*
|
||||
* Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.module.ModuleFinder;
|
||||
import java.lang.module.ModuleReader;
|
||||
import java.lang.module.ModuleReference;
|
||||
import java.net.URI;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8372787
|
||||
* @summary Test the behaviour of ModuleReader when using --patch-module
|
||||
* @comment patch the java.base module with a test specific resource
|
||||
* @compile/module=java.base java/lang/PatchedFoo.java
|
||||
* @run junit/othervm ${test.main.class}
|
||||
*/
|
||||
class PatchedModuleReaderTest {
|
||||
|
||||
private static ModuleReference patchedModuleRef;
|
||||
|
||||
@BeforeAll
|
||||
static void beforeAll() {
|
||||
patchedModuleRef = ModuleFinder.ofSystem()
|
||||
.find("java.base")
|
||||
.orElseThrow();
|
||||
}
|
||||
|
||||
/*
|
||||
* Verifies that the resource that was patched into a module
|
||||
* is found by the ModuleReader.
|
||||
*/
|
||||
@Test
|
||||
void testResourceFound() throws Exception {
|
||||
try (ModuleReader reader = patchedModuleRef.open()) {
|
||||
String resourceName = "java/lang/PatchedFoo.class";
|
||||
Optional<URI> res = reader.find(resourceName);
|
||||
assertTrue(res.isPresent(), resourceName + " is missing in "
|
||||
+ patchedModuleRef.descriptor().name() + " module");
|
||||
URI uri = res.get();
|
||||
assertEquals("file", uri.getScheme(),
|
||||
"unexpected scheme in resource URI " + uri);
|
||||
assertTrue(uri.getPath().endsWith(resourceName),
|
||||
"unexpected path component " + uri.getPath()
|
||||
+ " in resource URI " + uri);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Verifies the ModuleReader against a resource which isn't
|
||||
* expected to be part of the patched module.
|
||||
*/
|
||||
@Test
|
||||
void testResourceNotFound() throws Exception {
|
||||
try (ModuleReader reader = patchedModuleRef.open()) {
|
||||
String nonExistentResource = "foo/bar/NonExistent.class";
|
||||
Optional<URI> res = reader.find(nonExistentResource);
|
||||
assertTrue(res.isEmpty(), "unexpected resource " + nonExistentResource
|
||||
+ " in " + patchedModuleRef.descriptor().name() + " module");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This test opens a ModuleReader for a patched module, accumulates
|
||||
* the Stream of resources from that ModuleReader and then closes that
|
||||
* ModuleReader. It then verifies that the closed ModuleReader
|
||||
* throws the specified IOException whenever it is used for subsequent
|
||||
* operations on the Stream of resources.
|
||||
*/
|
||||
@Test
|
||||
void testIOExceptionAfterClose() throws Exception {
|
||||
ModuleReader reader;
|
||||
Stream<String> resources;
|
||||
try (var _ = reader = patchedModuleRef.open()) {
|
||||
// hold on to the available resources, to test them after the
|
||||
// ModuleReader is closed
|
||||
resources = reader.list();
|
||||
} // close the ModuleReader
|
||||
|
||||
// verify IOException is thrown by the closed ModuleReader
|
||||
|
||||
assertThrows(IOException.class, () -> reader.list(),
|
||||
"ModuleReader.list()");
|
||||
|
||||
resources.forEach(rn -> {
|
||||
assertThrows(IOException.class, () -> reader.read(rn),
|
||||
"ModuleReader.read(String)");
|
||||
assertThrows(IOException.class, () -> reader.open(rn),
|
||||
"ModuleReader.open(String)");
|
||||
assertThrows(IOException.class, () -> reader.find(rn),
|
||||
"ModuleReader.find(String)");
|
||||
});
|
||||
|
||||
// repeat the test for a non-existent resource
|
||||
String nonExistentResource = "foo/bar/NonExistent.class";
|
||||
assertThrows(IOException.class, () -> reader.read(nonExistentResource),
|
||||
"ModuleReader.read(String)");
|
||||
assertThrows(IOException.class, () -> reader.open(nonExistentResource),
|
||||
"ModuleReader.open(String)");
|
||||
assertThrows(IOException.class, () -> reader.find(nonExistentResource),
|
||||
"ModuleReader.find(String)");
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package java.lang;
|
||||
|
||||
public class PatchedFoo {
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
module m {
|
||||
}
|
||||
33
test/jdk/java/lang/module/ModuleReader/src/m/p/Main.java
Normal file
33
test/jdk/java/lang/module/ModuleReader/src/m/p/Main.java
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package p;
|
||||
|
||||
/**
|
||||
* Main class for dummy module.
|
||||
*/
|
||||
|
||||
public class Main {
|
||||
public static void main(String[] args) {
|
||||
}
|
||||
}
|
||||
82
test/jdk/java/lang/module/ModuleReferenceTest.java
Normal file
82
test/jdk/java/lang/module/ModuleReferenceTest.java
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
* Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @run testng ModuleReferenceTest
|
||||
* @summary Basic tests for java.lang.module.ModuleReference
|
||||
*/
|
||||
|
||||
import java.lang.module.ModuleDescriptor;
|
||||
import java.lang.module.ModuleReader;
|
||||
import java.lang.module.ModuleReference;
|
||||
import java.net.URI;
|
||||
import java.util.Set;
|
||||
|
||||
import org.testng.annotations.Test;
|
||||
import static org.testng.Assert.*;
|
||||
|
||||
@Test
|
||||
public class ModuleReferenceTest {
|
||||
|
||||
private ModuleReference newModuleReference(ModuleDescriptor descriptor, URI uri) {
|
||||
return new ModuleReference(descriptor, uri) {
|
||||
@Override
|
||||
public ModuleReader open() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public void testBasic() throws Exception {
|
||||
ModuleDescriptor descriptor
|
||||
= ModuleDescriptor.newModule("m")
|
||||
.exports("p")
|
||||
.exports("q")
|
||||
.packages(Set.of("p.internal"))
|
||||
.build();
|
||||
|
||||
URI uri = URI.create("module:/m");
|
||||
|
||||
ModuleReference mref = newModuleReference(descriptor, uri);
|
||||
|
||||
assertTrue(mref.descriptor().equals(descriptor));
|
||||
assertTrue(mref.location().get().equals(uri));
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = { NullPointerException.class })
|
||||
public void testNullDescriptor() throws Exception {
|
||||
URI location = URI.create("module:/m");
|
||||
newModuleReference(null, location);
|
||||
}
|
||||
|
||||
public void testNullLocation() {
|
||||
ModuleDescriptor descriptor
|
||||
= ModuleDescriptor.newModule("m")
|
||||
.exports("p")
|
||||
.build();
|
||||
ModuleReference mref = newModuleReference(descriptor, null);
|
||||
assertTrue(!mref.location().isPresent());
|
||||
}
|
||||
|
||||
}
|
||||
339
test/jdk/java/lang/module/MultiReleaseJarTest.java
Normal file
339
test/jdk/java/lang/module/MultiReleaseJarTest.java
Normal file
|
|
@ -0,0 +1,339 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @modules java.base/jdk.internal.module
|
||||
* @library /test/lib
|
||||
* @build MultiReleaseJarTest
|
||||
* jdk.test.lib.util.JarUtils
|
||||
* jdk.test.lib.util.ModuleInfoWriter
|
||||
* @run testng MultiReleaseJarTest
|
||||
* @run testng/othervm -Djdk.util.jar.enableMultiRelease=false MultiReleaseJarTest
|
||||
* @summary Basic test of modular JARs as multi-release JARs
|
||||
*/
|
||||
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.lang.module.ModuleDescriptor;
|
||||
import java.lang.module.ModuleFinder;
|
||||
import java.lang.module.ModuleReader;
|
||||
import java.lang.module.ModuleReference;
|
||||
import java.net.URI;
|
||||
import java.net.URLConnection;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.jar.Attributes;
|
||||
import java.util.jar.Manifest;
|
||||
|
||||
import jdk.test.lib.util.ModuleInfoWriter;
|
||||
import jdk.test.lib.util.JarUtils;
|
||||
|
||||
import org.testng.annotations.Test;
|
||||
import static org.testng.Assert.*;
|
||||
|
||||
|
||||
@Test
|
||||
public class MultiReleaseJarTest {
|
||||
|
||||
private static final String MODULE_INFO = "module-info.class";
|
||||
|
||||
private static final int VERSION = Runtime.version().major();
|
||||
|
||||
// are multi-release JARs enabled?
|
||||
private static final boolean MULTI_RELEASE;
|
||||
static {
|
||||
String s = System.getProperty("jdk.util.jar.enableMultiRelease");
|
||||
MULTI_RELEASE = (s == null || Boolean.parseBoolean(s));
|
||||
}
|
||||
|
||||
/**
|
||||
* Basic test of a multi-release JAR.
|
||||
*/
|
||||
public void testBasic() throws Exception {
|
||||
String name = "m1";
|
||||
|
||||
ModuleDescriptor descriptor = ModuleDescriptor.newModule(name)
|
||||
.requires("java.base")
|
||||
.build();
|
||||
|
||||
Path jar = new JarBuilder(name)
|
||||
.moduleInfo("module-info.class", descriptor)
|
||||
.resource("p/Main.class")
|
||||
.resource("p/Helper.class")
|
||||
.resource("META-INF/versions/" + VERSION + "/p/Helper.class")
|
||||
.resource("META-INF/versions/" + VERSION + "/p/internal/Helper.class")
|
||||
.build();
|
||||
|
||||
// find the module
|
||||
ModuleFinder finder = ModuleFinder.of(jar);
|
||||
Optional<ModuleReference> omref = finder.find(name);
|
||||
assertTrue((omref.isPresent()));
|
||||
ModuleReference mref = omref.get();
|
||||
|
||||
// check module packages
|
||||
descriptor = mref.descriptor();
|
||||
Set<String> packages = descriptor.packages();
|
||||
assertTrue(packages.contains("p"));
|
||||
if (MULTI_RELEASE) {
|
||||
assertTrue(packages.size() == 2);
|
||||
assertTrue(packages.contains("p.internal"));
|
||||
} else {
|
||||
assertTrue(packages.size() == 1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test a multi-release JAR with a module-info.class in the versioned
|
||||
* section of the JAR.
|
||||
*/
|
||||
public void testModuleInfoInVersionedSection() throws Exception {
|
||||
String name = "m1";
|
||||
|
||||
ModuleDescriptor descriptor1 = ModuleDescriptor.newModule(name)
|
||||
.requires("java.base")
|
||||
.build();
|
||||
|
||||
// module descriptor for versioned section
|
||||
ModuleDescriptor descriptor2 = ModuleDescriptor.newModule(name)
|
||||
.requires("java.base")
|
||||
.requires("jdk.unsupported")
|
||||
.build();
|
||||
|
||||
Path jar = new JarBuilder(name)
|
||||
.moduleInfo(MODULE_INFO, descriptor1)
|
||||
.resource("p/Main.class")
|
||||
.resource("p/Helper.class")
|
||||
.moduleInfo("META-INF/versions/" + VERSION + "/" + MODULE_INFO, descriptor2)
|
||||
.resource("META-INF/versions/" + VERSION + "/p/Helper.class")
|
||||
.resource("META-INF/versions/" + VERSION + "/p/internal/Helper.class")
|
||||
.build();
|
||||
|
||||
// find the module
|
||||
ModuleFinder finder = ModuleFinder.of(jar);
|
||||
Optional<ModuleReference> omref = finder.find(name);
|
||||
assertTrue((omref.isPresent()));
|
||||
ModuleReference mref = omref.get();
|
||||
|
||||
// ensure that the right module-info.class is loaded
|
||||
ModuleDescriptor descriptor = mref.descriptor();
|
||||
assertEquals(descriptor.name(), name);
|
||||
if (MULTI_RELEASE) {
|
||||
assertEquals(descriptor.requires(), descriptor2.requires());
|
||||
} else {
|
||||
assertEquals(descriptor.requires(), descriptor1.requires());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test multi-release JAR as an automatic module.
|
||||
*/
|
||||
public void testAutomaticModule() throws Exception {
|
||||
String name = "m";
|
||||
|
||||
Path jar = new JarBuilder(name)
|
||||
.resource("p/Main.class")
|
||||
.resource("p/Helper.class")
|
||||
.resource("META-INF/versions/" + VERSION + "/p/Helper.class")
|
||||
.resource("META-INF/versions/" + VERSION + "/p/internal/Helper.class")
|
||||
.build();
|
||||
|
||||
// find the module
|
||||
ModuleFinder finder = ModuleFinder.of(jar);
|
||||
Optional<ModuleReference> omref = finder.find(name);
|
||||
assertTrue((omref.isPresent()));
|
||||
ModuleReference mref = omref.get();
|
||||
|
||||
// check module packages
|
||||
ModuleDescriptor descriptor = mref.descriptor();
|
||||
Set<String> packages = descriptor.packages();
|
||||
if (MULTI_RELEASE) {
|
||||
assertTrue(packages.size() == 2);
|
||||
assertTrue(packages.contains("p.internal"));
|
||||
} else {
|
||||
assertTrue(packages.size() == 1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Exercise ModuleReader on a multi-release JAR
|
||||
*/
|
||||
public void testModuleReader() throws Exception {
|
||||
String name = "m1";
|
||||
|
||||
ModuleDescriptor descriptor1 = ModuleDescriptor.newModule(name)
|
||||
.requires("java.base")
|
||||
.build();
|
||||
|
||||
// module descriptor for versioned section
|
||||
ModuleDescriptor descriptor2 = ModuleDescriptor.newModule(name)
|
||||
.requires("java.base")
|
||||
.requires("jdk.unsupported")
|
||||
.build();
|
||||
|
||||
Path jar = new JarBuilder(name)
|
||||
.moduleInfo(MODULE_INFO, descriptor1)
|
||||
.moduleInfo("META-INF/versions/" + VERSION + "/" + MODULE_INFO, descriptor2)
|
||||
.build();
|
||||
|
||||
// find the module
|
||||
ModuleFinder finder = ModuleFinder.of(jar);
|
||||
Optional<ModuleReference> omref = finder.find(name);
|
||||
assertTrue((omref.isPresent()));
|
||||
ModuleReference mref = omref.get();
|
||||
|
||||
ModuleDescriptor expected;
|
||||
if (MULTI_RELEASE) {
|
||||
expected = descriptor2;
|
||||
} else {
|
||||
expected = descriptor1;
|
||||
}
|
||||
|
||||
// test ModuleReader by reading module-info.class resource
|
||||
try (ModuleReader reader = mref.open()) {
|
||||
|
||||
// open resource
|
||||
Optional<InputStream> oin = reader.open(MODULE_INFO);
|
||||
assertTrue(oin.isPresent());
|
||||
try (InputStream in = oin.get()) {
|
||||
checkRequires(ModuleDescriptor.read(in), expected);
|
||||
}
|
||||
|
||||
// read resource
|
||||
Optional<ByteBuffer> obb = reader.read(MODULE_INFO);
|
||||
assertTrue(obb.isPresent());
|
||||
ByteBuffer bb = obb.get();
|
||||
try {
|
||||
checkRequires(ModuleDescriptor.read(bb), expected);
|
||||
} finally {
|
||||
reader.release(bb);
|
||||
}
|
||||
|
||||
// find resource
|
||||
Optional<URI> ouri = reader.find(MODULE_INFO);
|
||||
assertTrue(ouri.isPresent());
|
||||
URI uri = ouri.get();
|
||||
|
||||
String expectedTail = "!/";
|
||||
if (MULTI_RELEASE)
|
||||
expectedTail += "META-INF/versions/" + VERSION + "/";
|
||||
expectedTail += MODULE_INFO;
|
||||
assertTrue(uri.toString().endsWith(expectedTail));
|
||||
|
||||
URLConnection uc = uri.toURL().openConnection();
|
||||
uc.setUseCaches(false);
|
||||
try (InputStream in = uc.getInputStream()) {
|
||||
checkRequires(ModuleDescriptor.read(in), expected);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that two ModuleDescriptor have the same requires
|
||||
*/
|
||||
static void checkRequires(ModuleDescriptor md1, ModuleDescriptor md2) {
|
||||
assertEquals(md1.requires(), md2.requires());
|
||||
}
|
||||
|
||||
/**
|
||||
* A builder of multi-release JAR files.
|
||||
*/
|
||||
static class JarBuilder {
|
||||
private String name;
|
||||
private Set<String> resources = new HashSet<>();
|
||||
private Map<String, ModuleDescriptor> descriptors = new HashMap<>();
|
||||
|
||||
JarBuilder(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a module-info.class to the JAR file.
|
||||
*/
|
||||
JarBuilder moduleInfo(String name, ModuleDescriptor descriptor) {
|
||||
descriptors.put(name, descriptor);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a dummy resource to the JAR file.
|
||||
*/
|
||||
JarBuilder resource(String name) {
|
||||
resources.add(name);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the multi-release JAR, returning its file path.
|
||||
*/
|
||||
Path build() throws Exception {
|
||||
Path dir = Files.createTempDirectory(Paths.get(""), "jar");
|
||||
List<Path> files = new ArrayList<>();
|
||||
|
||||
// write the module-info.class
|
||||
for (Map.Entry<String, ModuleDescriptor> e : descriptors.entrySet()) {
|
||||
String name = e.getKey();
|
||||
ModuleDescriptor descriptor = e.getValue();
|
||||
Path mi = Paths.get(name.replace('/', File.separatorChar));
|
||||
Path parent = dir.resolve(mi).getParent();
|
||||
if (parent != null)
|
||||
Files.createDirectories(parent);
|
||||
try (OutputStream out = Files.newOutputStream(dir.resolve(mi))) {
|
||||
ModuleInfoWriter.write(descriptor, out);
|
||||
}
|
||||
files.add(mi);
|
||||
}
|
||||
|
||||
// write the dummy resources
|
||||
for (String name : resources) {
|
||||
Path file = Paths.get(name.replace('/', File.separatorChar));
|
||||
// create dummy resource
|
||||
Path parent = dir.resolve(file).getParent();
|
||||
if (parent != null)
|
||||
Files.createDirectories(parent);
|
||||
Files.createFile(dir.resolve(file));
|
||||
files.add(file);
|
||||
}
|
||||
|
||||
Manifest man = new Manifest();
|
||||
Attributes attrs = man.getMainAttributes();
|
||||
attrs.put(Attributes.Name.MANIFEST_VERSION, "1.0");
|
||||
attrs.put(Attributes.Name.MULTI_RELEASE, "true");
|
||||
|
||||
Path jarfile = Paths.get(name + ".jar");
|
||||
JarUtils.createJarFile(jarfile, man, dir, files.toArray(new Path[0]));
|
||||
return jarfile;
|
||||
}
|
||||
}
|
||||
}
|
||||
58
test/jdk/java/lang/module/Packages/GetPackagesTest.java
Normal file
58
test/jdk/java/lang/module/Packages/GetPackagesTest.java
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @library /test/lib
|
||||
* @build m/*
|
||||
* @run main/othervm --add-modules m test.GetPackagesTest
|
||||
* @summary test the packages returned by Module::getPackages for an unnamed
|
||||
* module does not include the packages for named modules
|
||||
*/
|
||||
|
||||
package test;
|
||||
|
||||
import java.util.Set;
|
||||
import static jdk.test.lib.Asserts.*;
|
||||
|
||||
public class GetPackagesTest {
|
||||
public static void main(String... args) throws Exception {
|
||||
// module m contains the package "p"
|
||||
Class<?> c = Class.forName("p.Main");
|
||||
Module m = c.getModule();
|
||||
Module test = GetPackagesTest.class.getModule();
|
||||
|
||||
// module m and unnamed module are defined by the same class loader
|
||||
assertTrue(m.isNamed());
|
||||
assertFalse(test.isNamed());
|
||||
assertTrue(m.getClassLoader() == test.getClassLoader());
|
||||
|
||||
// verify Module::getPackages on an unnamed module only contains
|
||||
// the packages defined to the unnamed module
|
||||
assertEquals(m.getPackages(), Set.of("p"));
|
||||
|
||||
Set<String> pkgs = test.getPackages();
|
||||
assertTrue(pkgs.contains("test"));
|
||||
assertFalse(pkgs.contains("p"));
|
||||
}
|
||||
}
|
||||
26
test/jdk/java/lang/module/Packages/m/module-info.java
Normal file
26
test/jdk/java/lang/module/Packages/m/module-info.java
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
module m {
|
||||
exports p;
|
||||
}
|
||||
33
test/jdk/java/lang/module/Packages/m/p/Main.java
Normal file
33
test/jdk/java/lang/module/Packages/m/p/Main.java
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package p;
|
||||
|
||||
/**
|
||||
* Main class for dummy module.
|
||||
*/
|
||||
|
||||
public class Main {
|
||||
public static void main(String[] args) {
|
||||
}
|
||||
}
|
||||
177
test/jdk/java/lang/module/VersionTest.java
Normal file
177
test/jdk/java/lang/module/VersionTest.java
Normal file
|
|
@ -0,0 +1,177 @@
|
|||
/*
|
||||
* Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @run testng VersionTest
|
||||
* @summary Basic tests for java.lang.module.ModuleDescriptor.Version.
|
||||
*/
|
||||
|
||||
import java.lang.module.ModuleDescriptor.Version;
|
||||
|
||||
import org.testng.annotations.Test;
|
||||
import org.testng.annotations.DataProvider;
|
||||
import static org.testng.Assert.*;
|
||||
|
||||
@Test
|
||||
public class VersionTest {
|
||||
|
||||
// valid version strings
|
||||
@DataProvider(name = "validVersions")
|
||||
public Object[][] validVersions() {
|
||||
return new Object[][]{
|
||||
|
||||
{ "1.0", null },
|
||||
{ "1.0.0", null },
|
||||
{ "1.0.0.0", null },
|
||||
|
||||
{ "99", null },
|
||||
{ "99.99", null },
|
||||
{ "99.99.99", null },
|
||||
|
||||
{ "1-SNAPSHOT", null },
|
||||
{ "1.0-SNAPSHOT", null },
|
||||
{ "1.0.0-SNAPSHOT", null },
|
||||
|
||||
{ "9-ea", null },
|
||||
{ "9-ea+110", null },
|
||||
{ "9.3.2.1+42-8839942", null}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
// invalid version strings
|
||||
@DataProvider(name = "invalidVersions")
|
||||
public Object[][] invalidVersions() {
|
||||
return new Object[][]{
|
||||
|
||||
{ null, null },
|
||||
{ "", null },
|
||||
{ "A1", null }, // does not start with number
|
||||
{ "1.0-", null }, // empty branch
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
// Test parsing valid version strings
|
||||
@Test(dataProvider = "validVersions")
|
||||
public void testParseValidVersions(String vs, String ignore) {
|
||||
Version v = Version.parse(vs);
|
||||
assertEquals(v.toString(), vs);
|
||||
}
|
||||
|
||||
// Test parsing an invalid version strings
|
||||
@Test(dataProvider = "invalidVersions",
|
||||
expectedExceptions = IllegalArgumentException.class )
|
||||
public void testParseInvalidVersions(String vs, String ignore) {
|
||||
Version.parse(vs);
|
||||
}
|
||||
|
||||
// Test equals and hashCode
|
||||
@Test(dataProvider = "validVersions")
|
||||
public void testEqualsAndHashCode(String vs, String ignore) {
|
||||
|
||||
Version v1 = Version.parse(vs);
|
||||
Version v2 = Version.parse(vs);
|
||||
assertEquals(v1, v2);
|
||||
assertEquals(v2, v1);
|
||||
assertEquals(v1.hashCode(), v2.hashCode());
|
||||
|
||||
Version v3 = Version.parse("1.0-rhubarb");
|
||||
assertNotEquals(v1, v3);
|
||||
assertNotEquals(v2, v3);
|
||||
assertNotEquals(v3, v1);
|
||||
assertNotEquals(v3, v2);
|
||||
|
||||
}
|
||||
|
||||
// ordered version strings
|
||||
@DataProvider(name = "orderedVersions")
|
||||
public Object[][] orderedVersions() {
|
||||
return new Object[][]{
|
||||
|
||||
{ "1.0", "2.0" },
|
||||
{ "1.0-SNAPSHOT", "1.0" },
|
||||
{ "1.0-SNAPSHOT2", "1.0" },
|
||||
{ "1.2.3-ea", "1.2.3" },
|
||||
{ "1.2.3-ea+104", "1.2.3-ea+105" },
|
||||
{ "1.2.3-ea+104-4084552", "1.2.3-ea+104-4084552+8849330" },
|
||||
{ "1+104", "1+105" },
|
||||
{ "1.0-alpha1", "1.0-alpha2" }
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Test compareTo with ordered versions.
|
||||
*/
|
||||
@Test(dataProvider = "orderedVersions")
|
||||
public void testCompareOrderedVersions(String vs1, String vs2) {
|
||||
|
||||
Version v1 = Version.parse(vs1);
|
||||
assertTrue(v1.compareTo(v1) == 0);
|
||||
|
||||
Version v2 = Version.parse(vs2);
|
||||
assertTrue(v2.compareTo(v2) == 0);
|
||||
|
||||
// v1 < v2
|
||||
assertTrue(v1.compareTo(v2) < 0);
|
||||
assertTrue(v2.compareTo(v1) > 0);
|
||||
|
||||
}
|
||||
|
||||
// equal version strings
|
||||
@DataProvider(name = "equalVersions")
|
||||
public Object[][] equalVersions() {
|
||||
return new Object[][]{
|
||||
|
||||
{ "1", "1.0.0" },
|
||||
{ "1.0", "1.0.0" },
|
||||
{ "1.0-beta", "1.0.0-beta" },
|
||||
{ "1.0-1.1", "1.0-1..1" },
|
||||
{ "1.0-1+1", "1.0-1.+1" },
|
||||
{ "1.0-1+1.1", "1.0-1+1..1" },
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Test compareTo with equal versions.
|
||||
*/
|
||||
@Test(dataProvider = "equalVersions")
|
||||
public void testCompareEqualsVersions(String vs1, String vs2) {
|
||||
|
||||
Version v1 = Version.parse(vs1);
|
||||
assertTrue(v1.compareTo(v1) == 0);
|
||||
|
||||
Version v2 = Version.parse(vs2);
|
||||
assertTrue(v2.compareTo(v2) == 0);
|
||||
|
||||
assertTrue(v1.compareTo(v2) == 0);
|
||||
assertTrue(v2.compareTo(v1) == 0);
|
||||
assertEquals(v1, v2);
|
||||
assertEquals(v2, v1);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 8255542
|
||||
* @summary Module attribute has incorrect length
|
||||
* @library ..
|
||||
* @build module-info
|
||||
* @run main CheckBadModuleInfo
|
||||
*/
|
||||
|
|
@ -0,0 +1,98 @@
|
|||
/*
|
||||
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
module {
|
||||
0xCAFEBABE;
|
||||
0; // minor version
|
||||
55; // version
|
||||
[] { // Constant Pool
|
||||
; // first element is empty
|
||||
Utf8 "module-info"; // #1
|
||||
class #1; // #2
|
||||
Utf8 "module-info.java"; // #3
|
||||
Utf8 "m"; // #4
|
||||
Module #4; // #5
|
||||
Utf8 "ModuleMainClass"; // #6
|
||||
Utf8 "p/C"; // #7
|
||||
class #7; // #8
|
||||
Utf8 "ModulePackages"; // #9
|
||||
Utf8 "p"; // #10
|
||||
Package #10; // #11
|
||||
Utf8 "java.base"; // #12
|
||||
Module #12; // #13
|
||||
Utf8 "11.0.2"; // #14
|
||||
Utf8 "SourceFile"; // #15
|
||||
Utf8 "Module"; // #16
|
||||
} // Constant Pool
|
||||
|
||||
0x8000; // access
|
||||
#2;// this_cpx
|
||||
#0;// super_cpx
|
||||
|
||||
[] { // Interfaces
|
||||
} // Interfaces
|
||||
|
||||
[] { // Fields
|
||||
} // Fields
|
||||
|
||||
[] { // Methods
|
||||
} // Methods
|
||||
|
||||
[] { // Attributes
|
||||
Attr(#15) { // SourceFile
|
||||
#3;
|
||||
} // end SourceFile
|
||||
;
|
||||
Attr(#16, 256) { // Module incorrect attribute length
|
||||
#5; // name_index
|
||||
0x0000; // flags
|
||||
#0; // version
|
||||
[] { // requires
|
||||
#13 0x8000 #14;
|
||||
} // requires
|
||||
|
||||
[] { // exports
|
||||
} // exports
|
||||
|
||||
[] { // opens
|
||||
} // opens
|
||||
|
||||
[] { // uses
|
||||
} // uses
|
||||
|
||||
[] { // provides
|
||||
} // provides
|
||||
|
||||
} // end Module
|
||||
;
|
||||
Attr(#6) { // ModuleMainClass
|
||||
0x0008;
|
||||
} // end ModuleMainClass
|
||||
;
|
||||
Attr(#9) { // ModulePackages
|
||||
[] {
|
||||
#11;
|
||||
}
|
||||
} // end ModulePackages
|
||||
} // Attributes
|
||||
} // end module m
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 8255542
|
||||
* @summary ModuleMain attribute has incorrect length
|
||||
* @library ..
|
||||
* @build module-info
|
||||
* @run main CheckBadModuleInfo
|
||||
*/
|
||||
|
|
@ -0,0 +1,98 @@
|
|||
/*
|
||||
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
module {
|
||||
0xCAFEBABE;
|
||||
0; // minor version
|
||||
55; // version
|
||||
[] { // Constant Pool
|
||||
; // first element is empty
|
||||
Utf8 "module-info"; // #1
|
||||
class #1; // #2
|
||||
Utf8 "module-info.java"; // #3
|
||||
Utf8 "m"; // #4
|
||||
Module #4; // #5
|
||||
Utf8 "ModuleMainClass"; // #6
|
||||
Utf8 "p/C"; // #7
|
||||
class #7; // #8
|
||||
Utf8 "ModulePackages"; // #9
|
||||
Utf8 "p"; // #10
|
||||
Package #10; // #11
|
||||
Utf8 "java.base"; // #12
|
||||
Module #12; // #13
|
||||
Utf8 "11.0.2"; // #14
|
||||
Utf8 "SourceFile"; // #15
|
||||
Utf8 "Module"; // #16
|
||||
} // Constant Pool
|
||||
|
||||
0x8000; // access
|
||||
#2;// this_cpx
|
||||
#0;// super_cpx
|
||||
|
||||
[] { // Interfaces
|
||||
} // Interfaces
|
||||
|
||||
[] { // Fields
|
||||
} // Fields
|
||||
|
||||
[] { // Methods
|
||||
} // Methods
|
||||
|
||||
[] { // Attributes
|
||||
Attr(#15) { // SourceFile
|
||||
#3;
|
||||
} // end SourceFile
|
||||
;
|
||||
Attr(#16) { // Module
|
||||
#5; // name_index
|
||||
0x0000; // flags
|
||||
#0; // version
|
||||
[] { // requires
|
||||
#13 0x8000 #14;
|
||||
} // requires
|
||||
|
||||
[] { // exports
|
||||
} // exports
|
||||
|
||||
[] { // opens
|
||||
} // opens
|
||||
|
||||
[] { // uses
|
||||
} // uses
|
||||
|
||||
[] { // provides
|
||||
} // provides
|
||||
|
||||
} // end Module
|
||||
;
|
||||
Attr(#6, 3) { // ModuleMainClass attribute_length 3 instead of 2
|
||||
0x0008;
|
||||
} // end ModuleMainClass
|
||||
;
|
||||
Attr(#9) { // ModulePackages
|
||||
[] {
|
||||
#11;
|
||||
}
|
||||
} // end ModulePackages
|
||||
} // Attributes
|
||||
} // end module m
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 8255542
|
||||
* @summary ModulePackages attribute has incorrect length
|
||||
* @library ..
|
||||
* @build module-info
|
||||
* @run main CheckBadModuleInfo
|
||||
*/
|
||||
|
|
@ -0,0 +1,98 @@
|
|||
/*
|
||||
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
module {
|
||||
0xCAFEBABE;
|
||||
0; // minor version
|
||||
55; // version
|
||||
[] { // Constant Pool
|
||||
; // first element is empty
|
||||
Utf8 "module-info"; // #1
|
||||
class #1; // #2
|
||||
Utf8 "module-info.java"; // #3
|
||||
Utf8 "m"; // #4
|
||||
Module #4; // #5
|
||||
Utf8 "ModuleMainClass"; // #6
|
||||
Utf8 "p/C"; // #7
|
||||
class #7; // #8
|
||||
Utf8 "ModulePackages"; // #9
|
||||
Utf8 "p"; // #10
|
||||
Package #10; // #11
|
||||
Utf8 "java.base"; // #12
|
||||
Module #12; // #13
|
||||
Utf8 "11.0.2"; // #14
|
||||
Utf8 "SourceFile"; // #15
|
||||
Utf8 "Module"; // #16
|
||||
} // Constant Pool
|
||||
|
||||
0x8000; // access
|
||||
#2;// this_cpx
|
||||
#0;// super_cpx
|
||||
|
||||
[] { // Interfaces
|
||||
} // Interfaces
|
||||
|
||||
[] { // Fields
|
||||
} // Fields
|
||||
|
||||
[] { // Methods
|
||||
} // Methods
|
||||
|
||||
[] { // Attributes
|
||||
Attr(#15) { // SourceFile
|
||||
#3;
|
||||
} // end SourceFile
|
||||
;
|
||||
Attr(#16) { // Module
|
||||
#5; // name_index
|
||||
0x0000; // flags
|
||||
#0; // version
|
||||
[] { // requires
|
||||
#13 0x8000 #14;
|
||||
} // requires
|
||||
|
||||
[] { // exports
|
||||
} // exports
|
||||
|
||||
[] { // opens
|
||||
} // opens
|
||||
|
||||
[] { // uses
|
||||
} // uses
|
||||
|
||||
[] { // provides
|
||||
} // provides
|
||||
|
||||
} // end Module
|
||||
;
|
||||
Attr(#6) { // ModuleMainClass
|
||||
0x0008;
|
||||
} // end ModuleMainClass
|
||||
;
|
||||
Attr(#9, 6) { // ModulePackages attribute_length 6 instead of 4
|
||||
[] {
|
||||
#11;
|
||||
}
|
||||
} // end ModulePackages
|
||||
} // Attributes
|
||||
} // end module m
|
||||
50
test/jdk/java/lang/module/badclasses/CheckBadModuleInfo.java
Normal file
50
test/jdk/java/lang/module/badclasses/CheckBadModuleInfo.java
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.lang.module.ModuleDescriptor;
|
||||
import java.lang.module.InvalidModuleDescriptorException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
|
||||
/**
|
||||
* Uses the ModuleDescriptor.read API to read the module-info.class in the
|
||||
* ${test.classes} directory and expects InvalidModuleDescriptorException
|
||||
* to be thrown.
|
||||
*/
|
||||
public class CheckBadModuleInfo {
|
||||
public static void main(String[] args) throws IOException {
|
||||
Path mi = Path.of(System.getProperty("test.classes"), "module-info.class");
|
||||
try (InputStream in = Files.newInputStream(mi)) {
|
||||
try {
|
||||
ModuleDescriptor descriptor = ModuleDescriptor.read(in);
|
||||
System.out.println(descriptor);
|
||||
throw new RuntimeException("InvalidModuleDescriptorException expected");
|
||||
} catch (InvalidModuleDescriptorException e) {
|
||||
// expected
|
||||
System.out.println(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,148 @@
|
|||
/*
|
||||
* Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 8178380 8282444
|
||||
* @modules jdk.zipfs
|
||||
* @library /test/lib
|
||||
* @build ModulesInCustomFileSystem m1/* m2/*
|
||||
* jdk.test.lib.util.JarUtils
|
||||
* @run testng/othervm -Djava.io.tmpdir=. ModulesInCustomFileSystem
|
||||
* @summary Test ModuleFinder to find modules in a custom file system
|
||||
*/
|
||||
|
||||
import java.io.File;
|
||||
import java.lang.module.Configuration;
|
||||
import java.lang.module.ModuleFinder;
|
||||
import java.lang.module.ModuleReader;
|
||||
import java.lang.module.ModuleReference;
|
||||
import java.lang.reflect.Method;
|
||||
import java.nio.file.FileSystem;
|
||||
import java.nio.file.FileSystems;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import jdk.test.lib.util.JarUtils;
|
||||
|
||||
import org.testng.annotations.Test;
|
||||
import static org.testng.Assert.*;
|
||||
|
||||
@Test
|
||||
public class ModulesInCustomFileSystem {
|
||||
private static final Path HERE = Paths.get("");
|
||||
|
||||
/**
|
||||
* Test exploded modules in a Zip file system.
|
||||
*/
|
||||
public void testExplodedModulesInZipFileSystem() throws Exception {
|
||||
Path m1 = findModuleDirectory("m1");
|
||||
Path m2 = findModuleDirectory("m2");
|
||||
Path mlib = m1.getParent();
|
||||
assertEquals(mlib, m2.getParent());
|
||||
|
||||
// create JAR file containing m1/** and m2/**
|
||||
Path jar = Files.createTempDirectory(HERE, "mlib").resolve("modules.jar");
|
||||
JarUtils.createJarFile(jar, mlib);
|
||||
testZipFileSystem(jar);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test modular JARs in a Zip file system.
|
||||
*/
|
||||
public void testModularJARsInZipFileSystem() throws Exception {
|
||||
Path m1 = findModuleDirectory("m1");
|
||||
Path m2 = findModuleDirectory("m2");
|
||||
Path contents = Files.createTempDirectory(HERE, "contents");
|
||||
JarUtils.createJarFile(contents.resolve("m1.jar"), m1);
|
||||
JarUtils.createJarFile(contents.resolve("m2.jar"), m2);
|
||||
|
||||
// create JAR file containing m1.jar and m2.jar
|
||||
Path jar = Files.createTempDirectory(HERE, "mlib").resolve("modules.jar");
|
||||
JarUtils.createJarFile(jar, contents);
|
||||
testZipFileSystem(jar);
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens a JAR file as a file system
|
||||
*/
|
||||
private void testZipFileSystem(Path zip) throws Exception {
|
||||
try (FileSystem fs = FileSystems.newFileSystem(zip)) {
|
||||
// ModuleFinder to find modules in top-level directory
|
||||
Path top = fs.getPath("/");
|
||||
ModuleFinder finder = ModuleFinder.of(top);
|
||||
|
||||
// list the modules
|
||||
listAllModules(finder);
|
||||
|
||||
// load modules into child layer, invoking m1/p.Main
|
||||
loadAndRunModule(finder);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* List all modules that the finder finds and the resources in the module.
|
||||
*/
|
||||
private void listAllModules(ModuleFinder finder) throws Exception {
|
||||
for (ModuleReference mref : finder.findAll()) {
|
||||
System.out.println(mref.descriptor());
|
||||
try (ModuleReader reader = mref.open();
|
||||
Stream<String> stream = reader.list()) {
|
||||
stream.forEach(name -> System.out.format(" %s%n", name));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a child layer with m1 and m2, invokes m1/p.Main to ensure that
|
||||
* classes can be loaded.
|
||||
*/
|
||||
private void loadAndRunModule(ModuleFinder finder) throws Exception {
|
||||
ModuleLayer bootLayer = ModuleLayer.boot();
|
||||
Configuration cf = bootLayer.configuration()
|
||||
.resolve(finder, ModuleFinder.of(), Set.of("m1"));
|
||||
ClassLoader scl = ClassLoader.getSystemClassLoader();
|
||||
ModuleLayer layer = bootLayer.defineModulesWithOneLoader(cf, scl);
|
||||
Class<?> c = layer.findLoader("m1").loadClass("p.Main");
|
||||
Method m = c.getMethod("main", String[].class);
|
||||
m.invoke(null, (Object)new String[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the directory for a module on the module path
|
||||
*/
|
||||
private Path findModuleDirectory(String name) {
|
||||
String mp = System.getProperty("jdk.module.path");
|
||||
for (String element : mp.split(File.pathSeparator)) {
|
||||
Path dir = Paths.get(element).resolve(name);
|
||||
if (Files.exists(dir)) {
|
||||
return dir;
|
||||
}
|
||||
}
|
||||
assertFalse(true);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
27
test/jdk/java/lang/module/customfs/m1/module-info.java
Normal file
27
test/jdk/java/lang/module/customfs/m1/module-info.java
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
module m1 {
|
||||
exports p;
|
||||
requires m2;
|
||||
}
|
||||
30
test/jdk/java/lang/module/customfs/m1/p/Main.java
Normal file
30
test/jdk/java/lang/module/customfs/m1/p/Main.java
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package p;
|
||||
|
||||
public class Main {
|
||||
public static void main(String[] args) {
|
||||
q.r.Hello.hello();
|
||||
}
|
||||
}
|
||||
26
test/jdk/java/lang/module/customfs/m2/module-info.java
Normal file
26
test/jdk/java/lang/module/customfs/m2/module-info.java
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
module m2 {
|
||||
exports q.r;
|
||||
}
|
||||
30
test/jdk/java/lang/module/customfs/m2/q/r/Hello.java
Normal file
30
test/jdk/java/lang/module/customfs/m2/q/r/Hello.java
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package q.r;
|
||||
|
||||
public class Hello {
|
||||
public static void hello() {
|
||||
System.out.println("hello");
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue