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) 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 \ DOCLINT += -Xdoclint:all/protected \
'-Xdoclint/package:java.*,javax.*' '-Xdoclint/package:java.*,javax.*'
JAVAC_FLAGS += -XDstringConcat=inline 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 hijrah-config-Hijrah-umalqura_islamic-umalqura.properties
CLEAN += intrinsic.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 static jdk.tools.jlink.internal.TaskHelper.JLINK_BUNDLE;
import java.io.BufferedInputStream; import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.io.UncheckedIOException; import java.io.UncheckedIOException;
import java.lang.module.Configuration; import java.lang.module.Configuration;
@ -56,6 +58,7 @@ import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Objects; import java.util.Objects;
import java.util.Optional; import java.util.Optional;
import java.util.Set; import java.util.Set;
@ -238,6 +241,27 @@ public class JlinkTask {
} }
public static final String OPTIONS_RESOURCE = "jdk/tools/jlink/internal/options"; 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) { int run(String[] args) {
if (log == null) { if (log == null) {
@ -410,7 +434,8 @@ public class JlinkTask {
// Sanity check version if we use JMODs // Sanity check version if we use JMODs
if (!isLinkFromRuntime) { if (!isLinkFromRuntime) {
checkJavaBaseVersion(finder); assert(finder.find("java.base").isPresent());
checkJavaBaseVersion(finder.find("java.base").get());
} }
// Determine the roots set // Determine the roots set
@ -561,32 +586,34 @@ public class JlinkTask {
return finder; 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 * Checks the release information of the java.base used for target image
* with the current runtime version. * for compatibility with the java.base used by jlink.
* *
* @throws IllegalArgumentException the descriptor of java.base has no * @throws IllegalArgumentException If the `java.base` module reference `target`
* version or the java.base version is not the same as the current runtime's * is not compatible with this jlink.
* version.
*/ */
private static void checkJavaBaseVersion(ModuleFinder finder) { private static void checkJavaBaseVersion(ModuleReference target) {
assert finder.find("java.base").isPresent(); String currentRelease = getCurrentRuntimeVersion();
// use the version of java.base module, if present, as String targetRelease = getReleaseInfo(target).orElseThrow(() -> new IllegalArgumentException(
// the release version for multi-release JAR files taskHelper.getMessage("err.jlink.version.missing", currentRelease)));
ModuleDescriptor.Version v = finder.find("java.base").get()
.descriptor().version().orElseThrow(() ->
new IllegalArgumentException("No version in java.base descriptor")
);
Runtime.Version version = Runtime.Version.parse(v.toString()); if (!currentRelease.equals(targetRelease)) {
if (Runtime.version().feature() != version.feature() || // Current runtime image and the target runtime image are not compatible build
Runtime.version().interim() != version.interim()) {
// jlink version and java.base version do not match.
// We do not (yet) support this mode.
throw new IllegalArgumentException(taskHelper.getMessage("err.jlink.version.mismatch", throw new IllegalArgumentException(taskHelper.getMessage("err.jlink.version.mismatch",
Runtime.version().feature(), Runtime.version().interim(), currentRelease,
version.feature(), version.interim())); 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.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.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.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.automatic.module:automatic module cannot be used with jlink: {0} from {1}
err.unknown.byte.order:unknown byte order {0} err.unknown.byte.order:unknown byte order {0}
err.launcher.main.class.empty:launcher main class name cannot be empty: {0} err.launcher.main.class.empty:launcher main class name cannot be empty: {0}