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
|
|
@ -0,0 +1,135 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2018, 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.File;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Arrays;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import jdk.test.lib.compiler.CompilerUtils;
|
||||
import jdk.test.lib.util.FileUtils;
|
||||
import static jdk.test.lib.process.ProcessTools.*;
|
||||
|
||||
|
||||
import org.testng.annotations.BeforeTest;
|
||||
import org.testng.annotations.Test;
|
||||
import static org.testng.Assert.*;
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @library /test/lib
|
||||
* @modules jdk.compiler jdk.jlink
|
||||
* @build jdk.test.lib.compiler.CompilerUtils
|
||||
* jdk.test.lib.util.FileUtils
|
||||
* jdk.test.lib.Platform
|
||||
* CompiledVersionTest jdk.test.lib.process.ProcessTools
|
||||
* @run testng CompiledVersionTest
|
||||
*/
|
||||
|
||||
public class CompiledVersionTest {
|
||||
private static final String JAVA_HOME = System.getProperty("java.home");
|
||||
private static final String TEST_SRC = System.getProperty("test.src");
|
||||
|
||||
private static final Path SRC_DIR = Paths.get(TEST_SRC, "src");
|
||||
private static final Path MODS_DIR = Paths.get("mods");
|
||||
private static final Path IMAGE = Paths.get("image");
|
||||
private static final Path JMODS = Paths.get(JAVA_HOME, "jmods");
|
||||
private static final String MAIN_MID = "test/jdk.test.Main";
|
||||
|
||||
// the names of the modules in this test
|
||||
private static String[] modules = new String[] { "m1", "m2", "test"};
|
||||
private static String[] versions = new String[] { "1.0", "2-ea", "3-internal"};
|
||||
|
||||
|
||||
private static boolean hasJmods() {
|
||||
if (!Files.exists(JMODS)) {
|
||||
System.err.println("Test skipped. NO jmods directory");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Compiles all modules used by the test
|
||||
*/
|
||||
@BeforeTest
|
||||
public void compileAll() throws Throwable {
|
||||
if (!hasJmods()) return;
|
||||
|
||||
for (int i=0; i < modules.length; i++) {
|
||||
String mn = modules[i];
|
||||
String version = versions[i];
|
||||
Path msrc = SRC_DIR.resolve(mn);
|
||||
if (version.equals("0")) {
|
||||
assertTrue(CompilerUtils.compile(msrc, MODS_DIR,
|
||||
"--add-exports", "java.base/jdk.internal.module=m1",
|
||||
"--module-source-path", SRC_DIR.toString()));
|
||||
} else {
|
||||
assertTrue(CompilerUtils.compile(msrc, MODS_DIR,
|
||||
"--add-exports", "java.base/jdk.internal.module=m1",
|
||||
"--module-source-path", SRC_DIR.toString(),
|
||||
"--module-version", version));
|
||||
}
|
||||
}
|
||||
|
||||
if (Files.exists(IMAGE)) {
|
||||
FileUtils.deleteFileTreeUnchecked(IMAGE);
|
||||
}
|
||||
|
||||
createImage(IMAGE, modules);
|
||||
}
|
||||
|
||||
private void createImage(Path outputDir, String... modules) throws Throwable {
|
||||
Path jlink = Paths.get(JAVA_HOME, "bin", "jlink");
|
||||
String mp = JMODS.toString() + File.pathSeparator + MODS_DIR.toString();
|
||||
assertTrue(executeProcess(jlink.toString(), "--output", outputDir.toString(),
|
||||
"--add-modules", Arrays.stream(modules).collect(Collectors.joining(",")),
|
||||
"--module-path", mp)
|
||||
.outputTo(System.out)
|
||||
.errorTo(System.out)
|
||||
.getExitValue() == 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Test the image created when linking with a module with
|
||||
* no Packages attribute
|
||||
*/
|
||||
@Test
|
||||
public void testCompiledVersions() throws Throwable {
|
||||
if (!hasJmods()) return;
|
||||
|
||||
Path java = IMAGE.resolve("bin").resolve("java");
|
||||
Stream<String> options = Stream.concat(
|
||||
Stream.of(java.toString(), "-m", MAIN_MID, String.valueOf(modules.length)),
|
||||
Stream.concat(Arrays.stream(modules), Arrays.stream(versions))
|
||||
);
|
||||
|
||||
assertTrue(executeProcess(options.toArray(String[]::new))
|
||||
.outputTo(System.out)
|
||||
.errorTo(System.out)
|
||||
.getExitValue() == 0);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,145 @@
|
|||
/*
|
||||
* Copyright (c) 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.
|
||||
*/
|
||||
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Arrays;
|
||||
import java.util.spi.ToolProvider;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import jdk.test.lib.compiler.CompilerUtils;
|
||||
import jdk.test.lib.util.FileUtils;
|
||||
|
||||
import static jdk.test.lib.process.ProcessTools.*;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 8322809
|
||||
* @library /test/lib
|
||||
* @modules jdk.compiler jdk.jlink
|
||||
* @build jdk.test.lib.compiler.CompilerUtils
|
||||
* jdk.test.lib.process.ProcessTools
|
||||
* jdk.test.lib.util.FileUtils
|
||||
* ModuleMainClassTest
|
||||
* @run junit ModuleMainClassTest
|
||||
*/
|
||||
|
||||
public class ModuleMainClassTest {
|
||||
private static final String JAVA_HOME = System.getProperty("java.home");
|
||||
private static final String TEST_SRC = System.getProperty("test.src");
|
||||
|
||||
private static final Path SRC_DIR = Path.of(TEST_SRC, "src");
|
||||
private static final Path MODS_DIR = Path.of("mods");
|
||||
private static final Path JMODS_DIR = Path.of("jmods");
|
||||
|
||||
private static final Path IMAGE = Path.of("image");
|
||||
|
||||
// the module names are sorted by the plugin and so these names cover
|
||||
// the cases that are before and after the elements of `jdk.*` modules
|
||||
// with main classes
|
||||
private static String[] modules = new String[] {"com.foo", "net.foo"};
|
||||
|
||||
private static boolean hasJmods() {
|
||||
if (!Files.exists(Paths.get(JAVA_HOME, "jmods"))) {
|
||||
System.err.println("Test skipped. NO jmods directory");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@BeforeAll
|
||||
public static void compileAll() throws Throwable {
|
||||
if (!hasJmods()) return;
|
||||
|
||||
for (String mn : modules) {
|
||||
Path msrc = SRC_DIR.resolve(mn);
|
||||
assertTrue(CompilerUtils.compile(msrc, MODS_DIR,
|
||||
"--module-source-path", SRC_DIR.toString(),
|
||||
"--add-exports", "java.base/jdk.internal.module=" + mn));
|
||||
}
|
||||
|
||||
if (Files.exists(IMAGE)) {
|
||||
FileUtils.deleteFileTreeUnchecked(IMAGE);
|
||||
}
|
||||
|
||||
// create JMOD files
|
||||
Files.createDirectories(JMODS_DIR);
|
||||
Stream.of(modules).forEach(mn ->
|
||||
assertTrue(jmod("create",
|
||||
"--class-path", MODS_DIR.resolve(mn).toString(),
|
||||
"--main-class", mn + ".Main",
|
||||
JMODS_DIR.resolve(mn + ".jmod").toString()) == 0)
|
||||
);
|
||||
|
||||
// the run-time image created will have 4 modules with main classes
|
||||
createImage(IMAGE, "com.foo");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testComFoo() throws Exception {
|
||||
if (!hasJmods()) return;
|
||||
|
||||
Path java = IMAGE.resolve("bin").resolve("java");
|
||||
assertTrue(executeProcess(java.toString(),
|
||||
"-m", "com.foo")
|
||||
.outputTo(System.out)
|
||||
.errorTo(System.out)
|
||||
.getExitValue() == 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNetFoo() throws Exception {
|
||||
if (!hasJmods()) return;
|
||||
|
||||
Path java = IMAGE.resolve("bin").resolve("java");
|
||||
assertTrue(executeProcess(java.toString(),
|
||||
"-m", "net.foo")
|
||||
.outputTo(System.out)
|
||||
.errorTo(System.out)
|
||||
.getExitValue() == 0);
|
||||
}
|
||||
|
||||
static final ToolProvider JLINK_TOOL = ToolProvider.findFirst("jlink")
|
||||
.orElseThrow(() -> new RuntimeException("jlink tool not found"));
|
||||
|
||||
static final ToolProvider JMOD_TOOL = ToolProvider.findFirst("jmod")
|
||||
.orElseThrow(() -> new RuntimeException("jmod tool not found"));
|
||||
|
||||
private static void createImage(Path outputDir, String... modules) throws Throwable {
|
||||
assertTrue(JLINK_TOOL.run(System.out, System.out,
|
||||
"--output", outputDir.toString(),
|
||||
"--add-modules", Arrays.stream(modules).collect(Collectors.joining(",")),
|
||||
"--module-path", JMODS_DIR.toString()) == 0);
|
||||
}
|
||||
|
||||
private static int jmod(String... options) {
|
||||
System.out.println("jmod " + Arrays.asList(options));
|
||||
return JMOD_TOOL.run(System.out, System.out, options);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.IOException;
|
||||
import java.lang.module.ModuleReader;
|
||||
import java.lang.module.ModuleReference;
|
||||
import java.net.URI;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
import jdk.internal.module.ModuleInfo;
|
||||
import jdk.internal.module.ModuleInfo.Attributes;
|
||||
|
||||
public class ModuleTargetHelper {
|
||||
private ModuleTargetHelper() {}
|
||||
|
||||
public static final class ModuleTarget {
|
||||
private String targetPlatform;
|
||||
|
||||
public ModuleTarget(String targetPlatform) {
|
||||
this.targetPlatform = targetPlatform;
|
||||
}
|
||||
|
||||
public String targetPlatform() {
|
||||
return targetPlatform;
|
||||
}
|
||||
}
|
||||
|
||||
public static ModuleTarget getJavaBaseTarget() throws IOException {
|
||||
Path p = Paths.get(URI.create("jrt:/java.base/module-info.class"));
|
||||
try (InputStream in = Files.newInputStream(p)) {
|
||||
return read(in);
|
||||
}
|
||||
}
|
||||
|
||||
public static ModuleTarget read(InputStream in) throws IOException {
|
||||
ModuleInfo.Attributes attrs = ModuleInfo.read(in, null);
|
||||
if (attrs.target() != null) {
|
||||
return new ModuleTarget(attrs.target().targetPlatform());
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static ModuleTarget read(ModuleReference modRef) throws IOException {
|
||||
ModuleReader reader = modRef.open();
|
||||
try (InputStream in = reader.open("module-info.class").get()) {
|
||||
return read(in);
|
||||
} finally {
|
||||
reader.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,194 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 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.lang.module.ModuleDescriptor;
|
||||
import java.lang.module.ModuleDescriptor.*;
|
||||
import java.lang.module.ModuleFinder;
|
||||
import java.lang.module.ModuleReference;
|
||||
import java.io.IOException;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import jdk.internal.access.JavaLangModuleAccess;
|
||||
import jdk.internal.access.SharedSecrets;
|
||||
import org.testng.annotations.Test;
|
||||
import static org.testng.Assert.*;
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 8142968 8173381
|
||||
* @modules java.base/jdk.internal.access
|
||||
* @modules java.base/jdk.internal.module
|
||||
* @build ModuleTargetHelper
|
||||
* @run testng SystemModulesTest
|
||||
* @summary Verify the properties of ModuleDescriptor created
|
||||
* by SystemModules
|
||||
*/
|
||||
|
||||
public class SystemModulesTest {
|
||||
private static final JavaLangModuleAccess JLMA =
|
||||
SharedSecrets.getJavaLangModuleAccess();
|
||||
private static final String OS_NAME = System.getProperty("os.name");
|
||||
private static final String OS_ARCH = System.getProperty("os.arch");
|
||||
// system modules containing no package
|
||||
private static final Set<String> EMPTY_MODULES =
|
||||
Set.of("java.se", "jdk.jdwp.agent", "jdk.pack");
|
||||
|
||||
@Test
|
||||
public void testSystemModules() {
|
||||
Path jimage = Paths.get(System.getProperty("java.home"), "lib", "modules");
|
||||
if (Files.notExists(jimage))
|
||||
return;
|
||||
|
||||
ModuleFinder.ofSystem().findAll().stream()
|
||||
.forEach(this::checkAttributes);
|
||||
}
|
||||
|
||||
// JMOD files are created with OS name and arch matching the bundle name
|
||||
private boolean checkOSName(String name) {
|
||||
if (OS_NAME.startsWith("Windows")) {
|
||||
return name.equals("windows");
|
||||
}
|
||||
|
||||
switch (OS_NAME) {
|
||||
case "Linux":
|
||||
return name.equals("linux");
|
||||
case "Mac OS X":
|
||||
return name.equals("macos");
|
||||
default:
|
||||
// skip validation on unknown platform
|
||||
System.out.println("Skip checking OS name in ModuleTarget: " + name);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean checkOSArch(String name) {
|
||||
if (name.equals(OS_ARCH))
|
||||
return true;
|
||||
|
||||
switch (OS_ARCH) {
|
||||
case "i386":
|
||||
case "x86":
|
||||
return name.equals("x86");
|
||||
case "amd64":
|
||||
case "x86_64":
|
||||
return name.equals("amd64");
|
||||
default:
|
||||
// skip validation on unknown platform
|
||||
System.out.println("Skip checking OS arch in ModuleTarget: " + name);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private void checkAttributes(ModuleReference modRef) {
|
||||
try {
|
||||
ModuleTargetHelper.ModuleTarget mt = ModuleTargetHelper.read(modRef);
|
||||
String[] values = mt.targetPlatform().split("-");
|
||||
assertTrue(checkOSName(values[0]));
|
||||
assertTrue(checkOSArch(values[1]));
|
||||
} catch (IOException exp) {
|
||||
throw new UncheckedIOException(exp);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify ModuleDescriptor contains unmodifiable sets
|
||||
*/
|
||||
@Test
|
||||
public void testUnmodifableDescriptors() throws Exception {
|
||||
ModuleFinder.ofSystem().findAll()
|
||||
.stream()
|
||||
.map(ModuleReference::descriptor)
|
||||
.forEach(this::testModuleDescriptor);
|
||||
}
|
||||
|
||||
private void testModuleDescriptor(ModuleDescriptor md) {
|
||||
assertUnmodifiable(md.packages(), "package");
|
||||
assertUnmodifiable(md.requires(),
|
||||
JLMA.newRequires(Set.of(Requires.Modifier.TRANSITIVE),
|
||||
"require", null));
|
||||
for (Requires req : md.requires()) {
|
||||
assertUnmodifiable(req.modifiers(), Requires.Modifier.TRANSITIVE);
|
||||
}
|
||||
|
||||
assertUnmodifiable(md.exports(), JLMA.newExports(Set.of(), "export", Set.of()));
|
||||
for (Exports exp : md.exports()) {
|
||||
assertUnmodifiable(exp.modifiers(), Exports.Modifier.SYNTHETIC);
|
||||
assertUnmodifiable(exp.targets(), "target");
|
||||
}
|
||||
|
||||
assertUnmodifiable(md.opens(), JLMA.newOpens(Set.of(), "open", Set.of()));
|
||||
for (Opens opens : md.opens()) {
|
||||
assertUnmodifiable(opens.modifiers(), Opens.Modifier.SYNTHETIC);
|
||||
assertUnmodifiable(opens.targets(), "target");
|
||||
}
|
||||
|
||||
assertUnmodifiable(md.uses(), "use");
|
||||
|
||||
assertUnmodifiable(md.provides(),
|
||||
JLMA.newProvides("provide", List.of("provide")));
|
||||
for (Provides provides : md.provides()) {
|
||||
assertUnmodifiable(provides.providers(), "provide");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private <T> void assertUnmodifiable(Set<T> set, T dummy) {
|
||||
try {
|
||||
set.add(dummy);
|
||||
fail("Should throw UnsupportedOperationException");
|
||||
} catch (UnsupportedOperationException e) {
|
||||
// pass
|
||||
} catch (Exception e) {
|
||||
fail("Should throw UnsupportedOperationException");
|
||||
}
|
||||
}
|
||||
|
||||
private <T> void assertUnmodifiable(List<T> list, T dummy) {
|
||||
try {
|
||||
list.add(dummy);
|
||||
fail("Should throw UnsupportedOperationException");
|
||||
} catch (UnsupportedOperationException e) {
|
||||
// pass
|
||||
} catch (Exception e) {
|
||||
fail("Should throw UnsupportedOperationException");
|
||||
}
|
||||
}
|
||||
|
||||
private <T, V> void assertUnmodifiable(Map<T, V> set, T dummyKey, V dummyValue) {
|
||||
try {
|
||||
set.put(dummyKey, dummyValue);
|
||||
fail("Should throw UnsupportedOperationException");
|
||||
} catch (UnsupportedOperationException e) {
|
||||
// pass
|
||||
} catch (Exception e) {
|
||||
fail("Should throw UnsupportedOperationException");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,319 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2018, 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.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Arrays;
|
||||
import java.util.Set;
|
||||
import java.util.spi.ToolProvider;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import jdk.test.lib.compiler.CompilerUtils;
|
||||
import jdk.test.lib.util.FileUtils;
|
||||
|
||||
import static jdk.test.lib.process.ProcessTools.*;
|
||||
|
||||
import org.testng.annotations.BeforeTest;
|
||||
import org.testng.annotations.Test;
|
||||
import static org.testng.Assert.*;
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 8142968 8173381 8174740
|
||||
* @library /test/lib
|
||||
* @modules jdk.compiler jdk.jlink
|
||||
* @modules java.base/jdk.internal.module
|
||||
* @build jdk.test.lib.compiler.CompilerUtils
|
||||
* jdk.test.lib.util.FileUtils
|
||||
* jdk.test.lib.Platform
|
||||
* ModuleTargetHelper UserModuleTest jdk.test.lib.process.ProcessTools
|
||||
* @run testng UserModuleTest
|
||||
*/
|
||||
|
||||
public class UserModuleTest {
|
||||
private static final String JAVA_HOME = System.getProperty("java.home");
|
||||
private static final String TEST_SRC = System.getProperty("test.src");
|
||||
|
||||
private static final Path SRC_DIR = Paths.get(TEST_SRC, "src");
|
||||
private static final Path MODS_DIR = Paths.get("mods");
|
||||
private static final Path JMODS_DIR = Paths.get("jmods");
|
||||
|
||||
private static final Path IMAGE = Paths.get("image");
|
||||
private static final String MAIN_MID = "m1/p1.Main";
|
||||
|
||||
// the names of the modules in this test
|
||||
private static String[] modules = new String[] {"m1", "m2", "m3", "m4", "m5"};
|
||||
|
||||
|
||||
private static boolean hasJmods() {
|
||||
if (!Files.exists(Paths.get(JAVA_HOME, "jmods"))) {
|
||||
System.err.println("Test skipped. NO jmods directory");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Compiles all modules used by the test
|
||||
*/
|
||||
@BeforeTest
|
||||
public void compileAll() throws Throwable {
|
||||
if (!hasJmods()) return;
|
||||
|
||||
for (String mn : modules) {
|
||||
Path msrc = SRC_DIR.resolve(mn);
|
||||
assertTrue(CompilerUtils.compile(msrc, MODS_DIR,
|
||||
"--module-source-path", SRC_DIR.toString(),
|
||||
"--add-exports", "java.base/jdk.internal.module=" + mn));
|
||||
}
|
||||
|
||||
if (Files.exists(IMAGE)) {
|
||||
FileUtils.deleteFileTreeUnchecked(IMAGE);
|
||||
}
|
||||
|
||||
createImage(IMAGE, "m1", "m3");
|
||||
|
||||
createJmods("m1", "m4");
|
||||
}
|
||||
|
||||
/*
|
||||
* Test the image created when linking with a module with
|
||||
* no Packages attribute
|
||||
*/
|
||||
@Test
|
||||
public void testPackagesAttribute() throws Throwable {
|
||||
if (!hasJmods()) return;
|
||||
|
||||
Path java = IMAGE.resolve("bin").resolve("java");
|
||||
assertTrue(executeProcess(java.toString(),
|
||||
"--add-exports", "java.base/jdk.internal.module=m1,m4",
|
||||
"-m", MAIN_MID)
|
||||
.outputTo(System.out)
|
||||
.errorTo(System.out)
|
||||
.getExitValue() == 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Test the image created when linking with an open module
|
||||
*/
|
||||
@Test
|
||||
public void testOpenModule() throws Throwable {
|
||||
if (!hasJmods()) return;
|
||||
|
||||
Path java = IMAGE.resolve("bin").resolve("java");
|
||||
assertTrue(executeProcess(java.toString(), "-m", "m3/p3.Main")
|
||||
.outputTo(System.out)
|
||||
.errorTo(System.out)
|
||||
.getExitValue() == 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Disable the fast loading of system modules.
|
||||
* Parsing module-info.class
|
||||
*/
|
||||
@Test
|
||||
public void disableSystemModules() throws Throwable {
|
||||
if (!hasJmods()) return;
|
||||
|
||||
Path java = IMAGE.resolve("bin").resolve("java");
|
||||
assertTrue(executeProcess(java.toString(),
|
||||
"--add-exports", "java.base/jdk.internal.module=m1,m4",
|
||||
"-Djdk.system.module.finder.disabledFastPath",
|
||||
"-m", MAIN_MID)
|
||||
.outputTo(System.out)
|
||||
.errorTo(System.out)
|
||||
.getExitValue() == 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Test the optimization that deduplicates Set<String> on targets of exports,
|
||||
* uses, provides.
|
||||
*/
|
||||
@Test
|
||||
public void testDedupSet() throws Throwable {
|
||||
if (!hasJmods()) return;
|
||||
|
||||
Path dir = Paths.get("dedupSetTest");
|
||||
createImage(dir, "m1", "m2", "m3", "m4");
|
||||
Path java = dir.resolve("bin").resolve("java");
|
||||
assertTrue(executeProcess(java.toString(),
|
||||
"--add-exports", "java.base/jdk.internal.module=m1,m4",
|
||||
"-m", MAIN_MID)
|
||||
.outputTo(System.out)
|
||||
.errorTo(System.out)
|
||||
.getExitValue() == 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRequiresStatic() throws Throwable {
|
||||
if (!hasJmods()) return;
|
||||
|
||||
Path dir = Paths.get("requiresStatic");
|
||||
createImage(dir, "m5");
|
||||
Path java = dir.resolve("bin").resolve("java");
|
||||
assertTrue(executeProcess(java.toString(), "-m", "m5/p5.Main")
|
||||
.outputTo(System.out)
|
||||
.errorTo(System.out)
|
||||
.getExitValue() == 0);
|
||||
|
||||
// run with m3 present
|
||||
assertTrue(executeProcess(java.toString(),
|
||||
"--module-path", MODS_DIR.toString(),
|
||||
"--add-modules", "m3",
|
||||
"-m", "m5/p5.Main")
|
||||
.outputTo(System.out)
|
||||
.errorTo(System.out)
|
||||
.getExitValue() == 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRequiresStatic2() throws Throwable {
|
||||
if (!hasJmods()) return;
|
||||
|
||||
Path dir = Paths.get("requiresStatic2");
|
||||
createImage(dir, "m3", "m5");
|
||||
|
||||
Path java = dir.resolve("bin").resolve("java");
|
||||
assertTrue(executeProcess(java.toString(), "-m", "m5/p5.Main")
|
||||
.outputTo(System.out)
|
||||
.errorTo(System.out)
|
||||
.getExitValue() == 0);
|
||||
|
||||
// boot layer with m3 and m5
|
||||
assertTrue(executeProcess(java.toString(),
|
||||
"--add-modules", "m3",
|
||||
"-m", "m5/p5.Main")
|
||||
.outputTo(System.out)
|
||||
.errorTo(System.out)
|
||||
.getExitValue() == 0);
|
||||
}
|
||||
|
||||
private void createJmods(String... modules) throws IOException {
|
||||
ModuleTargetHelper.ModuleTarget mt = ModuleTargetHelper.getJavaBaseTarget();
|
||||
if (mt == null) {
|
||||
throw new RuntimeException("ModuleTarget is missing for java.base");
|
||||
}
|
||||
|
||||
String[] values = mt.targetPlatform().split("-");
|
||||
String osName = values[0];
|
||||
String osArch = values[1];
|
||||
|
||||
// create JMOD files
|
||||
Files.createDirectories(JMODS_DIR);
|
||||
Stream.of(modules).forEach(mn ->
|
||||
assertTrue(jmod("create",
|
||||
"--class-path", MODS_DIR.resolve(mn).toString(),
|
||||
"--target-platform", mt.targetPlatform(),
|
||||
"--main-class", mn.replace('m', 'p') + ".Main",
|
||||
JMODS_DIR.resolve(mn + ".jmod").toString()) == 0)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Verify the module descriptor if package p4.dummy is excluded at link time.
|
||||
*/
|
||||
@Test
|
||||
public void testModulePackagesAttribute() throws Throwable {
|
||||
if (!hasJmods()) return;
|
||||
|
||||
// create an image using JMOD files
|
||||
Path dir = Paths.get("packagesTest");
|
||||
String mp = Paths.get(JAVA_HOME, "jmods").toString() +
|
||||
File.pathSeparator + JMODS_DIR.toString();
|
||||
|
||||
Set<String> modules = Set.of("m1", "m4");
|
||||
assertTrue(JLINK_TOOL.run(System.out, System.out,
|
||||
"--output", dir.toString(),
|
||||
"--exclude-resources", "m4/p4/dummy/*",
|
||||
"--add-modules", modules.stream().collect(Collectors.joining(",")),
|
||||
"--module-path", mp) == 0);
|
||||
|
||||
// verify ModuleDescriptor
|
||||
Path java = dir.resolve("bin").resolve("java");
|
||||
assertTrue(executeProcess(java.toString(),
|
||||
"--add-exports", "java.base/jdk.internal.module=m1,m4",
|
||||
"--add-modules=m1", "-m", "m4")
|
||||
.outputTo(System.out)
|
||||
.errorTo(System.out)
|
||||
.getExitValue() == 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify the plugin to retain ModuleTarget attribute
|
||||
*/
|
||||
@Test
|
||||
public void testRetainModuleTarget() throws Throwable {
|
||||
if (!hasJmods()) return;
|
||||
|
||||
// create an image using JMOD files
|
||||
Path dir = Paths.get("retainModuleTargetTest");
|
||||
String mp = Paths.get(JAVA_HOME, "jmods").toString() +
|
||||
File.pathSeparator + JMODS_DIR.toString();
|
||||
|
||||
Set<String> modules = Set.of("m1", "m4");
|
||||
assertTrue(JLINK_TOOL.run(System.out, System.out,
|
||||
"--output", dir.toString(),
|
||||
"--exclude-resources", "m4/p4/dummy/*",
|
||||
"--add-modules", modules.stream().collect(Collectors.joining(",")),
|
||||
"--module-path", mp) == 0);
|
||||
|
||||
// verify ModuleDescriptor
|
||||
Path java = dir.resolve("bin").resolve("java");
|
||||
assertTrue(executeProcess(java.toString(),
|
||||
"--add-exports", "java.base/jdk.internal.module=m1,m4",
|
||||
"--add-modules=m1", "-m", "m4", "retainModuleTarget")
|
||||
.outputTo(System.out)
|
||||
.errorTo(System.out)
|
||||
.getExitValue() == 0);
|
||||
}
|
||||
|
||||
static final ToolProvider JLINK_TOOL = ToolProvider.findFirst("jlink")
|
||||
.orElseThrow(() ->
|
||||
new RuntimeException("jlink tool not found")
|
||||
);
|
||||
|
||||
static final ToolProvider JMOD_TOOL = ToolProvider.findFirst("jmod")
|
||||
.orElseThrow(() ->
|
||||
new RuntimeException("jmod tool not found")
|
||||
);
|
||||
|
||||
static final String MODULE_PATH = Paths.get(JAVA_HOME, "jmods").toString()
|
||||
+ File.pathSeparator + MODS_DIR.toString();
|
||||
|
||||
private void createImage(Path outputDir, String... modules) throws Throwable {
|
||||
assertTrue(JLINK_TOOL.run(System.out, System.out,
|
||||
"--output", outputDir.toString(),
|
||||
"--add-modules", Arrays.stream(modules).collect(Collectors.joining(",")),
|
||||
"--module-path", MODULE_PATH) == 0);
|
||||
}
|
||||
|
||||
private static int jmod(String... options) {
|
||||
System.out.println("jmod " + Arrays.asList(options));
|
||||
return JMOD_TOOL.run(System.out, System.out, options);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* Copyright (c) 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.
|
||||
*/
|
||||
|
||||
package com.foo;
|
||||
|
||||
import java.lang.module.ModuleDescriptor;
|
||||
import java.lang.module.ModuleFinder;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* Sanity test if SystemModules pre-resolved at link-time for com.foo
|
||||
* with main class is loaded properly.
|
||||
*/
|
||||
public class Main {
|
||||
public static void main(String... args) throws Exception {
|
||||
ModuleDescriptor md = Main.class.getModule().getDescriptor();
|
||||
System.out.println(md);
|
||||
|
||||
checkMainClass("com.foo", "com.foo.Main");
|
||||
checkMainClass("net.foo", "net.foo.Main");
|
||||
Stream.of("jdk.httpserver", "jdk.jfr").forEach(mn ->
|
||||
ModuleFinder.ofSystem().find(mn).get().descriptor().mainClass()
|
||||
.orElseThrow(() -> new RuntimeException(mn + " no main class"))
|
||||
);
|
||||
}
|
||||
|
||||
static void checkMainClass(String mn, String mainClass) {
|
||||
String cn = ModuleFinder.ofSystem().find(mn).get().descriptor().mainClass().get();
|
||||
if (!cn.equals(mainClass)) {
|
||||
throw new RuntimeException("Mismatched main class of module " + mn + ": " + cn + " expected: " + mainClass);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* Copyright (c) 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.
|
||||
*/
|
||||
|
||||
module com.foo {
|
||||
requires jdk.httpserver;
|
||||
requires net.foo;
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* m1 has an exported package and also internal package
|
||||
*/
|
||||
module m1 {
|
||||
exports p1;
|
||||
}
|
||||
|
|
@ -0,0 +1,94 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 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 p1;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.IOException;
|
||||
import java.lang.module.ModuleDescriptor;
|
||||
import java.net.URI;
|
||||
import java.nio.file.FileSystem;
|
||||
import java.nio.file.FileSystems;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
|
||||
import jdk.internal.module.ModuleInfo;
|
||||
import jdk.internal.module.ModuleInfo.Attributes;
|
||||
|
||||
public class Main {
|
||||
private static boolean hasModuleTarget(InputStream in) throws IOException {
|
||||
ModuleInfo.Attributes attrs = ModuleInfo.read(in, null);
|
||||
return attrs.target() != null;
|
||||
}
|
||||
|
||||
public static void main(String... args) throws Exception {
|
||||
// load another package
|
||||
p2.T.test();
|
||||
|
||||
// validate the module descriptor
|
||||
validate(Main.class.getModule());
|
||||
|
||||
// validate the Moduletarget attribute for java.base
|
||||
FileSystem fs = FileSystems.newFileSystem(URI.create("jrt:/"),
|
||||
Collections.emptyMap());
|
||||
Path path = fs.getPath("/", "modules", "java.base", "module-info.class");
|
||||
try (InputStream in = Files.newInputStream(path)) {
|
||||
if (! hasModuleTarget(in)) {
|
||||
throw new RuntimeException("Missing ModuleTarget for java.base");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void validate(Module module) throws IOException {
|
||||
ModuleDescriptor md = module.getDescriptor();
|
||||
|
||||
// read m1/module-info.class
|
||||
FileSystem fs = FileSystems.newFileSystem(URI.create("jrt:/"),
|
||||
Collections.emptyMap());
|
||||
Path path = fs.getPath("/", "modules", module.getName(), "module-info.class");
|
||||
ModuleDescriptor md1 = ModuleDescriptor.read(Files.newInputStream(path));
|
||||
|
||||
|
||||
// check the module descriptor of a system module and read from jimage
|
||||
checkPackages(md.packages(), "p1", "p2");
|
||||
checkPackages(md1.packages(), "p1", "p2");
|
||||
|
||||
try (InputStream in = Files.newInputStream(path)) {
|
||||
checkModuleTargetAttribute(in, "p1");
|
||||
}
|
||||
}
|
||||
|
||||
static void checkPackages(Set<String> pkgs, String... expected) {
|
||||
if (!pkgs.equals(Set.of(expected))) {
|
||||
throw new RuntimeException(pkgs + " expected: " + Set.of(expected));
|
||||
}
|
||||
}
|
||||
|
||||
static void checkModuleTargetAttribute(InputStream in, String modName) throws IOException {
|
||||
if (hasModuleTarget(in)) {
|
||||
throw new RuntimeException("ModuleTarget present for " + modName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* Copyright (c) 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.
|
||||
*/
|
||||
|
||||
package p2;
|
||||
|
||||
public class T {
|
||||
public static void test() { }
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* Copyright (c) 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.
|
||||
*/
|
||||
|
||||
module m2 {
|
||||
uses q.S1;
|
||||
uses q.S2;
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* Copyright (c) 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.
|
||||
*/
|
||||
|
||||
package q;
|
||||
|
||||
public interface S1 {
|
||||
public String name();
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* Copyright (c) 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.
|
||||
*/
|
||||
|
||||
package q;
|
||||
|
||||
public interface S2 {
|
||||
public String name();
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* Copyright (c) 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.
|
||||
*/
|
||||
|
||||
module m3 {
|
||||
requires m4;
|
||||
exports p3;
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* 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 p3;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Documented
|
||||
@Target(ElementType.FIELD)
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public @interface Foo {
|
||||
}
|
||||
|
|
@ -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 p3;
|
||||
|
||||
public class Lib {
|
||||
public static String concat(String x, String y) {
|
||||
return x + y;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
* Copyright (c) 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.
|
||||
*/
|
||||
|
||||
package p3;
|
||||
|
||||
import p4.Foo;
|
||||
import java.lang.module.ModuleDescriptor;
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import static java.lang.module.ModuleDescriptor.Exports.Modifier.*;
|
||||
|
||||
/**
|
||||
* Test if m4 is an open module and p4 is package that m3 can access
|
||||
*/
|
||||
public class Main {
|
||||
public static void main(String... args) throws Exception {
|
||||
Module m4 = Foo.class.getModule();
|
||||
if (!m4.isOpen("p4")) {
|
||||
throw new RuntimeException("m3 can't access p4");
|
||||
}
|
||||
|
||||
// Test if it can access a private field
|
||||
Foo foo = Foo.create("foo");
|
||||
|
||||
Field field = Foo.class.getDeclaredField("name");
|
||||
field.setAccessible(true);
|
||||
String name = (String) field.get(foo);
|
||||
if (!name.equals("foo")) {
|
||||
throw new RuntimeException("unexpected Foo::name value = " + name);
|
||||
}
|
||||
|
||||
checkOpenModule();
|
||||
}
|
||||
|
||||
// check the module descriptor of the open module m4
|
||||
static void checkOpenModule() {
|
||||
ModuleDescriptor md = Foo.class.getModule().getDescriptor();
|
||||
System.out.println(md);
|
||||
|
||||
if (!md.isOpen()) {
|
||||
throw new RuntimeException("m4 is a open module");
|
||||
}
|
||||
|
||||
if (md.packages().size() != 1 || !md.packages().contains("p4")) {
|
||||
throw new RuntimeException("unexpected m4 packages: " + md.packages());
|
||||
}
|
||||
|
||||
if (!md.opens().isEmpty()) {
|
||||
throw new RuntimeException("unexpected m4 opens: " + md.opens());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* Copyright (c) 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.
|
||||
*/
|
||||
|
||||
open module m4 {
|
||||
exports p4;
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Copyright (c) 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.
|
||||
*/
|
||||
|
||||
package p4;
|
||||
|
||||
public class Foo {
|
||||
private final String name;
|
||||
|
||||
private Foo(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public static Foo create(String name) {
|
||||
return new Foo(name);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,110 @@
|
|||
/*
|
||||
* 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 p4;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.lang.module.ModuleDescriptor;
|
||||
import java.lang.module.ModuleFinder;
|
||||
import java.net.URI;
|
||||
import java.nio.file.FileSystem;
|
||||
import java.nio.file.FileSystems;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import jdk.internal.module.ModuleInfo;
|
||||
import jdk.internal.module.ModuleInfo.Attributes;
|
||||
|
||||
public class Main {
|
||||
private static boolean hasModuleTarget(InputStream in) throws IOException {
|
||||
ModuleInfo.Attributes attrs = ModuleInfo.read(in, null);
|
||||
return attrs.target() != null;
|
||||
}
|
||||
|
||||
private static boolean hasModuleTarget(String modName) throws IOException {
|
||||
FileSystem fs = FileSystems.newFileSystem(URI.create("jrt:/"), Map.of());
|
||||
Path path = fs.getPath("/", "modules", modName, "module-info.class");
|
||||
try (InputStream in = Files.newInputStream(path)) {
|
||||
return hasModuleTarget(in);
|
||||
}
|
||||
}
|
||||
|
||||
// the system module plugin by default drops ModuleTarget attribute
|
||||
private static boolean expectModuleTarget = false;
|
||||
public static void main(String... args) throws IOException {
|
||||
if (args.length > 0) {
|
||||
if (!args[0].equals("retainModuleTarget")) {
|
||||
throw new IllegalArgumentException(args[0]);
|
||||
}
|
||||
|
||||
expectModuleTarget = true;
|
||||
}
|
||||
|
||||
// java.base is packaged with ModuleTarget
|
||||
if (!hasModuleTarget("java.base")) {
|
||||
throw new RuntimeException("ModuleTarget absent for java.base");
|
||||
}
|
||||
|
||||
// verify module-info.class for m1 and m4
|
||||
checkModule("m1", "p1", "p2");
|
||||
checkModule("m4", "p4");
|
||||
}
|
||||
|
||||
private static void checkModule(String mn, String... packages) throws IOException {
|
||||
// verify ModuleDescriptor from the runtime module
|
||||
ModuleDescriptor md = ModuleLayer.boot().findModule(mn).get()
|
||||
.getDescriptor();
|
||||
checkModuleDescriptor(md, packages);
|
||||
|
||||
// verify ModuleDescriptor from module-info.class read from ModuleReader
|
||||
try (InputStream in = ModuleFinder.ofSystem().find(mn).get()
|
||||
.open().open("module-info.class").get()) {
|
||||
checkModuleDescriptor(ModuleDescriptor.read(in), packages);
|
||||
}
|
||||
|
||||
// verify ModuleDescriptor from module-info.class read from jimage
|
||||
FileSystem fs = FileSystems.newFileSystem(URI.create("jrt:/"), Map.of());
|
||||
Path path = fs.getPath("/", "modules", mn, "module-info.class");
|
||||
checkModuleDescriptor(ModuleDescriptor.read(Files.newInputStream(path)), packages);
|
||||
}
|
||||
|
||||
static void checkModuleDescriptor(ModuleDescriptor md, String... packages) throws IOException {
|
||||
String mainClass = md.name().replace('m', 'p') + ".Main";
|
||||
if (!md.mainClass().get().equals(mainClass)) {
|
||||
throw new RuntimeException(md.mainClass().toString());
|
||||
}
|
||||
|
||||
// ModuleTarget attribute should be present
|
||||
if (!hasModuleTarget(md.name())) {
|
||||
throw new RuntimeException("ModuleTarget missing for " + md.name());
|
||||
}
|
||||
|
||||
Set<String> pkgs = md.packages();
|
||||
if (!pkgs.equals(Set.of(packages))) {
|
||||
throw new RuntimeException(pkgs + " expected: " + Set.of(packages));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
key=dummy
|
||||
|
|
@ -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 m5 {
|
||||
requires static m3;
|
||||
exports p5;
|
||||
}
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* 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 p5;
|
||||
|
||||
import p3.Foo;
|
||||
import p3.Lib;
|
||||
|
||||
/**
|
||||
* This test verifies jlink support of requires static.
|
||||
*/
|
||||
public class Main {
|
||||
public static void main(String... args) {
|
||||
boolean libPresent = ModuleLayer.boot().findModule("m3").isPresent();
|
||||
if (LibHelper.libClassFound != libPresent) {
|
||||
throw new RuntimeException("Expected module m3 not in the boot layer");
|
||||
}
|
||||
|
||||
if (libPresent) {
|
||||
// p3.Lib must be present
|
||||
LibHelper.concat("x", "y");
|
||||
}
|
||||
}
|
||||
|
||||
static class LibHelper {
|
||||
@Foo
|
||||
static final boolean libClassFound;
|
||||
|
||||
static {
|
||||
boolean found = false;
|
||||
try {
|
||||
Class<?> c = Class.forName("p3.Lib");
|
||||
found = true;
|
||||
} catch (ClassNotFoundException e) {
|
||||
}
|
||||
libClassFound = found;
|
||||
}
|
||||
|
||||
public static String concat(String x, String y) {
|
||||
return Lib.concat(x, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* Copyright (c) 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.
|
||||
*/
|
||||
|
||||
module net.foo {
|
||||
requires jdk.jfr;
|
||||
}
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* Copyright (c) 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.
|
||||
*/
|
||||
|
||||
package net.foo;
|
||||
|
||||
import java.lang.module.ModuleDescriptor;
|
||||
import java.lang.module.ModuleFinder;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* Sanity test if SystemModules pre-resolved at link-time for net.foo
|
||||
* with main class is loaded properly.
|
||||
*/
|
||||
public class Main {
|
||||
public static void main(String... args) throws Exception {
|
||||
ModuleDescriptor md = Main.class.getModule().getDescriptor();
|
||||
System.out.println(md);
|
||||
|
||||
checkMainClass("com.foo", "com.foo.Main");
|
||||
checkMainClass("net.foo", "net.foo.Main");
|
||||
Stream.of("jdk.httpserver", "jdk.jfr").forEach(mn ->
|
||||
ModuleFinder.ofSystem().find(mn).get().descriptor().mainClass()
|
||||
.orElseThrow(() -> new RuntimeException(mn + " no main class"))
|
||||
);
|
||||
}
|
||||
|
||||
static void checkMainClass(String mn, String mainClass) {
|
||||
String cn = ModuleFinder.ofSystem().find(mn).get().descriptor().mainClass().get();
|
||||
if (!cn.equals(mainClass)) {
|
||||
throw new RuntimeException("Mismatched main class of module " + mn + ": " + cn + " expected: " + mainClass);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,102 @@
|
|||
/*
|
||||
* Copyright (c) 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.
|
||||
*/
|
||||
|
||||
package jdk.test;
|
||||
|
||||
import java.lang.module.ModuleDescriptor;
|
||||
import java.net.URI;
|
||||
import java.nio.file.FileSystem;
|
||||
import java.nio.file.FileSystems;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
|
||||
/*
|
||||
* Main class to verify if ModuleDescriptor carries the correct version
|
||||
*/
|
||||
public class Main {
|
||||
static final Map<String, String> nameToVersion = new HashMap<>();
|
||||
|
||||
// jdk.test.Main $count $module-name... $version...
|
||||
public static void main(String... args) throws Exception {
|
||||
int count = args.length > 0 ? Integer.valueOf(args[0]) : 0;
|
||||
if (count < 1 || args.length != count*2+1) {
|
||||
throw new IllegalArgumentException(Arrays.toString(args));
|
||||
}
|
||||
|
||||
List<String> modules = List.of(Arrays.copyOfRange(args, 1, 1+count));
|
||||
List<String> versions = List.of(Arrays.copyOfRange(args, 1+count, args.length));
|
||||
for (int i=0; i < modules.size(); i++) {
|
||||
System.out.format("module %s expects %s version%n",
|
||||
modules.get(i), versions.get(i));
|
||||
nameToVersion.put(modules.get(i), versions.get(i));
|
||||
}
|
||||
|
||||
FileSystem fs = FileSystems.newFileSystem(URI.create("jrt:/"),
|
||||
Collections.emptyMap());
|
||||
// check the module descriptor of a system module
|
||||
for (int i=0; i < modules.size(); i++) {
|
||||
String mn = modules.get(i);
|
||||
Module module = ModuleLayer.boot().findModule(mn).orElseThrow(
|
||||
() -> new RuntimeException(mn + " not found")
|
||||
);
|
||||
|
||||
// check ModuleDescriptor from the run-time
|
||||
validate(module.getDescriptor());
|
||||
|
||||
// check module-info.class in the image
|
||||
Path path = fs.getPath("/", "modules", modules.get(i), "module-info.class");
|
||||
validate(ModuleDescriptor.read(Files.newInputStream(path)));
|
||||
}
|
||||
}
|
||||
|
||||
static void validate(ModuleDescriptor descriptor) {
|
||||
checkVersion(descriptor.name(), descriptor.version());
|
||||
descriptor.requires()
|
||||
.stream()
|
||||
.filter(r -> !r.name().equals("java.base"))
|
||||
.forEach(r -> checkVersion(r.name(), r.compiledVersion()));
|
||||
}
|
||||
|
||||
static void checkVersion(String mn, Optional<ModuleDescriptor.Version> version) {
|
||||
boolean matched;
|
||||
String v = nameToVersion.get(mn);
|
||||
if (version.isPresent()) {
|
||||
matched = version.get().toString().equals(v);
|
||||
} else {
|
||||
// 0 indicate no version
|
||||
matched = v.equals("0");
|
||||
}
|
||||
|
||||
if (!matched) {
|
||||
throw new RuntimeException(mn + " mismatched version " + version
|
||||
+ " expected: " + v);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* Copyright (c) 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.
|
||||
*/
|
||||
|
||||
module test {
|
||||
requires m1;
|
||||
requires m2;
|
||||
exports jdk.test;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue