8347831: Re-examine version check when cross linking

Co-authored-by: Magnus Ihse Bursie <ihse@openjdk.org>
Reviewed-by: erikj, alanb
This commit is contained in:
Henry Jen 2025-12-02 22:11:38 +00:00
parent 37cd8d6ca0
commit 8f0cb57e43
5 changed files with 75 additions and 23 deletions

View File

@ -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)
################################################################################

View File

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

View File

@ -0,0 +1 @@
@@COMPANY_NAME@@-@@VERSION_STRING@@-@@VERSION_DATE@@

View File

@ -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<String> getReleaseInfo(ModuleReference mref) {
try {
Optional<InputStream> 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));
}
}

View File

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