mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-27 06:45:07 +02:00
8304913: Use OperatingSystem, Architecture, and Version in jlink
Reviewed-by: jpai, alanb, mchung
This commit is contained in:
parent
0f7b1c549f
commit
01892f9c6e
7 changed files with 50 additions and 148 deletions
|
@ -283,6 +283,7 @@ module java.base {
|
||||||
java.security.jgss,
|
java.security.jgss,
|
||||||
java.smartcardio,
|
java.smartcardio,
|
||||||
jdk.charsets,
|
jdk.charsets,
|
||||||
|
jdk.jlink,
|
||||||
jdk.net;
|
jdk.net;
|
||||||
exports sun.net to
|
exports sun.net to
|
||||||
java.net.http,
|
java.net.http,
|
||||||
|
|
|
@ -56,6 +56,7 @@ import java.util.function.BiPredicate;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import jdk.internal.util.OperatingSystem;
|
||||||
import jdk.tools.jlink.internal.BasicImageWriter;
|
import jdk.tools.jlink.internal.BasicImageWriter;
|
||||||
import jdk.tools.jlink.internal.ExecutableImage;
|
import jdk.tools.jlink.internal.ExecutableImage;
|
||||||
import jdk.tools.jlink.internal.Platform;
|
import jdk.tools.jlink.internal.Platform;
|
||||||
|
@ -174,7 +175,11 @@ public final class DefaultImageBuilder implements ImageBuilder {
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
throw new PluginException("ModuleTarget attribute is missing for java.base module");
|
throw new PluginException("ModuleTarget attribute is missing for java.base module");
|
||||||
}
|
}
|
||||||
this.platform = Platform.parsePlatform(value);
|
try {
|
||||||
|
this.platform = Platform.parsePlatform(value);
|
||||||
|
} catch (IllegalArgumentException iae) {
|
||||||
|
throw new PluginException("ModuleTarget is malformed: " + iae.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
checkResourcePool(files);
|
checkResourcePool(files);
|
||||||
|
|
||||||
|
@ -490,7 +495,7 @@ public final class DefaultImageBuilder implements ImageBuilder {
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isWindows() {
|
private boolean isWindows() {
|
||||||
return platform.os() == Platform.OperatingSystem.WINDOWS;
|
return platform.os() == OperatingSystem.WINDOWS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -563,37 +568,6 @@ public final class DefaultImageBuilder implements ImageBuilder {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ExecutableImage getExecutableImage(Path root) {
|
|
||||||
Path binDir = root.resolve(BIN_DIRNAME);
|
|
||||||
if (Files.exists(binDir.resolve("java")) ||
|
|
||||||
Files.exists(binDir.resolve("java.exe"))) {
|
|
||||||
return new DefaultExecutableImage(root, retrieveModules(root), Platform.UNKNOWN);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Set<String> retrieveModules(Path root) {
|
|
||||||
Path releaseFile = root.resolve("release");
|
|
||||||
Set<String> modules = new HashSet<>();
|
|
||||||
if (Files.exists(releaseFile)) {
|
|
||||||
Properties release = new Properties();
|
|
||||||
try (FileInputStream fi = new FileInputStream(releaseFile.toFile())) {
|
|
||||||
release.load(fi);
|
|
||||||
} catch (IOException ex) {
|
|
||||||
System.err.println("Can't read release file " + ex);
|
|
||||||
}
|
|
||||||
String mods = release.getProperty("MODULES");
|
|
||||||
if (mods != null) {
|
|
||||||
String[] arr = mods.substring(1, mods.length() - 1).split(" ");
|
|
||||||
for (String m : arr) {
|
|
||||||
modules.add(m.trim());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return modules;
|
|
||||||
}
|
|
||||||
|
|
||||||
// finds subpaths matching the given criteria (up to 2 levels deep) and applies the given lambda
|
// finds subpaths matching the given criteria (up to 2 levels deep) and applies the given lambda
|
||||||
private static void forEachPath(Path dir, BiPredicate<Path, BasicFileAttributes> matcher, Consumer<Path> consumer) throws IOException {
|
private static void forEachPath(Path dir, BiPredicate<Path, BasicFileAttributes> matcher, Consumer<Path> consumer) throws IOException {
|
||||||
try (Stream<Path> stream = Files.find(dir, 2, matcher)) {
|
try (Stream<Path> stream = Files.find(dir, 2, matcher)) {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2015, 2021, 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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -80,8 +80,9 @@ public interface ImageBuilder {
|
||||||
* Gets the platform of the image.
|
* Gets the platform of the image.
|
||||||
*
|
*
|
||||||
* @return {@code Platform} object representing the platform of the image
|
* @return {@code Platform} object representing the platform of the image
|
||||||
|
* @throws UnsupportedOperationException if this method is not implemented by the ImageBuilder
|
||||||
*/
|
*/
|
||||||
public default Platform getTargetPlatform() {
|
public default Platform getTargetPlatform() {
|
||||||
return Platform.UNKNOWN;
|
throw new UnsupportedOperationException("Builder does not define getTargetPlatform");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2017, 2021, 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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -24,68 +24,44 @@
|
||||||
*/
|
*/
|
||||||
package jdk.tools.jlink.internal;
|
package jdk.tools.jlink.internal;
|
||||||
|
|
||||||
|
import jdk.internal.util.Architecture;
|
||||||
|
import jdk.internal.util.OperatingSystem;
|
||||||
|
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Supported platforms
|
* Supported OperatingSystem and Architecture.
|
||||||
*/
|
*/
|
||||||
public record Platform(OperatingSystem os, Architecture arch) {
|
public record Platform(OperatingSystem os, Architecture arch) {
|
||||||
|
|
||||||
public enum OperatingSystem {
|
|
||||||
WINDOWS,
|
|
||||||
LINUX,
|
|
||||||
MACOS,
|
|
||||||
AIX,
|
|
||||||
UNKNOWN;
|
|
||||||
}
|
|
||||||
|
|
||||||
public enum Architecture {
|
|
||||||
X86,
|
|
||||||
x64,
|
|
||||||
ARM,
|
|
||||||
AARCH64,
|
|
||||||
UNKNOWN;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static final Platform UNKNOWN = new Platform(OperatingSystem.UNKNOWN, Architecture.UNKNOWN);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Returns the {@code Platform} based on the platformString of the form <operating system>-<arch>.
|
* Returns the {@code Platform} based on the platformString of the form <operating system>-<arch>.
|
||||||
|
* @throws IllegalArgumentException if the delimiter is missing or either OS or
|
||||||
|
* architecture is not known
|
||||||
*/
|
*/
|
||||||
public static Platform parsePlatform(String platformString) {
|
public static Platform parsePlatform(String platformString) {
|
||||||
String osName;
|
String osName;
|
||||||
String archName;
|
String archName;
|
||||||
int index = platformString.indexOf("-");
|
int index = platformString.indexOf("-");
|
||||||
if (index < 0) {
|
if (index < 0) {
|
||||||
osName = platformString;
|
throw new IllegalArgumentException("platformString missing delimiter: " + platformString);
|
||||||
archName = "UNKNOWN";
|
|
||||||
} else {
|
|
||||||
osName = platformString.substring(0, index);
|
|
||||||
archName = platformString.substring(index + 1);
|
|
||||||
}
|
}
|
||||||
OperatingSystem os;
|
osName = platformString.substring(0, index);
|
||||||
try {
|
OperatingSystem os = OperatingSystem.valueOf(osName.toUpperCase(Locale.ROOT));
|
||||||
os = OperatingSystem.valueOf(osName.toUpperCase(Locale.ENGLISH));
|
|
||||||
} catch (IllegalArgumentException e) {
|
archName = platformString.substring(index + 1);
|
||||||
os = OperatingSystem.UNKNOWN;
|
// Alias architecture "amd64" to "X64"
|
||||||
}
|
archName = archName.replace("amd64", "X64");
|
||||||
Architecture arch = toArch(archName);
|
Architecture arch = Architecture.valueOf(archName.toUpperCase(Locale.ROOT));
|
||||||
|
|
||||||
return new Platform(os, arch);
|
return new Platform(os, arch);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return true is it's a 64-bit platform
|
* {@return the runtime {@code Platform}}
|
||||||
*/
|
|
||||||
public boolean is64Bit() {
|
|
||||||
return (arch() == Platform.Architecture.x64 ||
|
|
||||||
arch() == Platform.Architecture.AARCH64);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the runtime {@code Platform}.
|
|
||||||
*/
|
*/
|
||||||
public static Platform runtime() {
|
public static Platform runtime() {
|
||||||
return new Platform(runtimeOS(), runtimeArch());
|
return new Platform(OperatingSystem.current(), Architecture.current());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -93,43 +69,6 @@ public record Platform(OperatingSystem os, Architecture arch) {
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return os.toString().toLowerCase() + "-" + arch.toString().toLowerCase();
|
return os.toString().toLowerCase(Locale.ROOT) + "-" + arch.toString().toLowerCase(Locale.ROOT);
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the runtime {@code Platform.OperatingSystem}.
|
|
||||||
*/
|
|
||||||
private static OperatingSystem runtimeOS() {
|
|
||||||
String osName = System.getProperty("os.name").substring(0, 3).toLowerCase();
|
|
||||||
OperatingSystem os = switch (osName) {
|
|
||||||
case "win" -> OperatingSystem.WINDOWS;
|
|
||||||
case "lin" -> OperatingSystem.LINUX;
|
|
||||||
case "mac" -> OperatingSystem.MACOS;
|
|
||||||
case "aix" -> OperatingSystem.AIX;
|
|
||||||
default -> OperatingSystem.UNKNOWN;
|
|
||||||
};
|
|
||||||
return os;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the runtime {@code Platform.Architechrure}.
|
|
||||||
*/
|
|
||||||
private static Architecture runtimeArch() {
|
|
||||||
String archName = System.getProperty("os.arch");
|
|
||||||
return toArch(archName);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the {@code Platform.Architecture} based on the archName.
|
|
||||||
*/
|
|
||||||
private static Architecture toArch(String archName) {
|
|
||||||
Architecture arch = switch (archName) {
|
|
||||||
case "x86" -> Architecture.X86;
|
|
||||||
case "amd64", "x86_64" -> Architecture.x64;
|
|
||||||
case "arm" -> Architecture.ARM;
|
|
||||||
case "aarch64" -> Architecture.AARCH64;
|
|
||||||
default -> Architecture.UNKNOWN;
|
|
||||||
};
|
|
||||||
return arch;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -29,6 +29,8 @@ import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
|
import jdk.internal.util.Architecture;
|
||||||
|
import jdk.internal.util.OperatingSystem;
|
||||||
import jdk.tools.jlink.internal.ExecutableImage;
|
import jdk.tools.jlink.internal.ExecutableImage;
|
||||||
import jdk.tools.jlink.internal.Platform;
|
import jdk.tools.jlink.internal.Platform;
|
||||||
import jdk.tools.jlink.internal.PostProcessor;
|
import jdk.tools.jlink.internal.PostProcessor;
|
||||||
|
@ -51,7 +53,7 @@ public final class CDSPlugin extends AbstractPlugin implements PostProcessor {
|
||||||
|
|
||||||
|
|
||||||
private String javaExecutableName() {
|
private String javaExecutableName() {
|
||||||
if (targetPlatform.os() == Platform.OperatingSystem.WINDOWS) {
|
if (targetPlatform.os() == OperatingSystem.WINDOWS) {
|
||||||
return "java.exe";
|
return "java.exe";
|
||||||
} else {
|
} else {
|
||||||
return "java";
|
return "java";
|
||||||
|
@ -100,7 +102,9 @@ public final class CDSPlugin extends AbstractPlugin implements PostProcessor {
|
||||||
if (Files.exists(classListPath)) {
|
if (Files.exists(classListPath)) {
|
||||||
generateCDSArchive(image,false);
|
generateCDSArchive(image,false);
|
||||||
|
|
||||||
if (targetPlatform.is64Bit()) {
|
// The targetPlatform is the same as the runtimePlatform.
|
||||||
|
// For a 64-bit platform, generate the non-compressed oop CDS archive
|
||||||
|
if (Architecture.is64bit()) {
|
||||||
generateCDSArchive(image,true);
|
generateCDSArchive(image,true);
|
||||||
}
|
}
|
||||||
System.out.println("Created CDS archive successfully");
|
System.out.println("Created CDS archive successfully");
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2015, 2021, 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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -245,15 +245,17 @@ public final class ExcludeVMPlugin extends AbstractPlugin {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String[] jvmlibs(ResourcePoolModule module) {
|
private static String[] jvmlibs(ResourcePoolModule module) {
|
||||||
String targetPlatform = module.targetPlatform();
|
try {
|
||||||
Platform platform = Platform.parsePlatform(targetPlatform);
|
String targetPlatform = module.targetPlatform();
|
||||||
switch (platform.os()) {
|
Platform platform = Platform.parsePlatform(targetPlatform);
|
||||||
case WINDOWS:
|
return switch (platform.os()) {
|
||||||
return new String[] { "jvm.dll" };
|
case WINDOWS -> new String[]{"jvm.dll"};
|
||||||
case MACOS:
|
case MACOS -> new String[]{"libjvm.dylib", "libjvm.a"};
|
||||||
return new String[] { "libjvm.dylib", "libjvm.a" };
|
default -> new String[]{"libjvm.so", "libjvm.a"};
|
||||||
default:
|
};
|
||||||
return new String[] { "libjvm.so", "libjvm.a" };
|
} catch (IllegalArgumentException iae) {
|
||||||
|
// For unknown or malformed targetPlatform
|
||||||
|
return new String[]{"libjvm.so", "libjvm.a"};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -82,24 +82,5 @@ public class CDSPluginTest {
|
||||||
helper.checkImage(image, module, null, null,
|
helper.checkImage(image, module, null, null,
|
||||||
new String[] { subDir + "classes.jsa" });
|
new String[] { subDir + "classes.jsa" });
|
||||||
}
|
}
|
||||||
|
|
||||||
// Simulate different platforms between current runtime and target image.
|
|
||||||
if (Platform.isLinux()) {
|
|
||||||
System.out.println("---- Test different platforms scenario ----");
|
|
||||||
String jlinkPath = JDKToolFinder.getJDKTool("jlink");
|
|
||||||
String[] cmd = {jlinkPath, "--add-modules", "java.base,java.logging",
|
|
||||||
"-J-Dos.name=windows", "--generate-cds-archive",
|
|
||||||
"--output", System.getProperty("test.classes") + sep + module + "-tmp"};
|
|
||||||
StringBuilder cmdLine = new StringBuilder();
|
|
||||||
for (String s : cmd) {
|
|
||||||
cmdLine.append(s).append(' ');
|
|
||||||
}
|
|
||||||
System.out.println("Command line: [" + cmdLine.toString() + "]");
|
|
||||||
ProcessBuilder pb = new ProcessBuilder(cmd);
|
|
||||||
OutputAnalyzer out = new OutputAnalyzer(pb.start());
|
|
||||||
System.out.println(" stdout: " + out.getStdout());
|
|
||||||
out.shouldMatch("Error: Cannot generate CDS archives: target image platform linux-.*is different from runtime platform windows-.*");
|
|
||||||
out.shouldHaveExitValue(1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue