8185130: jlink should throw error if target image and current JDK versions don't match

Reviewed-by: redestad, alanb, mchung
This commit is contained in:
Athijegannathan Sundararajan 2017-12-06 08:04:35 +05:30
parent ed7a7fb89f
commit 448f3c1fcd
5 changed files with 25 additions and 66 deletions
src/jdk.jlink/share/classes/jdk/tools/jlink
test/jdk/tools/jlink/multireleasejar

@ -430,7 +430,7 @@ public class JlinkTask {
Set<String> roots)
{
if (Objects.requireNonNull(paths).isEmpty()) {
throw new IllegalArgumentException("Empty module path");
throw new IllegalArgumentException(taskHelper.getMessage("err.empty.module.path"));
}
Path[] entries = paths.toArray(new Path[0]);
@ -447,8 +447,13 @@ public class JlinkTask {
// java.base version is different than the current runtime version
version = Runtime.Version.parse(v.toString());
if (Runtime.version().major() != version.major()) {
finder = ModulePath.of(version, true, entries);
if (Runtime.version().major() != version.major() ||
Runtime.version().minor() != version.minor()) {
// 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",
Runtime.version().major(), Runtime.version().minor(),
version.major(), version.minor()));
}
}

@ -54,11 +54,8 @@ import jdk.tools.jlink.plugin.Plugin;
public final class GenerateJLIClassesPlugin implements Plugin {
private static final String NAME = "generate-jli-classes";
private static final String IGNORE_VERSION = "ignore-version";
private static final String DESCRIPTION = PluginsResourceBundle.getDescription(NAME);
private static final String IGNORE_VERSION_WARNING = NAME + ".ignore.version.warn";
private static final String VERSION_MISMATCH_WARNING = NAME + ".version.mismatch.warn";
private static final String DEFAULT_TRACE_FILE = "default_jli_trace.txt";
@ -85,8 +82,6 @@ public final class GenerateJLIClassesPlugin implements Plugin {
String mainArgument;
boolean ignoreVersion;
public GenerateJLIClassesPlugin() {
}
@ -170,7 +165,6 @@ public final class GenerateJLIClassesPlugin implements Plugin {
@Override
public void configure(Map<String, String> config) {
mainArgument = config.get(NAME);
ignoreVersion = Boolean.parseBoolean(config.get(IGNORE_VERSION));
}
public void initialize(ResourcePool in) {
@ -208,26 +202,6 @@ public final class GenerateJLIClassesPlugin implements Plugin {
}
}
private boolean checkVersion(Runtime.Version linkedVersion) {
Runtime.Version baseVersion = Runtime.version();
if (baseVersion.major() != linkedVersion.major() ||
baseVersion.minor() != linkedVersion.minor()) {
return false;
}
return true;
}
private Runtime.Version getLinkedVersion(ResourcePool in) {
ModuleDescriptor.Version version = in.moduleView()
.findModule("java.base")
.get()
.descriptor()
.version()
.orElseThrow(() -> new PluginException("No version defined in "
+ "the java.base being linked"));
return Runtime.Version.parse(version.toString());
}
private void readTraceConfig(Stream<String> lines) {
// Use TreeSet/TreeMap to keep things sorted in a deterministic
// order to avoid scrambling the layout on small changes and to
@ -315,24 +289,6 @@ public final class GenerateJLIClassesPlugin implements Plugin {
@Override
public ResourcePool transform(ResourcePool in, ResourcePoolBuilder out) {
if (ignoreVersion) {
System.out.println(
PluginsResourceBundle
.getMessage(IGNORE_VERSION_WARNING));
} else if (!checkVersion(getLinkedVersion(in))) {
// The linked images are not version compatible
if (mainArgument != null) {
// Log a mismatch warning if an argument was specified
System.out.println(
PluginsResourceBundle
.getMessage(VERSION_MISMATCH_WARNING,
getLinkedVersion(in),
Runtime.version()));
}
in.transformAndCopy(entry -> entry, out);
return out.build();
}
initialize(in);
// Copy all but DMH_ENTRY to out
in.transformAndCopy(entry -> {

@ -107,6 +107,8 @@ main.extended.help.footer=\
error.prefix=Error:
warn.prefix=Warning:
err.empty.module.path=empty module path
err.jlink.version.mismatch=jlink version {0}.{1} does not match target java.base version {2}.{3}
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}

@ -75,7 +75,7 @@ where <section-name> is \"man\" or \"headers".
exclude-jmod-section.description=\
Specify a JMOD section to exclude
generate-jli-classes.argument=@filename[:ignore-version=<true|false>]
generate-jli-classes.argument=@filename
generate-jli-classes.description=\
Specify a file listing the java.lang.invoke classes to pre-generate. \n\
@ -84,15 +84,6 @@ If this plugin runs on a different runtime version than the image being \n\
created then code generation will be disabled by default to guarantee \n\
correctness - add ignore-version=true to override this.
generate-jli-classes.ignore.version.warn=\
WARNING: --generate-jli-classes set to ignore version mismatch between \n\
JDK running jlink and target image.
generate-jli-classes.version.mismatch.warn=\
WARNING: Pre-generation of JLI classes is only supported when linking \n\
the same version of java.base ({0}) as the JDK running jlink ({1}), \n\
class generation skipped - specify ignore-version to override.
system-modules.argument=retainModuleTarget
system-modules.description=Fast loading of module descriptors (always enabled)

@ -25,6 +25,8 @@
* @test
* @bug 8177471
* @summary jlink should use the version from java.base.jmod to find modules
* @bug 8185130
* @summary jlink should throw error if target image and current JDK versions don't match
* @modules java.base/jdk.internal.module
* @library /test/lib
* @build jdk.test.lib.process.* CheckRuntimeVersion
@ -122,7 +124,9 @@ public class JLinkMRJavaBaseVersionTest {
System.out.println("Testing jlink with " + getJmods() + " of target version " + version);
// use jlink to build image from multi-release jar
jlink("m1.jar", "myimage");
if (jlink("m1.jar", "myimage")) {
return;
}
// validate runtime image
Path java = Paths.get("myimage", "bin", "java");
@ -130,12 +134,7 @@ public class JLinkMRJavaBaseVersionTest {
// validate the image linked with the proper MR version
if (version.equalsIgnoreOptional(Runtime.version())) {
ProcessTools.executeProcess(java.toString(), "-cp", System.getProperty("test.classes"),
"CheckRuntimeVersion", String.valueOf(version.major()),
"java.base", "java.logging", "m1")
.shouldHaveExitValue(0);
} else {
if (!version.equalsIgnoreOptional(Runtime.version())) {
ProcessTools.executeProcess(java.toString(), "-cp", System.getProperty("test.classes"),
"CheckRuntimeVersion", String.valueOf(version.major()),
"java.base", "m1")
@ -151,13 +150,19 @@ public class JLinkMRJavaBaseVersionTest {
return Runtime.Version.parse(mref.descriptor().version().get().toString());
}
private void jlink(String jar, String image) {
private boolean jlink(String jar, String image) {
List<String> args = List.of("--output", image,
"--add-modules", "m1",
"--module-path",
getJmods().toString() + File.pathSeparator + jar);
System.out.println("jlink " + args.stream().collect(Collectors.joining(" ")));
int exitCode = JLINK_TOOL.run(System.out, System.err, args.toArray(new String[0]));
Assert.assertEquals(exitCode, 0);
boolean isJDK9 = System.getProperty("java9.home") != null;
if (isJDK9) {
Assert.assertNotEquals(exitCode, 0);
} else {
Assert.assertEquals(exitCode, 0);
}
return isJDK9;
}
}