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:
russell@unturf.com 2026-03-26 17:11:57 -04:00
commit 0a580b313d
70422 changed files with 17213626 additions and 0 deletions

View file

@ -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);
}
}

View file

@ -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);
}
}

View file

@ -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();
}
}
}

View file

@ -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");
}
}
}

View file

@ -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);
}
}

View file

@ -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);
}
}
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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);
}
}
}

View file

@ -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() { }
}

View file

@ -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;
}

View file

@ -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();
}

View file

@ -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();
}

View file

@ -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;
}

View file

@ -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 {
}

View 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 p3;
public class Lib {
public static String concat(String x, String y) {
return x + y;
}
}

View file

@ -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());
}
}
}

View file

@ -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;
}

View file

@ -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);
}
}

View file

@ -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));
}
}
}

View 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 m5 {
requires static m3;
exports p5;
}

View file

@ -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);
}
}
}

View file

@ -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;
}

View file

@ -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);
}
}
}

View file

@ -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);
}
}
}

View file

@ -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;
}