mirror of
https://github.com/openjdk/jdk.git
synced 2026-02-26 18:20:28 +00:00
8343839: Detect patched modules and abort run-time image link early
Reviewed-by: mchung
This commit is contained in:
parent
0664b51765
commit
05ee562a38
@ -32,6 +32,7 @@ import java.io.ByteArrayOutputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.nio.ByteOrder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
@ -56,7 +57,6 @@ import jdk.tools.jlink.internal.runtimelink.JimageDiffGenerator;
|
||||
import jdk.tools.jlink.internal.runtimelink.JimageDiffGenerator.ImageResource;
|
||||
import jdk.tools.jlink.internal.runtimelink.ResourceDiff;
|
||||
import jdk.tools.jlink.internal.runtimelink.ResourcePoolReader;
|
||||
import jdk.tools.jlink.internal.runtimelink.RuntimeImageLinkException;
|
||||
import jdk.tools.jlink.plugin.PluginException;
|
||||
import jdk.tools.jlink.plugin.ResourcePool;
|
||||
import jdk.tools.jlink.plugin.ResourcePoolBuilder;
|
||||
@ -91,14 +91,11 @@ public final class ImageFileCreator {
|
||||
private final Map<String, List<Entry>> entriesForModule = new HashMap<>();
|
||||
private final ImagePluginStack plugins;
|
||||
private final boolean generateRuntimeImage;
|
||||
private final TaskHelper helper;
|
||||
|
||||
private ImageFileCreator(ImagePluginStack plugins,
|
||||
boolean generateRuntimeImage,
|
||||
TaskHelper taskHelper) {
|
||||
boolean generateRuntimeImage) {
|
||||
this.plugins = Objects.requireNonNull(plugins);
|
||||
this.generateRuntimeImage = generateRuntimeImage;
|
||||
this.helper = taskHelper;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -118,24 +115,20 @@ public final class ImageFileCreator {
|
||||
public static ExecutableImage create(Set<Archive> archives,
|
||||
ByteOrder byteOrder,
|
||||
ImagePluginStack plugins,
|
||||
boolean generateRuntimeImage,
|
||||
TaskHelper taskHelper)
|
||||
boolean generateRuntimeImage)
|
||||
throws IOException
|
||||
{
|
||||
ImageFileCreator image = new ImageFileCreator(plugins,
|
||||
generateRuntimeImage,
|
||||
taskHelper);
|
||||
generateRuntimeImage);
|
||||
try {
|
||||
image.readAllEntries(archives);
|
||||
// write to modular image
|
||||
image.writeImage(archives, byteOrder);
|
||||
} catch (RuntimeImageLinkException e) {
|
||||
// readAllEntries() might throw this exception.
|
||||
// Propagate as IOException with appropriate message for
|
||||
// jlink runs from the run-time image. This handles better
|
||||
// error messages for the case of modified files in the run-time
|
||||
// image.
|
||||
throw image.newIOException(e);
|
||||
} catch (UncheckedIOException e) {
|
||||
// When linking from the run-time image, readAllEntries() might
|
||||
// throw this exception for a modified runtime. Unpack and
|
||||
// re-throw as IOException.
|
||||
throw e.getCause();
|
||||
} finally {
|
||||
// Close all archives
|
||||
for (Archive a : archives) {
|
||||
@ -200,11 +193,6 @@ public final class ImageFileCreator {
|
||||
ResourcePool result = null;
|
||||
try (DataOutputStream out = plugins.getJImageFileOutputStream()) {
|
||||
result = generateJImage(allContent, writer, plugins, out, generateRuntimeImage);
|
||||
} catch (RuntimeImageLinkException e) {
|
||||
// Propagate as IOException with appropriate message for
|
||||
// jlink runs from the run-time image. This handles better
|
||||
// error messages for the case of --patch-module.
|
||||
throw newIOException(e);
|
||||
}
|
||||
|
||||
//Handle files.
|
||||
@ -218,18 +206,6 @@ public final class ImageFileCreator {
|
||||
}
|
||||
}
|
||||
|
||||
private IOException newIOException(RuntimeImageLinkException e) throws IOException {
|
||||
if (JlinkTask.DEBUG) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
String message = switch (e.getReason()) {
|
||||
case PATCH_MODULE -> helper.getMessage("err.runtime.link.patched.module", e.getFile());
|
||||
case MODIFIED_FILE -> helper.getMessage("err.runtime.link.modified.file", e.getFile());
|
||||
default -> throw new AssertionError("Unexpected value: " + e.getReason());
|
||||
};
|
||||
throw new IOException(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a jimage based on content of the given ResourcePoolManager,
|
||||
* optionally creating a runtime that can be used for linking from the
|
||||
|
||||
@ -26,8 +26,6 @@
|
||||
package jdk.tools.jlink.internal;
|
||||
|
||||
import static jdk.tools.jlink.internal.LinkableRuntimeImage.RESPATH_PATTERN;
|
||||
import static jdk.tools.jlink.internal.runtimelink.RuntimeImageLinkException.Reason.MODIFIED_FILE;
|
||||
import static jdk.tools.jlink.internal.runtimelink.RuntimeImageLinkException.Reason.PATCH_MODULE;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
@ -37,7 +35,6 @@ import java.lang.module.ModuleFinder;
|
||||
import java.lang.module.ModuleReference;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.NoSuchFileException;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.security.MessageDigest;
|
||||
@ -56,7 +53,6 @@ import java.util.stream.Stream;
|
||||
import jdk.internal.util.OperatingSystem;
|
||||
import jdk.tools.jlink.internal.Archive.Entry.EntryType;
|
||||
import jdk.tools.jlink.internal.runtimelink.ResourceDiff;
|
||||
import jdk.tools.jlink.internal.runtimelink.RuntimeImageLinkException;
|
||||
import jdk.tools.jlink.plugin.ResourcePoolEntry;
|
||||
import jdk.tools.jlink.plugin.ResourcePoolEntry.Type;
|
||||
|
||||
@ -223,7 +219,9 @@ public class JRTArchive implements Archive {
|
||||
Path path = BASE.resolve(m.resPath);
|
||||
if (shaSumMismatch(path, m.hashOrTarget, m.symlink)) {
|
||||
if (errorOnModifiedFile) {
|
||||
throw new RuntimeImageLinkException(path.toString(), MODIFIED_FILE);
|
||||
String msg = taskHelper.getMessage("err.runtime.link.modified.file", path.toString());
|
||||
IOException cause = new IOException(msg);
|
||||
throw new UncheckedIOException(cause);
|
||||
} else {
|
||||
taskHelper.warning("err.runtime.link.modified.file", path.toString());
|
||||
}
|
||||
@ -460,16 +458,7 @@ public class JRTArchive implements Archive {
|
||||
// the underlying base path is a JrtPath with the
|
||||
// JrtFileSystem underneath which is able to handle
|
||||
// this size query.
|
||||
try {
|
||||
return Files.size(archive.getPath().resolve(resPath));
|
||||
} catch (NoSuchFileException file) {
|
||||
// This indicates that we don't find the class in the
|
||||
// modules image using the JRT FS provider. Yet, we find
|
||||
// the class using the system module finder. Therefore,
|
||||
// we have a patched module. Mention that module patching
|
||||
// is not supported.
|
||||
throw new RuntimeImageLinkException(file.getFile(), PATCH_MODULE);
|
||||
}
|
||||
return Files.size(archive.getPath().resolve(resPath));
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new UncheckedIOException(e);
|
||||
|
||||
@ -63,6 +63,7 @@ import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import jdk.internal.module.ModuleBootstrap;
|
||||
import jdk.internal.module.ModulePath;
|
||||
import jdk.internal.module.ModuleReferenceImpl;
|
||||
import jdk.internal.module.ModuleResolution;
|
||||
@ -73,7 +74,6 @@ import jdk.tools.jlink.internal.Jlink.PluginsConfiguration;
|
||||
import jdk.tools.jlink.internal.TaskHelper.BadArgs;
|
||||
import jdk.tools.jlink.internal.TaskHelper.Option;
|
||||
import jdk.tools.jlink.internal.TaskHelper.OptionsHelper;
|
||||
import jdk.tools.jlink.internal.runtimelink.RuntimeImageLinkException;
|
||||
import jdk.tools.jlink.plugin.PluginException;
|
||||
|
||||
/**
|
||||
@ -309,7 +309,7 @@ public class JlinkTask {
|
||||
}
|
||||
cleanupOutput(outputPath);
|
||||
return EXIT_ERROR;
|
||||
} catch (IllegalArgumentException | ResolutionException | RuntimeImageLinkException e) {
|
||||
} catch (IllegalArgumentException | ResolutionException e) {
|
||||
log.println(taskHelper.getMessage("error.prefix") + " " + e.getMessage());
|
||||
if (DEBUG) {
|
||||
e.printStackTrace(log);
|
||||
@ -620,6 +620,12 @@ public class JlinkTask {
|
||||
String msg = taskHelper.getMessage("err.runtime.link.jdk.jlink.prohibited");
|
||||
throw new IllegalArgumentException(msg);
|
||||
}
|
||||
// Do not permit linking from run-time image when the current image
|
||||
// is being patched.
|
||||
if (ModuleBootstrap.patcher().hasPatches()) {
|
||||
String msg = taskHelper.getMessage("err.runtime.link.patched.module");
|
||||
throw new IllegalArgumentException(msg);
|
||||
}
|
||||
|
||||
// Print info message indicating linking from the run-time image
|
||||
if (verbose && log != null) {
|
||||
@ -1039,7 +1045,7 @@ public class JlinkTask {
|
||||
@Override
|
||||
public ExecutableImage retrieve(ImagePluginStack stack) throws IOException {
|
||||
ExecutableImage image = ImageFileCreator.create(archives,
|
||||
targetPlatform.arch().byteOrder(), stack, generateRuntimeImage, taskHelper);
|
||||
targetPlatform.arch().byteOrder(), stack, generateRuntimeImage);
|
||||
if (packagedModulesPath != null) {
|
||||
// copy the packaged modules to the given path
|
||||
Files.createDirectories(packagedModulesPath);
|
||||
|
||||
@ -1,62 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2024, Red Hat, Inc.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package jdk.tools.jlink.internal.runtimelink;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Exception thrown when linking from the run-time image
|
||||
*/
|
||||
public class RuntimeImageLinkException extends RuntimeException {
|
||||
|
||||
private static final long serialVersionUID = -1848914673073119403L;
|
||||
|
||||
public static enum Reason {
|
||||
PATCH_MODULE, /* link exception due to patched module */
|
||||
MODIFIED_FILE, /* link exception due to modified file */
|
||||
}
|
||||
|
||||
private final String file;
|
||||
private final Reason reason;
|
||||
|
||||
public RuntimeImageLinkException(String file, Reason reason) {
|
||||
this.file = Objects.requireNonNull(file);
|
||||
this.reason = Objects.requireNonNull(reason);
|
||||
}
|
||||
|
||||
public String getFile() {
|
||||
return file;
|
||||
}
|
||||
|
||||
public Reason getReason() {
|
||||
return reason;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
return reason + ", file: " + file;
|
||||
}
|
||||
}
|
||||
@ -125,8 +125,8 @@ err.runtime.link.jdk.jlink.prohibited=This JDK does not contain packaged modules
|
||||
err.runtime.link.packaged.mods=This JDK has no packaged modules.\
|
||||
\ --keep-packaged-modules is not supported
|
||||
err.runtime.link.modified.file={0} has been modified
|
||||
err.runtime.link.patched.module=File {0} not found in the modules image.\
|
||||
\ --patch-module is not supported when linking from the run-time image
|
||||
err.runtime.link.patched.module=jlink does not support linking from the run-time image\
|
||||
\ when running on a patched runtime with --patch-module
|
||||
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}
|
||||
|
||||
@ -224,6 +224,6 @@ public class ImageFileCreatorTest {
|
||||
ImagePluginStack stack = new ImagePluginStack(noopBuilder, Collections.emptyList(),
|
||||
null, false);
|
||||
|
||||
ImageFileCreator.create(archives, ByteOrder.nativeOrder(), stack, false, null);
|
||||
ImageFileCreator.create(archives, ByteOrder.nativeOrder(), stack, false);
|
||||
}
|
||||
}
|
||||
|
||||
@ -78,7 +78,7 @@ public class ModifiedFilesExitTest extends ModifiedFilesTest {
|
||||
}
|
||||
analyzer.stdoutShouldContain(modifiedFile.toString() + " has been modified");
|
||||
// Verify the error message is reasonable
|
||||
analyzer.stdoutShouldNotContain("jdk.tools.jlink.internal.RunImageLinkException");
|
||||
analyzer.stdoutShouldNotContain("IOException");
|
||||
analyzer.stdoutShouldNotContain("java.lang.IllegalArgumentException");
|
||||
}
|
||||
|
||||
|
||||
@ -70,6 +70,6 @@ public class ModifiedFilesWarningTest extends ModifiedFilesTest {
|
||||
// verify we get the warning message
|
||||
out.stdoutShouldMatch("Warning: .* has been modified");
|
||||
out.stdoutShouldNotContain("java.lang.IllegalArgumentException");
|
||||
out.stdoutShouldNotContain("jdk.tools.jlink.internal.RunImageLinkException");
|
||||
out.stdoutShouldNotContain("IOException");
|
||||
}
|
||||
}
|
||||
|
||||
@ -97,10 +97,10 @@ public class PatchedJDKModuleJlinkTest extends AbstractLinkableRuntimeTest {
|
||||
if (analyzer.getExitValue() == 0) {
|
||||
throw new AssertionError("Expected jlink to fail due to patched module!");
|
||||
}
|
||||
analyzer.stdoutShouldContain("MyJlinkPatchInteger.class not found in the modules image.");
|
||||
analyzer.stdoutShouldContain("--patch-module is not supported");
|
||||
analyzer.stdoutShouldContain("jlink does not support linking from the run-time image");
|
||||
analyzer.stdoutShouldContain(" when running on a patched runtime with --patch-module");
|
||||
// Verify the error message is reasonable
|
||||
analyzer.stdoutShouldNotContain("jdk.tools.jlink.internal.RunImageLinkException");
|
||||
analyzer.stdoutShouldNotContain("IOException");
|
||||
analyzer.stdoutShouldNotContain("java.lang.IllegalArgumentException");
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user