diff --git a/make/modules/java.base/gensrc/GensrcMisc.gmk b/make/modules/java.base/gensrc/GensrcMisc.gmk index 3519b0216ae..b2bae11baa3 100644 --- a/make/modules/java.base/gensrc/GensrcMisc.gmk +++ b/make/modules/java.base/gensrc/GensrcMisc.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2020, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 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 @@ -50,8 +50,14 @@ $(eval $(call SetupTextFileProcessing, BUILD_VERSION_JAVA, \ @@VENDOR_URL_VM_BUG@@ => $(VENDOR_URL_VM_BUG), \ )) -TARGETS += $(BUILD_VERSION_JAVA) +$(eval $(call SetupTextFileProcessing, BUILD_PLATFORMPROPERTIES_JAVA, \ + SOURCE_FILES := $(TOPDIR)/src/java.base/share/classes/jdk/internal/util/OperatingSystemProps.java.template, \ + OUTPUT_FILE := $(SUPPORT_OUTPUTDIR)/gensrc/java.base/jdk/internal/util/OperatingSystemProps.java, \ + REPLACEMENTS := \ + @@OPENJDK_TARGET_OS@@ => $(OPENJDK_TARGET_OS), \ +)) +TARGETS += $(BUILD_VERSION_JAVA) $(BUILD_PLATFORMPROPERTIES_JAVA) ################################################################################ ifneq ($(filter $(TOOLCHAIN_TYPE), gcc clang), ) diff --git a/src/java.base/share/classes/java/lang/ProcessBuilder.java b/src/java.base/share/classes/java/lang/ProcessBuilder.java index a7076ca4584..0b86dd507ac 100644 --- a/src/java.base/share/classes/java/lang/ProcessBuilder.java +++ b/src/java.base/share/classes/java/lang/ProcessBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 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 @@ -25,6 +25,7 @@ package java.lang; +import jdk.internal.util.OperatingSystem; import java.io.File; import java.io.FileDescriptor; import java.io.IOException; @@ -35,7 +36,6 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; import jdk.internal.event.ProcessStartEvent; -import sun.security.action.GetPropertyAction; /** * This class is used to create operating system processes. @@ -469,9 +469,8 @@ public final class ProcessBuilder * @since 1.7 */ public abstract static class Redirect { - private static final File NULL_FILE = new File( - (GetPropertyAction.privilegedGetProperty("os.name") - .startsWith("Windows") ? "NUL" : "/dev/null") + private static final File NULL_FILE = + new File((OperatingSystem.isWindows() ? "NUL" : "/dev/null") ); /** diff --git a/src/java.base/share/classes/java/util/zip/ZipFile.java b/src/java.base/share/classes/java/util/zip/ZipFile.java index f6b3588c738..e1c02759cb1 100644 --- a/src/java.base/share/classes/java/util/zip/ZipFile.java +++ b/src/java.base/share/classes/java/util/zip/ZipFile.java @@ -63,7 +63,7 @@ import java.util.stream.StreamSupport; import jdk.internal.access.JavaUtilZipFileAccess; import jdk.internal.access.JavaUtilJarAccess; import jdk.internal.access.SharedSecrets; -import jdk.internal.misc.VM; +import jdk.internal.util.OperatingSystem; import jdk.internal.perf.PerfCounter; import jdk.internal.ref.CleanerFactory; import jdk.internal.vm.annotation.Stable; @@ -1085,8 +1085,6 @@ public class ZipFile implements ZipConstants, Closeable { } } - private static boolean isWindows; - static { SharedSecrets.setJavaUtilZipFileAccess( new JavaUtilZipFileAccess() { @@ -1133,7 +1131,6 @@ public class ZipFile implements ZipConstants, Closeable { } ); - isWindows = VM.getSavedProperty("os.name").contains("Windows"); } private static class Source { @@ -1321,7 +1318,7 @@ public class ZipFile implements ZipConstants, Closeable { this.zc = zc; this.key = key; if (toDelete) { - if (isWindows) { + if (OperatingSystem.isWindows()) { this.zfile = SharedSecrets.getJavaIORandomAccessFileAccess() .openAndDelete(key.file, "r"); } else { diff --git a/src/java.base/share/classes/jdk/internal/foreign/CABI.java b/src/java.base/share/classes/jdk/internal/foreign/CABI.java index fa1661ff5a6..a6dfba99533 100644 --- a/src/java.base/share/classes/jdk/internal/foreign/CABI.java +++ b/src/java.base/share/classes/jdk/internal/foreign/CABI.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 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 @@ -25,8 +25,10 @@ */ package jdk.internal.foreign; +import jdk.internal.util.OperatingSystem; +import jdk.internal.util.StaticProperty; + import static java.lang.foreign.ValueLayout.ADDRESS; -import static sun.security.action.GetPropertyAction.privilegedGetProperty; public enum CABI { SYS_V, @@ -38,32 +40,30 @@ public enum CABI { private static final CABI ABI; private static final String ARCH; - private static final String OS; private static final long ADDRESS_SIZE; static { - ARCH = privilegedGetProperty("os.arch"); - OS = privilegedGetProperty("os.name"); + ARCH = StaticProperty.osArch(); ADDRESS_SIZE = ADDRESS.bitSize(); // might be running in a 32-bit VM on a 64-bit platform. // addressSize will be correctly 32 if ((ARCH.equals("amd64") || ARCH.equals("x86_64")) && ADDRESS_SIZE == 64) { - if (OS.startsWith("Windows")) { + if (OperatingSystem.isWindows()) { ABI = WIN_64; } else { ABI = SYS_V; } } else if (ARCH.equals("aarch64")) { - if (OS.startsWith("Mac")) { + if (OperatingSystem.isMacOS()) { ABI = MAC_OS_AARCH_64; - } else if (OS.startsWith("Windows")) { + } else if (OperatingSystem.isWindows()) { ABI = WIN_AARCH_64; } else { // The Linux ABI follows the standard AAPCS ABI ABI = LINUX_AARCH_64; } } else if (ARCH.equals("riscv64")) { - if (OS.startsWith("Linux")) { + if (OperatingSystem.isLinux()) { ABI = LINUX_RISCV_64; } else { // unsupported @@ -78,7 +78,8 @@ public enum CABI { public static CABI current() { if (ABI == null) { throw new UnsupportedOperationException( - "Unsupported os, arch, or address size: " + OS + ", " + ARCH + ", " + ADDRESS_SIZE); + "Unsupported os, arch, or address size: " + OperatingSystem.current() + + ", " + ARCH + ", " + ADDRESS_SIZE); } return ABI; } diff --git a/src/java.base/share/classes/jdk/internal/util/OperatingSystem.java b/src/java.base/share/classes/jdk/internal/util/OperatingSystem.java new file mode 100644 index 00000000000..ad90483a65e --- /dev/null +++ b/src/java.base/share/classes/jdk/internal/util/OperatingSystem.java @@ -0,0 +1,124 @@ +/* + * 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. + */ +package jdk.internal.util; + +import jdk.internal.util.OperatingSystemProps; +import jdk.internal.vm.annotation.ForceInline; + +/** + * Enumeration of operating system types and testing for the current OS. + * The enumeration can be used to dispatch to OS specific code or values. + * Checking if a specific operating system is current uses a simple + * static method for each operating system. + *
+ * For example,
+ * {@snippet lang = "java":
+ * if (OperatingSystem.isWindows()) {
+ * // Windows only code.
+ * } else if (OperatingSystem.isLinux()) {
+ * // Linux only code
+ * }
+ *}
+ *
+ * Alternatively, compare with the {@linkplain #current() current} operating system.
+ * For example,
+ * {@snippet lang = "java":
+ * if (OperatingSystem.current() == OperatingSystem.WINDOWS) {
+ * // Windows only code.
+ * }
+ *}
+ * Dispatch based on the current operating system or choose a value.
+ * For example,
+ * {@snippet lang = "java":
+ * int port() {
+ * return switch(OperatingSystem.current()) {
+ * case LINUX->32768;
+ * case AIX->32768;
+ * case MACOS->49152;
+ * case WINDOWS->49152;
+ * };
+ * }
+ *}
+ */
+public enum OperatingSystem {
+
+ /**
+ * Operating systems based on the Linux kernel.
+ */
+ LINUX,
+ /**
+ * The Mac OS X Operating system.
+ */
+ MACOS,
+ /**
+ * The Windows Operating system.
+ */
+ WINDOWS,
+ /**
+ * The AIX Operating system.
+ */
+ AIX,
+ ;
+
+ // Cache a copy of the array for lightweight indexing
+ private static final OperatingSystem[] osValues = OperatingSystem.values();
+
+ /**
+ * {@return {@code true} if built for the Linux operating system}
+ */
+ @ForceInline
+ public static boolean isLinux() {
+ return OperatingSystemProps.TARGET_OS_IS_LINUX;
+ }
+
+ /**
+ * {@return {@code true} if built for the Mac OS X operating system}
+ */
+ @ForceInline
+ public static boolean isMacOS() {
+ return OperatingSystemProps.TARGET_OS_IS_MACOSX;
+ }
+
+ /**
+ * {@return {@code true} if built for the Windows operating system}
+ */
+ @ForceInline
+ public static boolean isWindows() {
+ return OperatingSystemProps.TARGET_OS_IS_WINDOWS;
+ }
+
+ /**
+ * {@return {@code true} if built for the AIX operating system}
+ */
+ @ForceInline
+ public static boolean isAix() {
+ return OperatingSystemProps.TARGET_OS_IS_AIX;
+ }
+
+ /**
+ * {@return the current operating system}
+ */
+ public static OperatingSystem current() {
+ return osValues[OperatingSystemProps.CURRENT_OS_ORDINAL];
+ }
+}
diff --git a/src/java.base/share/classes/jdk/internal/util/OperatingSystemProps.java.template b/src/java.base/share/classes/jdk/internal/util/OperatingSystemProps.java.template
new file mode 100644
index 00000000000..b7178675e2c
--- /dev/null
+++ b/src/java.base/share/classes/jdk/internal/util/OperatingSystemProps.java.template
@@ -0,0 +1,46 @@
+/*
+ * 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.
+ */
+package jdk.internal.util;
+
+/**
+ * The corresponding source file is generated by GensrcMisc.gmk for java.base.
+ * @see OperatingSystem
+ */
+class OperatingSystemProps {
+
+ // Unique integers named to match the build system naming of the build target
+ // The values must match the ordinals of the respective enum
+ private static final int TARGET_OS_linux = 0;
+ private static final int TARGET_OS_macosx = 1;
+ private static final int TARGET_OS_windows = 2;
+ private static final int TARGET_OS_aix = 3;
+
+ // Index/ordinal of the current OperatingSystem enum as substituted by the build
+ static final int CURRENT_OS_ORDINAL = TARGET_OS_@@OPENJDK_TARGET_OS@@;
+
+ // Precomputed booleans for each Operating System
+ static final boolean TARGET_OS_IS_LINUX = TARGET_OS_@@OPENJDK_TARGET_OS@@ == TARGET_OS_linux;
+ static final boolean TARGET_OS_IS_MACOSX = TARGET_OS_@@OPENJDK_TARGET_OS@@ == TARGET_OS_macosx;
+ static final boolean TARGET_OS_IS_WINDOWS = TARGET_OS_@@OPENJDK_TARGET_OS@@ == TARGET_OS_windows;
+ static final boolean TARGET_OS_IS_AIX = TARGET_OS_@@OPENJDK_TARGET_OS@@ == TARGET_OS_aix;
+}
diff --git a/src/java.base/share/classes/jdk/internal/util/StaticProperty.java b/src/java.base/share/classes/jdk/internal/util/StaticProperty.java
index 10d062f1ab8..92004802f84 100644
--- a/src/java.base/share/classes/jdk/internal/util/StaticProperty.java
+++ b/src/java.base/share/classes/jdk/internal/util/StaticProperty.java
@@ -54,6 +54,8 @@ public final class StaticProperty {
private static final String JAVA_PROPERTIES_DATE;
private static final String SUN_JNU_ENCODING;
private static final String JAVA_LOCALE_USE_OLD_ISO_CODES;
+ private static final String OS_NAME;
+ private static final String OS_ARCH;
private StaticProperty() {}
@@ -73,6 +75,8 @@ public final class StaticProperty {
JAVA_PROPERTIES_DATE = getProperty(props, "java.properties.date", null);
SUN_JNU_ENCODING = getProperty(props, "sun.jnu.encoding");
JAVA_LOCALE_USE_OLD_ISO_CODES = getProperty(props, "java.locale.useOldISOCodes", "");
+ OS_NAME = getProperty(props, "os.name");
+ OS_ARCH = getProperty(props, "os.arch");
}
private static String getProperty(Properties props, String key) {
@@ -243,4 +247,22 @@ public final class StaticProperty {
public static String javaLocaleUseOldISOCodes() {
return JAVA_LOCALE_USE_OLD_ISO_CODES;
}
+
+ /**
+ * {@return the {@code os.name} system property}
+ * {@link SecurityManager#checkPropertyAccess} is NOT checked
+ * in this method. This property is not considered security sensitive.
+ */
+ public static String osName() {
+ return OS_NAME;
+ }
+
+ /**
+ * {@return the {@code os.arch} system property}
+ * {@link SecurityManager#checkPropertyAccess} is NOT checked
+ * in this method. This property is not considered security sensitive.
+ */
+ public static String osArch() {
+ return OS_ARCH;
+ }
}
diff --git a/src/java.base/share/classes/sun/launcher/LauncherHelper.java b/src/java.base/share/classes/sun/launcher/LauncherHelper.java
index 22a889a3025..76609edc249 100644
--- a/src/java.base/share/classes/sun/launcher/LauncherHelper.java
+++ b/src/java.base/share/classes/sun/launcher/LauncherHelper.java
@@ -77,6 +77,7 @@ import java.util.jar.Manifest;
import java.util.stream.Collectors;
import java.util.stream.Stream;
+import jdk.internal.util.OperatingSystem;
import jdk.internal.misc.VM;
import jdk.internal.module.ModuleBootstrap;
import jdk.internal.module.Modules;
@@ -168,7 +169,7 @@ public final class LauncherHelper {
printLocale();
break;
case "system":
- if (System.getProperty("os.name").contains("Linux")) {
+ if (OperatingSystem.isLinux()) {
printSystemMetrics();
break;
}
@@ -176,7 +177,7 @@ public final class LauncherHelper {
printVmSettings(initialHeapSize, maxHeapSize, stackSize);
printProperties();
printLocale();
- if (System.getProperty("os.name").contains("Linux")) {
+ if (OperatingSystem.isLinux()) {
printSystemMetrics();
}
break;
@@ -532,7 +533,7 @@ public final class LauncherHelper {
initOutput(printToStderr);
ostream.println(getLocalizedMessage("java.launcher.X.usage",
File.pathSeparator));
- if (System.getProperty("os.name").contains("OS X")) {
+ if (OperatingSystem.isMacOS()) {
ostream.println(getLocalizedMessage("java.launcher.X.macosx.usage",
File.pathSeparator));
}
@@ -745,7 +746,7 @@ public final class LauncherHelper {
Class> c = null;
try {
c = Class.forName(m, mainClass);
- if (c == null && System.getProperty("os.name", "").contains("OS X")
+ if (c == null && OperatingSystem.isMacOS()
&& Normalizer.isNormalized(mainClass, Normalizer.Form.NFD)) {
String cn = Normalizer.normalize(mainClass, Normalizer.Form.NFC);
@@ -789,7 +790,7 @@ public final class LauncherHelper {
try {
mainClass = Class.forName(cn, false, scl);
} catch (NoClassDefFoundError | ClassNotFoundException cnfe) {
- if (System.getProperty("os.name", "").contains("OS X")
+ if (OperatingSystem.isMacOS()
&& Normalizer.isNormalized(cn, Normalizer.Form.NFD)) {
try {
// On Mac OS X since all names with diacritical marks are
diff --git a/src/java.base/share/classes/sun/net/sdp/SdpSupport.java b/src/java.base/share/classes/sun/net/sdp/SdpSupport.java
index eab38bcbe53..5aa1ecaed8a 100644
--- a/src/java.base/share/classes/sun/net/sdp/SdpSupport.java
+++ b/src/java.base/share/classes/sun/net/sdp/SdpSupport.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 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
@@ -30,7 +30,7 @@ import java.io.FileDescriptor;
import jdk.internal.access.SharedSecrets;
import jdk.internal.access.JavaIOFileDescriptorAccess;
-import sun.security.action.GetPropertyAction;
+import jdk.internal.util.OperatingSystem;
/**
@@ -39,8 +39,7 @@ import sun.security.action.GetPropertyAction;
*/
public final class SdpSupport {
- private static final String os = GetPropertyAction.privilegedGetProperty("os.name");
- private static final boolean isSupported = os.equals("Linux");
+ private static final boolean isSupported = OperatingSystem.isLinux();
private static final JavaIOFileDescriptorAccess fdAccess =
SharedSecrets.getJavaIOFileDescriptorAccess();
diff --git a/src/java.base/unix/classes/java/lang/ProcessImpl.java b/src/java.base/unix/classes/java/lang/ProcessImpl.java
index 898ec9f398c..3b302b23cd3 100644
--- a/src/java.base/unix/classes/java/lang/ProcessImpl.java
+++ b/src/java.base/unix/classes/java/lang/ProcessImpl.java
@@ -37,19 +37,17 @@ import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.Charset;
import java.util.Arrays;
-import java.util.EnumSet;
import java.util.Locale;
-import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
import java.security.AccessController;
-import java.security.PrivilegedAction;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import jdk.internal.access.JavaIOFileDescriptorAccess;
import jdk.internal.access.SharedSecrets;
+import jdk.internal.util.OperatingSystem;
import jdk.internal.util.StaticProperty;
import sun.security.action.GetPropertyAction;
@@ -92,65 +90,39 @@ final class ProcessImpl extends Process {
VFORK
}
- private static enum Platform {
-
- LINUX(LaunchMechanism.POSIX_SPAWN, LaunchMechanism.VFORK, LaunchMechanism.FORK),
-
- BSD(LaunchMechanism.POSIX_SPAWN, LaunchMechanism.FORK),
-
- AIX(LaunchMechanism.POSIX_SPAWN, LaunchMechanism.FORK);
-
- final LaunchMechanism defaultLaunchMechanism;
- final Set