|
@@ -18,6 +18,10 @@
|
|
|
|
|
|
package org.apache.hadoop.util;
|
|
package org.apache.hadoop.util;
|
|
|
|
|
|
|
|
+import java.security.AccessController;
|
|
|
|
+import java.security.PrivilegedAction;
|
|
|
|
+import java.util.Arrays;
|
|
|
|
+
|
|
import org.apache.hadoop.classification.InterfaceAudience;
|
|
import org.apache.hadoop.classification.InterfaceAudience;
|
|
import org.apache.hadoop.classification.InterfaceStability;
|
|
import org.apache.hadoop.classification.InterfaceStability;
|
|
|
|
|
|
@@ -33,21 +37,71 @@ public class PlatformName {
|
|
* per the java-vm.
|
|
* per the java-vm.
|
|
*/
|
|
*/
|
|
public static final String PLATFORM_NAME =
|
|
public static final String PLATFORM_NAME =
|
|
- (System.getProperty("os.name").startsWith("Windows")
|
|
|
|
- ? System.getenv("os") : System.getProperty("os.name"))
|
|
|
|
- + "-" + System.getProperty("os.arch")
|
|
|
|
- + "-" + System.getProperty("sun.arch.data.model");
|
|
|
|
|
|
+ (System.getProperty("os.name").startsWith("Windows") ?
|
|
|
|
+ System.getenv("os") : System.getProperty("os.name"))
|
|
|
|
+ + "-" + System.getProperty("os.arch") + "-"
|
|
|
|
+ + System.getProperty("sun.arch.data.model");
|
|
|
|
|
|
/**
|
|
/**
|
|
* The java vendor name used in this platform.
|
|
* The java vendor name used in this platform.
|
|
*/
|
|
*/
|
|
public static final String JAVA_VENDOR_NAME = System.getProperty("java.vendor");
|
|
public static final String JAVA_VENDOR_NAME = System.getProperty("java.vendor");
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
+ * Define a system class accessor that is open to changes in underlying implementations
|
|
|
|
+ * of the system class loader modules.
|
|
|
|
+ */
|
|
|
|
+ private static final class SystemClassAccessor extends ClassLoader {
|
|
|
|
+ public Class<?> getSystemClass(String className) throws ClassNotFoundException {
|
|
|
|
+ return findSystemClass(className);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
/**
|
|
/**
|
|
* A public static variable to indicate the current java vendor is
|
|
* A public static variable to indicate the current java vendor is
|
|
- * IBM java or not.
|
|
|
|
|
|
+ * IBM and the type is Java Technology Edition which provides its
|
|
|
|
+ * own implementations of many security packages and Cipher suites.
|
|
|
|
+ * Note that these are not provided in Semeru runtimes:
|
|
|
|
+ * See https://developer.ibm.com/languages/java/semeru-runtimes for details.
|
|
*/
|
|
*/
|
|
- public static final boolean IBM_JAVA = JAVA_VENDOR_NAME.contains("IBM");
|
|
|
|
|
|
+ public static final boolean IBM_JAVA = JAVA_VENDOR_NAME.contains("IBM") &&
|
|
|
|
+ hasIbmTechnologyEditionModules();
|
|
|
|
+
|
|
|
|
+ private static boolean hasIbmTechnologyEditionModules() {
|
|
|
|
+ return Arrays.asList(
|
|
|
|
+ "com.ibm.security.auth.module.JAASLoginModule",
|
|
|
|
+ "com.ibm.security.auth.module.Win64LoginModule",
|
|
|
|
+ "com.ibm.security.auth.module.NTLoginModule",
|
|
|
|
+ "com.ibm.security.auth.module.AIX64LoginModule",
|
|
|
|
+ "com.ibm.security.auth.module.LinuxLoginModule",
|
|
|
|
+ "com.ibm.security.auth.module.Krb5LoginModule"
|
|
|
|
+ ).stream().anyMatch((module) -> isSystemClassAvailable(module));
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * In rare cases where different behaviour is performed based on the JVM vendor
|
|
|
|
+ * this method should be used to test for a unique JVM class provided by the
|
|
|
|
+ * vendor rather than using the vendor method. For example if on JVM provides a
|
|
|
|
+ * different Kerberos login module testing for that login module being loadable
|
|
|
|
+ * before configuring to use it is preferable to using the vendor data.
|
|
|
|
+ *
|
|
|
|
+ * @param className the name of a class in the JVM to test for
|
|
|
|
+ * @return true if the class is available, false otherwise.
|
|
|
|
+ */
|
|
|
|
+ private static boolean isSystemClassAvailable(String className) {
|
|
|
|
+ return AccessController.doPrivileged((PrivilegedAction<Boolean>) () -> {
|
|
|
|
+ try {
|
|
|
|
+ // Using ClassLoader.findSystemClass() instead of
|
|
|
|
+ // Class.forName(className, false, null) because Class.forName with a null
|
|
|
|
+ // ClassLoader only looks at the boot ClassLoader with Java 9 and above
|
|
|
|
+ // which doesn't look at all the modules available to the findSystemClass.
|
|
|
|
+ new SystemClassAccessor().getSystemClass(className);
|
|
|
|
+ return true;
|
|
|
|
+ } catch (Exception ignored) {
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+ }
|
|
|
|
|
|
public static void main(String[] args) {
|
|
public static void main(String[] args) {
|
|
System.out.println(PLATFORM_NAME);
|
|
System.out.println(PLATFORM_NAME);
|