From 8f0cb57e439df87dee4c0ba7bbff0b981ebc3541 Mon Sep 17 00:00:00 2001 From: Henry Jen Date: Tue, 2 Dec 2025 22:11:38 +0000 Subject: [PATCH] 8347831: Re-examine version check when cross linking Co-authored-by: Magnus Ihse Bursie Reviewed-by: erikj, alanb --- make/modules/java.base/Gensrc.gmk | 22 ++++++ make/modules/java.base/Java.gmk | 2 +- .../misc/resources/release.txt.template | 1 + .../jdk/tools/jlink/internal/JlinkTask.java | 69 +++++++++++++------ .../tools/jlink/resources/jlink.properties | 4 +- 5 files changed, 75 insertions(+), 23 deletions(-) create mode 100644 src/java.base/share/classes/jdk/internal/misc/resources/release.txt.template diff --git a/make/modules/java.base/Gensrc.gmk b/make/modules/java.base/Gensrc.gmk index 79db438934e..e8236f0b0e4 100644 --- a/make/modules/java.base/Gensrc.gmk +++ b/make/modules/java.base/Gensrc.gmk @@ -120,3 +120,25 @@ $(INTPOLY_GEN_DONE): $(INTPLOY_HEADER) $(BUILD_TOOLS_JDK) TARGETS += $(INTPOLY_GEN_DONE) ################################################################################ + +RELEASE_FILE_TEMPLATE := $(TOPDIR)/src/java.base/share/classes/jdk/internal/misc/resources/release.txt.template +RELEASE_FILE_TARGET := $(SUPPORT_OUTPUTDIR)/gensrc/$(MODULE)/jdk/internal/misc/resources/release.txt + +RELEASE_FILE_VARDEPS := $(COMPANY_NAME) $(VERSION_STRING) $(VERSION_DATE) +RELEASE_FILE_VARDEPS_FILE := $(call DependOnVariable, RELEASE_FILE_VARDEPS, \ + $(SUPPORT_OUTPUTDIR)/gensrc/$(MODULE)/jlink_release_txt.vardeps) + +$(eval $(call SetupTextFileProcessing, BUILD_RELEASE_FILE, \ + SOURCE_FILES := $(RELEASE_FILE_TEMPLATE), \ + OUTPUT_FILE := $(RELEASE_FILE_TARGET), \ + REPLACEMENTS := \ + @@COMPANY_NAME@@ => $(COMPANY_NAME) ; \ + @@VERSION_STRING@@ => $(VERSION_STRING) ; \ + @@VERSION_DATE@@ => $(VERSION_DATE) , \ +)) + +$(BUILD_RELEASE_FILE): $(RELEASE_FILE_VARDEPS_FILE) + +TARGETS += $(BUILD_RELEASE_FILE) + +################################################################################ diff --git a/make/modules/java.base/Java.gmk b/make/modules/java.base/Java.gmk index fc091377456..e20db38297d 100644 --- a/make/modules/java.base/Java.gmk +++ b/make/modules/java.base/Java.gmk @@ -34,7 +34,7 @@ DOCLINT += -Xdoclint:all/protected \ '-Xdoclint/package:java.*,javax.*' JAVAC_FLAGS += -XDstringConcat=inline -COPY += .icu .dat .spp .nrm content-types.properties \ +COPY += .icu .dat .spp .nrm .txt content-types.properties \ hijrah-config-Hijrah-umalqura_islamic-umalqura.properties CLEAN += intrinsic.properties diff --git a/src/java.base/share/classes/jdk/internal/misc/resources/release.txt.template b/src/java.base/share/classes/jdk/internal/misc/resources/release.txt.template new file mode 100644 index 00000000000..2d46f8f0e60 --- /dev/null +++ b/src/java.base/share/classes/jdk/internal/misc/resources/release.txt.template @@ -0,0 +1 @@ +@@COMPANY_NAME@@-@@VERSION_STRING@@-@@VERSION_DATE@@ diff --git a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/JlinkTask.java b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/JlinkTask.java index 928b9a47934..03b9611c179 100644 --- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/JlinkTask.java +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/JlinkTask.java @@ -27,9 +27,11 @@ package jdk.tools.jlink.internal; import static jdk.tools.jlink.internal.TaskHelper.JLINK_BUNDLE; import java.io.BufferedInputStream; +import java.io.BufferedReader; import java.io.File; import java.io.IOException; import java.io.InputStream; +import java.io.InputStreamReader; import java.io.PrintWriter; import java.io.UncheckedIOException; import java.lang.module.Configuration; @@ -56,6 +58,7 @@ import java.util.HashSet; import java.util.List; import java.util.Locale; import java.util.Map; +import java.util.NoSuchElementException; import java.util.Objects; import java.util.Optional; import java.util.Set; @@ -238,6 +241,27 @@ public class JlinkTask { } public static final String OPTIONS_RESOURCE = "jdk/tools/jlink/internal/options"; + // Release information stored in the java.base module + private static final String JDK_RELEASE_RESOURCE = "jdk/internal/misc/resources/release.txt"; + + /** + * Read the release.txt from the module. + */ + private static Optional getReleaseInfo(ModuleReference mref) { + try { + Optional release = mref.open().open(JDK_RELEASE_RESOURCE); + + if (release.isEmpty()) { + return Optional.empty(); + } + + try (var r = new BufferedReader(new InputStreamReader(release.get()))) { + return Optional.of(r.readLine()); + } + } catch (IOException ioe) { + throw new UncheckedIOException(ioe); + } + } int run(String[] args) { if (log == null) { @@ -410,7 +434,8 @@ public class JlinkTask { // Sanity check version if we use JMODs if (!isLinkFromRuntime) { - checkJavaBaseVersion(finder); + assert(finder.find("java.base").isPresent()); + checkJavaBaseVersion(finder.find("java.base").get()); } // Determine the roots set @@ -561,32 +586,34 @@ public class JlinkTask { return finder; } + private static String getCurrentRuntimeVersion() { + ModuleReference current = ModuleLayer.boot() + .configuration() + .findModule("java.base") + .get() + .reference(); + // This jlink runtime should always have the release.txt + return getReleaseInfo(current).get(); + } + /* - * Checks the version of the module descriptor of java.base for compatibility - * with the current runtime version. + * Checks the release information of the java.base used for target image + * for compatibility with the java.base used by jlink. * - * @throws IllegalArgumentException the descriptor of java.base has no - * version or the java.base version is not the same as the current runtime's - * version. + * @throws IllegalArgumentException If the `java.base` module reference `target` + * is not compatible with this jlink. */ - private static void checkJavaBaseVersion(ModuleFinder finder) { - assert finder.find("java.base").isPresent(); + private static void checkJavaBaseVersion(ModuleReference target) { + String currentRelease = getCurrentRuntimeVersion(); - // use the version of java.base module, if present, as - // the release version for multi-release JAR files - ModuleDescriptor.Version v = finder.find("java.base").get() - .descriptor().version().orElseThrow(() -> - new IllegalArgumentException("No version in java.base descriptor") - ); + String targetRelease = getReleaseInfo(target).orElseThrow(() -> new IllegalArgumentException( + taskHelper.getMessage("err.jlink.version.missing", currentRelease))); - Runtime.Version version = Runtime.Version.parse(v.toString()); - if (Runtime.version().feature() != version.feature() || - Runtime.version().interim() != version.interim()) { - // jlink version and java.base version do not match. - // We do not (yet) support this mode. + if (!currentRelease.equals(targetRelease)) { + // Current runtime image and the target runtime image are not compatible build throw new IllegalArgumentException(taskHelper.getMessage("err.jlink.version.mismatch", - Runtime.version().feature(), Runtime.version().interim(), - version.feature(), version.interim())); + currentRelease, + targetRelease)); } } diff --git a/src/jdk.jlink/share/classes/jdk/tools/jlink/resources/jlink.properties b/src/jdk.jlink/share/classes/jdk/tools/jlink/resources/jlink.properties index 080d51506a6..374ed78f608 100644 --- a/src/jdk.jlink/share/classes/jdk/tools/jlink/resources/jlink.properties +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/resources/jlink.properties @@ -130,7 +130,9 @@ err.runtime.link.patched.module=jlink does not support linking from the run-time err.no.module.path=--module-path option must be specified with --add-modules ALL-MODULE-PATH err.empty.module.path=No module found in module path ''{0}'' with --add-modules ALL-MODULE-PATH err.limit.modules=--limit-modules not allowed with --add-modules ALL-MODULE-PATH -err.jlink.version.mismatch=jlink version {0}.{1} does not match target java.base version {2}.{3} +err.jlink.version.mismatch=jlink build ''{0}'' does not match target java.base build ''{1}'' +err.jlink.version.missing=jlink build ''{0}'' cannot find the build signature\ +\ in the java.base specified on module path, likely from an earlier build. err.automatic.module:automatic module cannot be used with jlink: {0} from {1} err.unknown.byte.order:unknown byte order {0} err.launcher.main.class.empty:launcher main class name cannot be empty: {0}