8304006: jlink should create the jimage file in the native endian for the target platform
Co-authored-by: Mandy Chung <mchung@openjdk.org> Reviewed-by: alanb, mchung, rriggs
This commit is contained in:
parent
e8f66bf88c
commit
81c4e8f916
@ -64,7 +64,6 @@ import jdk.tools.jlink.plugin.PluginException;
|
||||
import jdk.tools.jlink.plugin.ResourcePool;
|
||||
import jdk.tools.jlink.plugin.ResourcePoolEntry;
|
||||
import jdk.tools.jlink.plugin.ResourcePoolEntry.Type;
|
||||
import jdk.tools.jlink.plugin.ResourcePoolModule;
|
||||
|
||||
import static java.util.stream.Collectors.groupingBy;
|
||||
import static java.util.stream.Collectors.mapping;
|
||||
@ -145,16 +144,21 @@ public final class DefaultImageBuilder implements ImageBuilder {
|
||||
private final Map<String, String> launchers;
|
||||
private final Path mdir;
|
||||
private final Set<String> modules = new HashSet<>();
|
||||
private Platform platform;
|
||||
private final Platform platform;
|
||||
|
||||
/**
|
||||
* Default image builder constructor.
|
||||
*
|
||||
* @param root The image root directory.
|
||||
* @param launchers mapping of launcher command name to their module/main class
|
||||
* @param targetPlatform target platform of the image
|
||||
* @throws IOException
|
||||
* @throws NullPointerException If any of the params is null
|
||||
*/
|
||||
public DefaultImageBuilder(Path root, Map<String, String> launchers) throws IOException {
|
||||
public DefaultImageBuilder(Path root, Map<String, String> launchers, Platform targetPlatform)
|
||||
throws IOException {
|
||||
this.root = Objects.requireNonNull(root);
|
||||
this.platform = Objects.requireNonNull(targetPlatform);
|
||||
this.launchers = Objects.requireNonNull(launchers);
|
||||
this.mdir = root.resolve("lib");
|
||||
Files.createDirectories(mdir);
|
||||
@ -168,19 +172,6 @@ public final class DefaultImageBuilder implements ImageBuilder {
|
||||
@Override
|
||||
public void storeFiles(ResourcePool files) {
|
||||
try {
|
||||
String value = files.moduleView()
|
||||
.findModule("java.base")
|
||||
.map(ResourcePoolModule::targetPlatform)
|
||||
.orElse(null);
|
||||
if (value == null) {
|
||||
throw new PluginException("ModuleTarget attribute is missing for java.base module");
|
||||
}
|
||||
try {
|
||||
this.platform = Platform.parsePlatform(value);
|
||||
} catch (IllegalArgumentException iae) {
|
||||
throw new PluginException("ModuleTarget is malformed: " + iae.getMessage());
|
||||
}
|
||||
|
||||
checkResourcePool(files);
|
||||
|
||||
Path bin = root.resolve(BIN_DIRNAME);
|
||||
|
@ -147,7 +147,6 @@ public final class Jlink {
|
||||
|
||||
private final Path output;
|
||||
private final Set<String> modules;
|
||||
private final ByteOrder endian;
|
||||
private final ModuleFinder finder;
|
||||
|
||||
/**
|
||||
@ -155,26 +154,16 @@ public final class Jlink {
|
||||
*
|
||||
* @param output Output directory, must not exist.
|
||||
* @param modules The possibly-empty set of root modules to resolve
|
||||
* @param endian Jimage byte order. Native order by default
|
||||
* @param finder the ModuleFinder for this configuration
|
||||
*/
|
||||
public JlinkConfiguration(Path output,
|
||||
Set<String> modules,
|
||||
ByteOrder endian,
|
||||
ModuleFinder finder) {
|
||||
this.output = output;
|
||||
this.modules = Objects.requireNonNull(modules);
|
||||
this.endian = Objects.requireNonNull(endian);
|
||||
this.finder = finder;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the byte ordering
|
||||
*/
|
||||
public ByteOrder getByteOrder() {
|
||||
return endian;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the output
|
||||
*/
|
||||
@ -229,7 +218,6 @@ public final class Jlink {
|
||||
modsBuilder.append(p).append(",");
|
||||
}
|
||||
builder.append("modules=").append(modsBuilder).append("\n");
|
||||
builder.append("endian=").append(endian).append("\n");
|
||||
return builder.toString();
|
||||
}
|
||||
}
|
||||
|
@ -60,6 +60,7 @@ import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import jdk.internal.module.ModuleReferenceImpl;
|
||||
import jdk.tools.jlink.internal.TaskHelper.BadArgs;
|
||||
import static jdk.tools.jlink.internal.TaskHelper.JLINK_BUNDLE;
|
||||
import jdk.tools.jlink.internal.Jlink.JlinkConfiguration;
|
||||
@ -68,8 +69,6 @@ import jdk.tools.jlink.internal.TaskHelper.Option;
|
||||
import jdk.tools.jlink.internal.TaskHelper.OptionsHelper;
|
||||
import jdk.tools.jlink.internal.ImagePluginStack.ImageProvider;
|
||||
import jdk.tools.jlink.plugin.PluginException;
|
||||
import jdk.tools.jlink.builder.DefaultImageBuilder;
|
||||
import jdk.tools.jlink.plugin.Plugin;
|
||||
import jdk.internal.opt.CommandLine;
|
||||
import jdk.internal.module.ModulePath;
|
||||
import jdk.internal.module.ModuleResolution;
|
||||
@ -219,7 +218,7 @@ public class JlinkTask {
|
||||
Path output;
|
||||
final Map<String, String> launchers = new HashMap<>();
|
||||
Path packagedModulesPath;
|
||||
ByteOrder endian = ByteOrder.nativeOrder();
|
||||
ByteOrder endian;
|
||||
boolean ignoreSigning = false;
|
||||
boolean bindServices = false;
|
||||
boolean suggestProviders = false;
|
||||
@ -355,6 +354,7 @@ public class JlinkTask {
|
||||
null,
|
||||
IGNORE_SIGNING_DEFAULT,
|
||||
false,
|
||||
null,
|
||||
false,
|
||||
null);
|
||||
|
||||
@ -394,7 +394,6 @@ public class JlinkTask {
|
||||
|
||||
return new JlinkConfiguration(options.output,
|
||||
roots,
|
||||
options.endian,
|
||||
finder);
|
||||
}
|
||||
|
||||
@ -408,16 +407,18 @@ public class JlinkTask {
|
||||
}
|
||||
|
||||
// First create the image provider
|
||||
ImageProvider imageProvider = createImageProvider(config,
|
||||
options.packagedModulesPath,
|
||||
options.ignoreSigning,
|
||||
options.bindServices,
|
||||
options.verbose,
|
||||
log);
|
||||
ImageHelper imageProvider = createImageProvider(config,
|
||||
options.packagedModulesPath,
|
||||
options.ignoreSigning,
|
||||
options.bindServices,
|
||||
options.endian,
|
||||
options.verbose,
|
||||
log);
|
||||
|
||||
// Then create the Plugin Stack
|
||||
ImagePluginStack stack = ImagePluginConfiguration.parseConfiguration(
|
||||
taskHelper.getPluginsConfig(options.output, options.launchers));
|
||||
taskHelper.getPluginsConfig(options.output, options.launchers,
|
||||
imageProvider.targetPlatform));
|
||||
|
||||
//Ask the stack to proceed
|
||||
stack.operate(imageProvider);
|
||||
@ -511,12 +512,13 @@ public class JlinkTask {
|
||||
}
|
||||
|
||||
|
||||
private static ImageProvider createImageProvider(JlinkConfiguration config,
|
||||
Path retainModulesPath,
|
||||
boolean ignoreSigning,
|
||||
boolean bindService,
|
||||
boolean verbose,
|
||||
PrintWriter log)
|
||||
private static ImageHelper createImageProvider(JlinkConfiguration config,
|
||||
Path retainModulesPath,
|
||||
boolean ignoreSigning,
|
||||
boolean bindService,
|
||||
ByteOrder endian,
|
||||
boolean verbose,
|
||||
PrintWriter log)
|
||||
throws IOException
|
||||
{
|
||||
Configuration cf = bindService ? config.resolveAndBind()
|
||||
@ -563,7 +565,22 @@ public class JlinkTask {
|
||||
|
||||
Map<String, Path> mods = cf.modules().stream()
|
||||
.collect(Collectors.toMap(ResolvedModule::name, JlinkTask::toPathLocation));
|
||||
return new ImageHelper(cf, mods, config.getByteOrder(), retainModulesPath, ignoreSigning);
|
||||
// determine the target platform of the image being created
|
||||
Platform targetPlatform = targetPlatform(cf, mods);
|
||||
// if the user specified any --endian, then it must match the target platform's native
|
||||
// endianness
|
||||
if (endian != null && endian != targetPlatform.arch().byteOrder()) {
|
||||
throw new IOException(
|
||||
taskHelper.getMessage("err.target.endianness.mismatch", endian, targetPlatform));
|
||||
}
|
||||
if (verbose && log != null) {
|
||||
Platform runtime = Platform.runtime();
|
||||
if (runtime.os() != targetPlatform.os() || runtime.arch() != targetPlatform.arch()) {
|
||||
log.format("Cross-platform image generation, using %s for target platform %s%n",
|
||||
targetPlatform.arch().byteOrder(), targetPlatform);
|
||||
}
|
||||
}
|
||||
return new ImageHelper(cf, mods, targetPlatform, retainModulesPath, ignoreSigning);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -609,6 +626,63 @@ public class JlinkTask {
|
||||
};
|
||||
}
|
||||
|
||||
private static Platform targetPlatform(Configuration cf, Map<String, Path> modsPaths) throws IOException {
|
||||
Path javaBasePath = modsPaths.get("java.base");
|
||||
assert javaBasePath != null : "java.base module path is missing";
|
||||
if (isJavaBaseFromDefaultModulePath(javaBasePath)) {
|
||||
// this implies that the java.base module used for the target image
|
||||
// will correspond to the current platform. So this isn't an attempt to
|
||||
// build a cross-platform image. We use the current platform's endianness
|
||||
// in this case
|
||||
return Platform.runtime();
|
||||
} else {
|
||||
// this is an attempt to build a cross-platform image. We now attempt to
|
||||
// find the target platform's arch and thus its endianness from the java.base
|
||||
// module's ModuleTarget attribute
|
||||
String targetPlatformVal = readJavaBaseTargetPlatform(cf);
|
||||
try {
|
||||
return Platform.parsePlatform(targetPlatformVal);
|
||||
} catch (IllegalArgumentException iae) {
|
||||
throw new IOException(
|
||||
taskHelper.getMessage("err.unknown.target.platform", targetPlatformVal));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// returns true if the default module-path is the parent of the passed javaBasePath
|
||||
private static boolean isJavaBaseFromDefaultModulePath(Path javaBasePath) throws IOException {
|
||||
Path defaultModulePath = getDefaultModulePath();
|
||||
if (defaultModulePath == null) {
|
||||
return false;
|
||||
}
|
||||
// resolve, against the default module-path dir, the java.base module file used
|
||||
// for image creation
|
||||
Path javaBaseInDefaultPath = defaultModulePath.resolve(javaBasePath.getFileName());
|
||||
if (Files.notExists(javaBaseInDefaultPath)) {
|
||||
// the java.base module used for image creation doesn't exist in the default
|
||||
// module path
|
||||
return false;
|
||||
}
|
||||
return Files.isSameFile(javaBasePath, javaBaseInDefaultPath);
|
||||
}
|
||||
|
||||
// returns the targetPlatform value from the ModuleTarget attribute of the java.base module.
|
||||
// throws IOException if the targetPlatform cannot be determined.
|
||||
private static String readJavaBaseTargetPlatform(Configuration cf) throws IOException {
|
||||
Optional<ResolvedModule> javaBase = cf.findModule("java.base");
|
||||
assert javaBase.isPresent() : "java.base module is missing";
|
||||
ModuleReference ref = javaBase.get().reference();
|
||||
if (ref instanceof ModuleReferenceImpl modRefImpl
|
||||
&& modRefImpl.moduleTarget() != null) {
|
||||
return modRefImpl.moduleTarget().targetPlatform();
|
||||
}
|
||||
// could not determine target platform
|
||||
throw new IOException(
|
||||
taskHelper.getMessage("err.cannot.determine.target.platform",
|
||||
ref.location().map(URI::toString)
|
||||
.orElse("java.base module")));
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns a map of each service type to the modules that use it
|
||||
* It will include services that are provided by a module but may not used
|
||||
@ -772,7 +846,7 @@ public class JlinkTask {
|
||||
}
|
||||
|
||||
private static class ImageHelper implements ImageProvider {
|
||||
final ByteOrder order;
|
||||
final Platform targetPlatform;
|
||||
final Path packagedModulesPath;
|
||||
final boolean ignoreSigning;
|
||||
final Runtime.Version version;
|
||||
@ -780,10 +854,11 @@ public class JlinkTask {
|
||||
|
||||
ImageHelper(Configuration cf,
|
||||
Map<String, Path> modsPaths,
|
||||
ByteOrder order,
|
||||
Platform targetPlatform,
|
||||
Path packagedModulesPath,
|
||||
boolean ignoreSigning) throws IOException {
|
||||
this.order = order;
|
||||
Objects.requireNonNull(targetPlatform);
|
||||
this.targetPlatform = targetPlatform;
|
||||
this.packagedModulesPath = packagedModulesPath;
|
||||
this.ignoreSigning = ignoreSigning;
|
||||
|
||||
@ -857,7 +932,8 @@ public class JlinkTask {
|
||||
|
||||
@Override
|
||||
public ExecutableImage retrieve(ImagePluginStack stack) throws IOException {
|
||||
ExecutableImage image = ImageFileCreator.create(archives, order, stack);
|
||||
ExecutableImage image = ImageFileCreator.create(archives,
|
||||
targetPlatform.arch().byteOrder(), stack);
|
||||
if (packagedModulesPath != null) {
|
||||
// copy the packaged modules to the given path
|
||||
Files.createDirectories(packagedModulesPath);
|
||||
|
@ -50,10 +50,7 @@ public record Platform(OperatingSystem os, Architecture arch) {
|
||||
OperatingSystem os = OperatingSystem.valueOf(osName.toUpperCase(Locale.ROOT));
|
||||
|
||||
archName = platformString.substring(index + 1);
|
||||
// Alias architecture names, if needed
|
||||
archName = archName.replace("amd64", "X64");
|
||||
archName = archName.replace("s390x", "S390");
|
||||
Architecture arch = Architecture.valueOf(archName.toUpperCase(Locale.ROOT));
|
||||
Architecture arch = Architecture.lookupByName(archName);
|
||||
|
||||
return new Platform(os, arch);
|
||||
}
|
||||
|
@ -409,8 +409,9 @@ public final class TaskHelper {
|
||||
return null;
|
||||
}
|
||||
|
||||
private PluginsConfiguration getPluginsConfig(Path output, Map<String, String> launchers
|
||||
) throws IOException, BadArgs {
|
||||
private PluginsConfiguration getPluginsConfig(Path output, Map<String, String> launchers,
|
||||
Platform targetPlatform)
|
||||
throws IOException, BadArgs {
|
||||
if (output != null) {
|
||||
if (Files.exists(output)) {
|
||||
throw new IllegalArgumentException(PluginsResourceBundle.
|
||||
@ -457,7 +458,7 @@ public final class TaskHelper {
|
||||
// recreate or postprocessing don't require an output directory.
|
||||
ImageBuilder builder = null;
|
||||
if (output != null) {
|
||||
builder = new DefaultImageBuilder(output, launchers);
|
||||
builder = new DefaultImageBuilder(output, launchers, targetPlatform);
|
||||
}
|
||||
|
||||
return new Jlink.PluginsConfiguration(pluginsList,
|
||||
@ -708,9 +709,10 @@ public final class TaskHelper {
|
||||
+ bundleHelper.getMessage(key, args));
|
||||
}
|
||||
|
||||
public PluginsConfiguration getPluginsConfig(Path output, Map<String, String> launchers)
|
||||
public PluginsConfiguration getPluginsConfig(Path output, Map<String, String> launchers,
|
||||
Platform targetPlatform)
|
||||
throws IOException, BadArgs {
|
||||
return pluginOptions.getPluginsConfig(output, launchers);
|
||||
return pluginOptions.getPluginsConfig(output, launchers, targetPlatform);
|
||||
}
|
||||
|
||||
public void showVersion(boolean full) {
|
||||
|
@ -146,6 +146,10 @@ err.cannot.read.module.info=cannot read module descriptor from {0}
|
||||
err.not.modular.format=selected module {0} ({1}) not in jmod or modular JAR format
|
||||
err.signing=signed modular JAR {0} is currently not supported,\
|
||||
\ use --ignore-signing-information to suppress error
|
||||
err.cannot.determine.target.platform=cannot determine target platform from {0}
|
||||
err.unknown.target.platform=unknown target platform {0}
|
||||
err.target.endianness.mismatch=specified --endian {0} does not match endianness of target \
|
||||
platform {1}
|
||||
warn.signing=WARNING: signed modular JAR {0} is currently not supported
|
||||
warn.invalid.arg=invalid classname or pathname not exist: {0}
|
||||
warn.split.package=package {0} defined in {1} {2}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -41,6 +41,7 @@ import java.util.function.Function;
|
||||
import jdk.tools.jlink.internal.Jlink;
|
||||
import jdk.tools.jlink.internal.JlinkTask;
|
||||
import jdk.tools.jlink.builder.DefaultImageBuilder;
|
||||
import jdk.tools.jlink.internal.Platform;
|
||||
import jdk.tools.jlink.plugin.ResourcePool;
|
||||
import jdk.tools.jlink.plugin.ResourcePoolBuilder;
|
||||
import jdk.tools.jlink.plugin.Plugin;
|
||||
@ -160,7 +161,7 @@ public class IntegrationTest {
|
||||
Set<String> limits = new HashSet<>();
|
||||
limits.add("java.management");
|
||||
JlinkConfiguration config = new Jlink.JlinkConfiguration(output,
|
||||
mods, ByteOrder.nativeOrder(),
|
||||
mods,
|
||||
JlinkTask.newModuleFinder(modulePaths, limits, mods));
|
||||
|
||||
List<Plugin> lst = new ArrayList<>();
|
||||
@ -189,7 +190,8 @@ public class IntegrationTest {
|
||||
lst.add(new MyPostProcessor());
|
||||
}
|
||||
// Image builder
|
||||
DefaultImageBuilder builder = new DefaultImageBuilder(output, Collections.emptyMap());
|
||||
DefaultImageBuilder builder = new DefaultImageBuilder(output, Collections.emptyMap(),
|
||||
Platform.runtime());
|
||||
PluginsConfiguration plugins
|
||||
= new Jlink.PluginsConfiguration(lst, builder, null);
|
||||
|
||||
|
121
test/jdk/tools/jlink/JLinkEndianTest.java
Normal file
121
test/jdk/tools/jlink/JLinkEndianTest.java
Normal file
@ -0,0 +1,121 @@
|
||||
/*
|
||||
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.nio.ByteOrder;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Arrays;
|
||||
import java.util.spi.ToolProvider;
|
||||
|
||||
import jdk.internal.util.OperatingSystem;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8206890
|
||||
* @summary verify that the image created through jlink uses the byte order of the target platform
|
||||
* @modules java.base/jdk.internal.util
|
||||
* @comment the test asserts the presence of locale specific error message in the test's output,
|
||||
* so we explicitly use en_US locale
|
||||
* @run main/othervm -Duser.language=en -Duser.country=US JLinkEndianTest
|
||||
*/
|
||||
public class JLinkEndianTest {
|
||||
private static final ToolProvider JLINK_TOOL = ToolProvider.findFirst("jlink")
|
||||
.orElseThrow(() -> new RuntimeException("jlink tool not found"));
|
||||
|
||||
|
||||
public static void main(final String[] args) throws Exception {
|
||||
testEndianMismatch();
|
||||
testCorrectEndian();
|
||||
}
|
||||
|
||||
/**
|
||||
* Launches jlink with "--endian" option whose value doesn't match the target platform.
|
||||
* Asserts that the jlink process fails with an error.
|
||||
*/
|
||||
private static void testEndianMismatch() throws Exception {
|
||||
// we use a --endian value which doesn't match the current platform's endianness.
|
||||
// this should cause the jlink image generation against the current platform to fail
|
||||
final String endianOptVal = ByteOrder.nativeOrder() == ByteOrder.LITTLE_ENDIAN
|
||||
? "big" : "little";
|
||||
final String[] args = new String[]{
|
||||
"-v",
|
||||
"--endian", endianOptVal,
|
||||
"--add-modules", "java.base",
|
||||
"--output", "image-should-not-have-been-created"
|
||||
};
|
||||
final StringWriter jlinkStdout = new StringWriter();
|
||||
final StringWriter jlinkStderr = new StringWriter();
|
||||
System.out.println("Launching jlink with args: " + Arrays.toString(args));
|
||||
final int exitCode = JLINK_TOOL.run(new PrintWriter(jlinkStdout),
|
||||
new PrintWriter(jlinkStderr), args);
|
||||
System.out.println(jlinkStdout);
|
||||
System.err.println(jlinkStderr);
|
||||
if (exitCode == 0) {
|
||||
throw new AssertionError("jlink command was expected to fail but completed with" +
|
||||
" exit code: " + exitCode);
|
||||
}
|
||||
// verify the failure was due to the expected error (message)
|
||||
if (!jlinkStdout.toString().contains("does not match endianness of target platform")) {
|
||||
throw new AssertionError("jlink process' stderr didn't contain the expected" +
|
||||
" error message");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Launches jlink with "--endian" option whose value matches the target platform's endianness.
|
||||
* Asserts that the jlink process successfully creates the image.
|
||||
*/
|
||||
private static void testCorrectEndian() throws Exception {
|
||||
// we use a --endian value which matches the current platform
|
||||
final String endianOptVal = ByteOrder.nativeOrder() == ByteOrder.LITTLE_ENDIAN
|
||||
? "little" : "big";
|
||||
final Path imageOutDir = Path.of("correct-endian-image");
|
||||
final String[] args = new String[]{
|
||||
"-v",
|
||||
"--endian", endianOptVal,
|
||||
"--add-modules", "java.base",
|
||||
"--output", imageOutDir.toString()
|
||||
};
|
||||
final StringWriter jlinkStdout = new StringWriter();
|
||||
final StringWriter jlinkStderr = new StringWriter();
|
||||
System.out.println("Launching jlink with args: " + Arrays.toString(args));
|
||||
final int exitCode = JLINK_TOOL.run(new PrintWriter(jlinkStdout),
|
||||
new PrintWriter(jlinkStderr), args);
|
||||
System.out.println(jlinkStdout);
|
||||
System.err.println(jlinkStderr);
|
||||
if (exitCode != 0) {
|
||||
throw new AssertionError("jlink command was expected to succeed but completed with" +
|
||||
" exit code: " + exitCode);
|
||||
}
|
||||
// trivially verify <image-dir>/bin/java exists
|
||||
final Path javaBinary = OperatingSystem.isWindows()
|
||||
? Path.of(imageOutDir.toString(), "bin", "java.exe")
|
||||
: Path.of(imageOutDir.toString(), "bin", "java");
|
||||
if (!Files.exists(javaBinary)) {
|
||||
throw new AssertionError("jlink image generation was expected to create "
|
||||
+ javaBinary + ", but that file is missing");
|
||||
}
|
||||
}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -39,6 +39,7 @@ import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Collections;
|
||||
import jdk.tools.jlink.builder.DefaultImageBuilder;
|
||||
import jdk.tools.jlink.internal.Platform;
|
||||
import jdk.tools.jlink.internal.ResourcePoolEntryFactory;
|
||||
import jdk.tools.jlink.internal.ResourcePoolManager;
|
||||
import jdk.tools.jlink.plugin.PluginException;
|
||||
@ -61,7 +62,8 @@ public class ResourceDuplicateCheckTest {
|
||||
input.add(newInMemoryImageFile("/com.foo/bin/myexec",
|
||||
ResourcePoolEntry.Type.NATIVE_CMD, "mylib"));
|
||||
Path root = Paths.get(System.getProperty("test.classes"));
|
||||
DefaultImageBuilder writer = new DefaultImageBuilder(root, Collections.emptyMap());
|
||||
DefaultImageBuilder writer = new DefaultImageBuilder(root, Collections.emptyMap(),
|
||||
Platform.runtime());
|
||||
try {
|
||||
writer.storeFiles(input.resourcePool());
|
||||
} catch (PluginException pe) {
|
||||
|
Loading…
Reference in New Issue
Block a user