diff --git a/src/jdk.jartool/share/classes/sun/tools/jar/FingerPrint.java b/src/jdk.jartool/share/classes/sun/tools/jar/FingerPrint.java index beb97ae5fd8..a703b8b69c1 100644 --- a/src/jdk.jartool/share/classes/sun/tools/jar/FingerPrint.java +++ b/src/jdk.jartool/share/classes/sun/tools/jar/FingerPrint.java @@ -131,6 +131,14 @@ final class FingerPrint { return attrs.name; } + public int classMajorVersion() { + return attrs.majorVersion; // ..., 53, 54, ... + } + + public int classReleaseVersion() { + return attrs.majorVersion - 44; // ..., 53 -> 9, 54 -> 10, ... + } + public int mrversion() { return mrversion; } diff --git a/src/jdk.jartool/share/classes/sun/tools/jar/Main.java b/src/jdk.jartool/share/classes/sun/tools/jar/Main.java index 132c73b6084..111bb7ce13b 100644 --- a/src/jdk.jartool/share/classes/sun/tools/jar/Main.java +++ b/src/jdk.jartool/share/classes/sun/tools/jar/Main.java @@ -209,18 +209,8 @@ public class Main { } } - static String formatMsg(String key, String arg) { + static String formatMsg(String key, String... args) { String msg = getMsg(key); - String[] args = new String[1]; - args[0] = arg; - return MessageFormat.format(msg, (Object[]) args); - } - - static String formatMsg2(String key, String arg, String arg1) { - String msg = getMsg(key); - String[] args = new String[2]; - args[0] = arg; - args[1] = arg1; return MessageFormat.format(msg, (Object[]) args); } @@ -458,7 +448,7 @@ public class Main { try (ZipFile zf = new ZipFile(file)) { return Validator.validate(this, zf); } catch (IOException e) { - error(formatMsg2("error.validator.jarfile.exception", fname, e.getMessage())); + error(formatMsg("error.validator.jarfile.exception", fname, e.getMessage())); return true; } } @@ -839,7 +829,7 @@ public class Main { // the entry starts with VERSIONS_DIR and version != BASE_VERSION, // which means the "[dirs|files]" in --release v [dirs|files] // includes VERSIONS_DIR-ed entries --> warning and skip (?) - error(formatMsg2("error.release.unexpected.versioned.entry", + error(formatMsg("error.release.unexpected.versioned.entry", name, String.valueOf(version))); ok = false; return; @@ -1263,8 +1253,7 @@ public class Main { if (vflag) { size = e.getSize(); long csize = e.getCompressedSize(); - out.print(formatMsg2("out.size", String.valueOf(size), - String.valueOf(csize))); + out.print(formatMsg("out.size", String.valueOf(size), String.valueOf(csize))); if (e.getMethod() == ZipEntry.DEFLATED) { long ratio = 0; if (size != 0) { diff --git a/src/jdk.jartool/share/classes/sun/tools/jar/Validator.java b/src/jdk.jartool/share/classes/sun/tools/jar/Validator.java index 4201039ca78..3bb5e9a2a5e 100644 --- a/src/jdk.jartool/share/classes/sun/tools/jar/Validator.java +++ b/src/jdk.jartool/share/classes/sun/tools/jar/Validator.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 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 @@ -51,7 +51,6 @@ import static sun.tools.jar.Main.VERSIONS_DIR_LENGTH; import static sun.tools.jar.Main.MODULE_INFO; import static sun.tools.jar.Main.getMsg; import static sun.tools.jar.Main.formatMsg; -import static sun.tools.jar.Main.formatMsg2; import static sun.tools.jar.Main.toBinaryName; final class Validator { @@ -164,7 +163,15 @@ final class Validator { public void validateVersioned(Map fps) { fps.values().forEach( fp -> { - + // all versioned entries must be compatible with their release target number + if (fp.mrversion() < fp.classReleaseVersion()) { + errorAndInvalid(formatMsg("error.release.value.toohigh.versioned.entry", + fp.entryName(), // META-INF/versions/9/com/foo/Bar.class has class file version + String.valueOf(fp.classMajorVersion()), // 69, but class file version + String.valueOf(fp.mrversion() + 44), // 53 or less is required to target release + String.valueOf(fp.mrversion()))); // 9 of the Java Platform + return; + } // validate the versioned module-info if (MODULE_INFO.equals(fp.basename())) { checkModuleDescriptor(fp.entryName()); @@ -310,7 +317,7 @@ final class Validator { if (fp.className().equals(className(fp.basename()))) { return true; } - error(formatMsg2("error.validator.names.mismatch", + error(formatMsg("error.validator.names.mismatch", fp.entryName(), fp.className().replace("/", "."))); return isValid = false; } diff --git a/src/jdk.jartool/share/classes/sun/tools/jar/resources/jar.properties b/src/jdk.jartool/share/classes/sun/tools/jar/resources/jar.properties index 51e4299abc6..676c16c445a 100644 --- a/src/jdk.jartool/share/classes/sun/tools/jar/resources/jar.properties +++ b/src/jdk.jartool/share/classes/sun/tools/jar/resources/jar.properties @@ -90,6 +90,8 @@ error.release.value.toosmall=\ release {0} not valid, must be >= 9 error.release.unexpected.versioned.entry=\ unexpected versioned entry {0} for release {1} +error.release.value.toohigh.versioned.entry=\ + {0} has class file version {1}, but class file version {2} or less is required to target release {3} of the Java Platform error.date.notvalid=\ date {0} is not a valid ISO-8601 extended offset date-time with optional time-zone error.date.out.of.range=\ diff --git a/test/jdk/sun/security/tools/jarsigner/multiRelease/MVJarSigningTest.java b/test/jdk/sun/security/tools/jarsigner/multiRelease/MVJarSigningTest.java index e87c147ab16..06d096de18a 100644 --- a/test/jdk/sun/security/tools/jarsigner/multiRelease/MVJarSigningTest.java +++ b/test/jdk/sun/security/tools/jarsigner/multiRelease/MVJarSigningTest.java @@ -125,15 +125,15 @@ public class MVJarSigningTest { private static void compile (String jarContent_path) throws Throwable { Path classes = Paths.get(USR_DIR, "classes", "base"); Path source = Paths.get(TEST_SRC, jarContent_path, "base", "version"); - CompilerUtils.compile(source, classes); + CompilerUtils.compile(source, classes, "--release", "8"); classes = Paths.get(USR_DIR, "classes", "v9"); source = Paths.get(TEST_SRC, jarContent_path , "v9", "version"); - CompilerUtils.compile(source, classes); + CompilerUtils.compile(source, classes, "--release", "9"); classes = Paths.get(USR_DIR, "classes", "v10"); source = Paths.get(TEST_SRC, jarContent_path, "v10", "version"); - CompilerUtils.compile(source, classes); + CompilerUtils.compile(source, classes, "--release", "10"); } private static OutputAnalyzer jar(String...args) throws Throwable { diff --git a/test/jdk/tools/jar/mmrjar/Basic.java b/test/jdk/tools/jar/mmrjar/Basic.java index 14c11edd47a..4d1d56f7c7a 100644 --- a/test/jdk/tools/jar/mmrjar/Basic.java +++ b/test/jdk/tools/jar/mmrjar/Basic.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -49,6 +49,7 @@ import java.lang.module.ModuleDescriptor.Version; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; +import java.util.ArrayList; import java.util.Arrays; import java.util.Optional; import java.util.Set; @@ -80,25 +81,28 @@ public class Basic { // compile the classes directory Path source = testsrc.resolve("src").resolve("classes"); Path destination = Paths.get("classes"); - javac(source, destination); + javac(source, destination, 8); // compile the mr9 directory including module-info.java source = testsrc.resolve("src").resolve("mr9"); destination = Paths.get("mr9"); - javac(source, destination); + javac(source, destination, 9); // move module-info.class for later use Files.move(destination.resolve("module-info.class"), Paths.get("module-info.class")); } - private void javac(Path source, Path destination) throws IOException { - String[] args = Stream.concat( - Stream.of("-d", destination.toString()), - Files.walk(source) - .map(Path::toString) - .filter(s -> s.endsWith(".java")) - ).toArray(String[]::new); + private void javac(Path source, Path destination, int release) throws IOException { + ArrayList arguments = new ArrayList(); + arguments.add("-d"); + arguments.add(destination); + arguments.add("--release"); + arguments.add(release); + try (var stream = Files.walk(source)) { + stream.map(Path::toString).filter(s -> s.endsWith(".java")).forEach(arguments::add); + } + String[] args = arguments.stream().map(Object::toString).toArray(String[]::new); JAVAC_TOOL.run(System.out, System.err, args); } @@ -110,8 +114,8 @@ public class Basic { @AfterClass public void cleanup() throws IOException { - Files.walk(userdir, 1) - .filter(p -> !p.equals(userdir)) + try (var stream = Files.walk(userdir, 1)) { + stream.filter(p -> !p.equals(userdir)) .forEach(p -> { try { if (Files.isDirectory(p)) { @@ -123,6 +127,7 @@ public class Basic { throw new UncheckedIOException(x); } }); + } } // updates a valid multi-release jar with a new public class in @@ -229,7 +234,7 @@ public class Basic { // compile the mr10 directory Path source = testsrc.resolve("src").resolve("mr10"); Path destination = Paths.get("mr10"); - javac(source, destination); + javac(source, destination, 10); // create a directory for this tests special files Files.createDirectory(Paths.get("test5")); @@ -240,7 +245,7 @@ public class Basic { Files.write(modinfo, hi.getBytes()); // and compile it - javac(modinfo, Paths.get("test5")); + javac(modinfo, Paths.get("test5"), 9); int rc = jar("--create --file mr.jar -C classes ."); Assert.assertEquals(rc, 0); @@ -335,7 +340,7 @@ public class Basic { // compile the classes directory Path src = testsrc.resolve("src").resolve("classes"); Path dst = Paths.get("test6"); - javac(src, dst); + javac(src, dst, 8); byte[] mdBytes = Files.readAllBytes(Paths.get("module-info.class")); @@ -397,7 +402,7 @@ public class Basic { // compile the classes directory Path src = testsrc.resolve("src").resolve("classes"); Path dst = Paths.get("test7"); - javac(src, dst); + javac(src, dst, 8); // move module-info.class to v9 later use Files.copy(Paths.get("module-info.class"), diff --git a/test/jdk/tools/jar/multiRelease/ApiValidatorTest.java b/test/jdk/tools/jar/multiRelease/ApiValidatorTest.java index 9b10540df85..b8c71305146 100644 --- a/test/jdk/tools/jar/multiRelease/ApiValidatorTest.java +++ b/test/jdk/tools/jar/multiRelease/ApiValidatorTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 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 @@ -82,8 +82,8 @@ public class ApiValidatorTest extends MRTestBase { String base = classTemplate.replace(METHOD_SIG, sigBase); String v10 = classTemplate.replace(METHOD_SIG, sigV10); - compileTemplate(classes.resolve("base"), base); - compileTemplate(classes.resolve("v10"), v10); + compileTemplate(8, classes.resolve("base"), base); + compileTemplate(10, classes.resolve("v10"), v10); String jarfile = root.resolve("test.jar").toString(); OutputAnalyzer result = jar("cf", jarfile, @@ -135,8 +135,8 @@ public class ApiValidatorTest extends MRTestBase { String base = classTemplate.replace(API, ""); String v10 = classTemplate.replace(API, publicAPI); - compileTemplate(classes.resolve("base"), base); - compileTemplate(classes.resolve("v10"), v10); + compileTemplate(8, classes.resolve("base"), base); + compileTemplate(10, classes.resolve("v10"), v10); String failureMessage = "contains a class with different api from earlier version"; @@ -176,8 +176,8 @@ public class ApiValidatorTest extends MRTestBase { String base = classTemplate.replace(API, ""); String v10 = classTemplate.replace(API, privateAPI); - compileTemplate(classes.resolve("base"), base); - compileTemplate(classes.resolve("v10"), v10); + compileTemplate(8, classes.resolve("base"), base); + compileTemplate(10, classes.resolve("v10"), v10); String jarfile = root.resolve("test.jar").toString(); jar("cf", jarfile, "-C", classes.resolve("base").toString(), ".", @@ -208,12 +208,12 @@ public class ApiValidatorTest extends MRTestBase { }; } - private void compileTemplate(Path classes, String template) throws Throwable { + private void compileTemplate(int release, Path classes, String template) throws Throwable { Path classSourceFile = Files.createDirectories( classes.getParent().resolve("src").resolve(classes.getFileName())) .resolve("C.java"); Files.write(classSourceFile, template.getBytes()); - javac(classes, classSourceFile); + javac(release, classes, classSourceFile); } /* Modular multi-release checks */ @@ -452,7 +452,7 @@ public class ApiValidatorTest extends MRTestBase { sourceFiles[i + 1] = sourceFile; } - javac(classes, sourceFiles); + javac(9, classes, sourceFiles); } @SafeVarargs diff --git a/test/jdk/tools/jar/multiRelease/Basic.java b/test/jdk/tools/jar/multiRelease/Basic.java index ffde4849d1f..e826de71f32 100644 --- a/test/jdk/tools/jar/multiRelease/Basic.java +++ b/test/jdk/tools/jar/multiRelease/Basic.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ /* * @test - # @bug 8186087 8196748 8212807 + # @bug 8186087 8196748 8212807 8268611 * @library /test/lib * @modules java.base/jdk.internal.misc * jdk.compiler @@ -126,9 +126,9 @@ public class Basic extends MRTestBase { Path classes = Paths.get("classes"); // valid - for (String release : List.of("10000", "09", "00010", "10")) { + for (String release : List.of("09", "00010", "10")) { jarTool("cf", jarfile, "-C", classes.resolve("base").toString(), ".", - "--release", release, "-C", classes.resolve("v10").toString(), ".") + "--release", release, "-C", classes.resolve("v9").toString(), ".") .shouldHaveExitValue(SUCCESS) .shouldBeEmptyIgnoreVMWarnings(); } @@ -207,26 +207,16 @@ public class Basic extends MRTestBase { compare(jarfile, names); + // 8268611: The following creates an invalid JAR, which gets deleted. // write the v9 version/Version.class entry in base and the v10 // version/Version.class entry in versions/9 section jarTool("uf", jarfile, "-C", classes.resolve("v9").toString(), "version", "--release", "9", "-C", classes.resolve("v10").toString(), ".") - .shouldHaveExitValue(SUCCESS); - - checkMultiRelease(jarfile, true); - - names = Map.of( - "version/Main.class", - new String[]{"base", "version", "Main.class"}, - - "version/Version.class", - new String[]{"v9", "version", "Version.class"}, - - "META-INF/versions/9/version/Version.class", - new String[]{"v10", "version", "Version.class"} - ); - - compare(jarfile, names); + .shouldNotHaveExitValue(SUCCESS) + .shouldContain("META-INF/versions/9/version/Version.class") + .shouldContain(" has class file version 54,") + .shouldContain(" but class file version 53 or less is required") + .shouldContain(" to target release 9 of the Java Platform"); FileUtils.deleteFileIfExistsWithRetry(Paths.get(jarfile)); FileUtils.deleteFileTreeWithRetry(Paths.get(usr, "classes")); @@ -247,7 +237,7 @@ public class Basic extends MRTestBase { // replace the v9 class Path source = Paths.get(src, "data", "test04", "v9", "version"); - javac(classes.resolve("v9"), source.resolve("Version.java")); + javac(9, classes.resolve("v9"), source.resolve("Version.java")); jarTool("cf", jarfile, "-C", classes.resolve("base").toString(), ".", "--release", "9", "-C", classes.resolve("v9").toString(), ".") @@ -269,7 +259,7 @@ public class Basic extends MRTestBase { // add the new v9 class Path source = Paths.get(src, "data", "test05", "v9", "version"); - javac(classes.resolve("v9"), source.resolve("Extra.java")); + javac(9, classes.resolve("v9"), source.resolve("Extra.java")); jarTool("cf", jarfile, "-C", classes.resolve("base").toString(), ".", "--release", "9", "-C", classes.resolve("v9").toString(), ".") @@ -291,7 +281,7 @@ public class Basic extends MRTestBase { // add the new v9 class Path source = Paths.get(src, "data", "test06", "v9", "version"); - javac(classes.resolve("v9"), source.resolve("Extra.java")); + javac(9, classes.resolve("v9"), source.resolve("Extra.java")); jarTool("cf", jarfile, "-C", classes.resolve("base").toString(), ".", "--release", "9", "-C", classes.resolve("v9").toString(), ".") @@ -313,7 +303,7 @@ public class Basic extends MRTestBase { // add the new v9 class Path source = Paths.get(src, "data", "test01", "base", "version"); - javac(classes.resolve("v9"), source.resolve("Version.java")); + javac(9, classes.resolve("v9"), source.resolve("Version.java")); jarTool("cf", jarfile, "-C", classes.resolve("base").toString(), ".", "--release", "9", "-C", classes.resolve("v9").toString(), ".") @@ -382,11 +372,11 @@ public class Basic extends MRTestBase { // add a base class with a nested class Path source = Paths.get(src, "data", "test10", "base", "version"); - javac(classes.resolve("base"), source.resolve("Nested.java")); + javac(8, classes.resolve("base"), source.resolve("Nested.java")); // add a versioned class with a nested class source = Paths.get(src, "data", "test10", "v9", "version"); - javac(classes.resolve("v9"), source.resolve("Nested.java")); + javac(9, classes.resolve("v9"), source.resolve("Nested.java")); jarTool("cf", jarfile, "-C", classes.resolve("base").toString(), ".", "--release", "9", "-C", classes.resolve("v9").toString(), ".") @@ -407,14 +397,14 @@ public class Basic extends MRTestBase { // add a base class with a nested class Path source = Paths.get(src, "data", "test10", "base", "version"); - javac(classes.resolve("base"), source.resolve("Nested.java")); + javac(8, classes.resolve("base"), source.resolve("Nested.java")); // remove the top level class, thus isolating the nested class Files.delete(classes.resolve("base").resolve("version").resolve("Nested.class")); // add a versioned class with a nested class source = Paths.get(src, "data", "test10", "v9", "version"); - javac(classes.resolve("v9"), source.resolve("Nested.java")); + javac(9, classes.resolve("v9"), source.resolve("Nested.java")); List output = jarTool("cf", jarfile, "-C", classes.resolve("base").toString(), ".", @@ -460,11 +450,11 @@ public class Basic extends MRTestBase { // add a base class with a nested class Path source = Paths.get(src, "data", "test10", "base", "version"); - javac(classes.resolve("base"), source.resolve("Nested.java")); + javac(8, classes.resolve("base"), source.resolve("Nested.java")); // add a versioned class with a nested class source = Paths.get(src, "data", "test10", "v9", "version"); - javac(classes.resolve("v9"), source.resolve("Nested.java")); + javac(9, classes.resolve("v9"), source.resolve("Nested.java")); // remove the top level class, thus isolating the nested class Files.delete(classes.resolve("v9").resolve("version").resolve("Nested.class")); @@ -489,11 +479,11 @@ public class Basic extends MRTestBase { // add a base class with a nested and nested-nested class Path source = Paths.get(src, "data", "test13", "base", "version"); - javac(classes.resolve("base"), source.resolve("Nested.java")); + javac(8, classes.resolve("base"), source.resolve("Nested.java")); // add a versioned class with a nested and nested-nested class source = Paths.get(src, "data", "test13", "v10", "version"); - javac(classes.resolve("v10"), source.resolve("Nested.java")); + javac(10, classes.resolve("v10"), source.resolve("Nested.java")); jarTool("cf", jarfile, "-C", classes.resolve("base").toString(), ".", "--release", "10", "-C", classes.resolve("v10").toString(), ".") @@ -535,7 +525,7 @@ public class Basic extends MRTestBase { jar("ufm", jarfile, manifest.toString(), "-C", classes.resolve("base").toString(), ".", - "--release", "9", "-C", classes.resolve("v10").toString(), ".") + "--release", "9", "-C", classes.resolve("v9").toString(), ".") .shouldHaveExitValue(SUCCESS) .shouldContain("WARNING: Duplicate name in Manifest: Multi-release."); diff --git a/test/jdk/tools/jar/multiRelease/Basic1.java b/test/jdk/tools/jar/multiRelease/Basic1.java index 9f86eb029cd..1312d890a5f 100644 --- a/test/jdk/tools/jar/multiRelease/Basic1.java +++ b/test/jdk/tools/jar/multiRelease/Basic1.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -52,22 +52,22 @@ public class Basic1 extends MRTestBase { Path base = classes.resolve("base"); Files.createDirectories(base); Path source = Paths.get(src, "data", test, "base", "version"); - javac(base, source.resolve("Main.java"), source.resolve("Version.java")); + javac(8, base, source.resolve("Main.java"), source.resolve("Version.java")); Path v9 = classes.resolve("v9"); Files.createDirectories(v9); source = Paths.get(src, "data", test, "v9", "version"); - javac(v9, source.resolve("Version.java")); + javac(9, v9, source.resolve("Version.java")); Path v10 = classes.resolve("v10"); Files.createDirectories(v10); source = Paths.get(src, "data", test, "v10", "version"); - javac(v10, source.resolve("Version.java")); + javac(10, v10, source.resolve("Version.java")); Path v10_1 = classes.resolve("v10_1").resolve("META-INF").resolve("versions").resolve("v10"); Files.createDirectories(v10_1); source = Paths.get(src, "data", test, "v10", "version"); - javac(v10_1, source.resolve("Version.java")); + javac(10, v10_1, source.resolve("Version.java")); } @Test diff --git a/test/jdk/tools/jar/multiRelease/MRTestBase.java b/test/jdk/tools/jar/multiRelease/MRTestBase.java index 1a4d2f00e51..3bb9285fd4a 100644 --- a/test/jdk/tools/jar/multiRelease/MRTestBase.java +++ b/test/jdk/tools/jar/multiRelease/MRTestBase.java @@ -62,17 +62,17 @@ public class MRTestBase { Path classes = Paths.get(usr, "classes", "base"); Files.createDirectories(classes); Path source = Paths.get(src, "data", test, "base", "version"); - javac(classes, source.resolve("Main.java"), source.resolve("Version.java")); + javac(8, classes, source.resolve("Main.java"), source.resolve("Version.java")); classes = Paths.get(usr, "classes", "v9"); Files.createDirectories(classes); source = Paths.get(src, "data", test, "v9", "version"); - javac(classes, source.resolve("Version.java")); + javac(9, classes, source.resolve("Version.java")); classes = Paths.get(usr, "classes", "v10"); Files.createDirectories(classes); source = Paths.get(src, "data", test, "v10", "version"); - javac(classes, source.resolve("Version.java")); + javac(10, classes, source.resolve("Version.java")); } protected void checkMultiRelease(String jarFile, @@ -101,23 +101,17 @@ public class MRTestBase { } } - void javac(Path dest, Path... sourceFiles) throws Throwable { - javac(dest, List.of(), sourceFiles); - } - - void javac(Path dest, List extraParameters, Path... sourceFiles) throws Throwable { - + void javac(int release, Path dest, Path... sourceFiles) throws Throwable { List commands = new ArrayList<>(); String opts = System.getProperty("test.compiler.opts"); if (!opts.isEmpty()) { commands.addAll(Arrays.asList(opts.split(" +"))); } + commands.add("--release"); + commands.add(String.valueOf(release)); commands.add("-d"); commands.add(dest.toString()); - Stream.of(sourceFiles) - .map(Object::toString) - .forEach(x -> commands.add(x)); - commands.addAll(extraParameters); + Stream.of(sourceFiles).map(Object::toString).forEach(commands::add); StringWriter sw = new StringWriter(); try (PrintWriter pw = new PrintWriter(sw)) { diff --git a/test/jdk/tools/jar/multiRelease/VersionValidatorTest.java b/test/jdk/tools/jar/multiRelease/VersionValidatorTest.java index 6e285e20c90..f8dacb1d8dc 100644 --- a/test/jdk/tools/jar/multiRelease/VersionValidatorTest.java +++ b/test/jdk/tools/jar/multiRelease/VersionValidatorTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 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 @@ -88,7 +88,7 @@ public class VersionValidatorTest extends MRTestBase { Path classesDir = root.resolve("classes").resolve(majorVersion); - javac(classesDir, List.of("--release", majorVersion), sourceFile); + javac(Integer.parseInt(majorVersion), classesDir, sourceFile); if (enablePreview) { rewriteMinorVersionForEnablePreviewClass(classesDir.resolve("Lib.class")); } diff --git a/test/langtools/tools/jdeps/MultiReleaseJar.java b/test/langtools/tools/jdeps/MultiReleaseJar.java index 8ba642083f1..ffc5ee874ec 100644 --- a/test/langtools/tools/jdeps/MultiReleaseJar.java +++ b/test/langtools/tools/jdeps/MultiReleaseJar.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,6 @@ * @test * @bug 8153654 8176333 * @summary Tests for jdeps tool with multi-release jar files - * @modules jdk.jdeps/com.sun.tools.jdeps * @library mrjar mrjar/base mrjar/9 mrjar/10 mrjar/v9 mrjar/v10 * @build test.* p.* q.* foo/* Main * @run testng MultiReleaseJar @@ -38,6 +37,7 @@ import org.testng.annotations.Test; import java.io.File; import java.io.InputStream; +import java.io.RandomAccessFile; import java.nio.file.Path; import java.nio.file.Paths; import java.util.stream.Stream; @@ -60,6 +60,15 @@ public class MultiReleaseJar { fileSep = System.getProperty("file.separator"); cmdPath = Paths.get(testJdk, "bin"); + // fixup classfile versions + forceReleaseInClassFile(9, "Main.class"); + forceReleaseInClassFile(9, "base/test/Version.class", "base/p/Foo.class"); + forceReleaseInClassFile(9, "9/test/NonPublic.class", "9/test/Version.class"); + forceReleaseInClassFile(9, "v9/p/Foo.class", "v9/q/Bar.class"); + forceReleaseInClassFile(9, "v9/p/Foo.class", "v9/q/Bar.class"); + forceReleaseInClassFile(10, "10/test/Version.class"); + forceReleaseInClassFile(10, "v10/q/Bar.class", "v10/q/Gee.class"); + // build Version.jar, Version_9.jar and main.jar Result r = run("jar -cf Version.jar -C base test --release 9 -C 9 test --release 10 -C 10 test"); checkResult(r); @@ -74,10 +83,22 @@ public class MultiReleaseJar { checkResult(r); Path foo = Paths.get(System.getProperty("test.classes")).resolve("modules").resolve("foo"); + forceReleaseInClassFile(9, foo.resolve("module-info.class")); r = run("jar -uf Foo.jar --release 9 -C " + foo.toString() + " module-info.class --release 10 -C v10 q"); checkResult(r); } + private void forceReleaseInClassFile(int release, Object... paths) { + for (var path : paths) { + try (var file = new RandomAccessFile(mrjar.resolve(path.toString()).toFile(), "rw")) { + file.seek(4 + 2); // skip magic and minor + file.writeShort(release + 44); // overwrite major + } catch (Exception exception) { + throw new RuntimeException(exception); + } + } + } + @Test public void basic() throws Exception { Result r = run("jdeps -J-Duser.language=en -J-Duser.country=US --multi-release 9 -v missing.jar"); diff --git a/test/langtools/tools/jdeps/missingDeps/MissingDepsTest.java b/test/langtools/tools/jdeps/missingDeps/MissingDepsTest.java index edd3f3f5787..4a2e47426f2 100644 --- a/test/langtools/tools/jdeps/missingDeps/MissingDepsTest.java +++ b/test/langtools/tools/jdeps/missingDeps/MissingDepsTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 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 @@ -55,7 +55,7 @@ public class MissingDepsTest { private static final Path CLASSES_DIR = Paths.get("classes"); private static final ToolProvider JAR_TOOL = ToolProvider.findFirst("jar").orElseThrow(); - private static final String VERSION = "13"; + private static final String VERSION = String.valueOf(Runtime.version().feature()); private static final Set modules = Set.of("m1", "m2"); @@ -122,7 +122,7 @@ public class MissingDepsTest { JdepsRunner jdepsRunner = new JdepsRunner(options.toArray(new String[0])); int rc = jdepsRunner.run(DEBUG); assertTrue(rc != 0); - String regex = "\\s+13/p.internal.X\\s+->\\s+q.T\\s+not found"; + String regex = "\\s+" + VERSION + "/p.internal.X\\s+->\\s+q.T\\s+not found"; assertTrue(Arrays.stream(jdepsRunner.output()).anyMatch(l -> l.matches(regex))); } diff --git a/test/langtools/tools/jdeps/multiVersion/MultiVersionError.java b/test/langtools/tools/jdeps/multiVersion/MultiVersionError.java index 62513406b71..bcb69f27aa7 100644 --- a/test/langtools/tools/jdeps/multiVersion/MultiVersionError.java +++ b/test/langtools/tools/jdeps/multiVersion/MultiVersionError.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 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 @@ -56,7 +56,7 @@ public class MultiVersionError { public void compileAll() throws Exception { CompilerUtils.cleanDir(MODS_DIR); modules.forEach(mn -> - assertTrue(CompilerUtils.compileModule(SRC_DIR, MODS_DIR, mn))); + assertTrue(CompilerUtils.compileModule(SRC_DIR, MODS_DIR, mn, "--release", "9"))); // create a modular multi-release m1.jar Path m1 = MODS_DIR.resolve("m1");