18
18
19
19
package org .apache .hadoop .util ;
20
20
21
+ import java .security .AccessController ;
22
+ import java .security .PrivilegedAction ;
23
+ import java .util .Arrays ;
24
+
21
25
import org .apache .hadoop .classification .InterfaceAudience ;
22
26
import org .apache .hadoop .classification .InterfaceStability ;
23
27
@@ -33,21 +37,71 @@ public class PlatformName {
33
37
* per the java-vm.
34
38
*/
35
39
public static final String PLATFORM_NAME =
36
- (System .getProperty ("os.name" ).startsWith ("Windows" )
37
- ? System .getenv ("os" ) : System .getProperty ("os.name" ))
38
- + "-" + System .getProperty ("os.arch" )
39
- + "-" + System .getProperty ("sun.arch.data.model" );
40
+ (System .getProperty ("os.name" ).startsWith ("Windows" ) ?
41
+ System .getenv ("os" ) : System .getProperty ("os.name" ))
42
+ + "-" + System .getProperty ("os.arch" ) + "-"
43
+ + System .getProperty ("sun.arch.data.model" );
40
44
41
45
/**
42
46
* The java vendor name used in this platform.
43
47
*/
44
48
public static final String JAVA_VENDOR_NAME = System .getProperty ("java.vendor" );
45
49
50
+ /**
51
+ * Define a system class accessor that is open to changes in underlying implementations
52
+ * of the system class loader modules.
53
+ */
54
+ private static final class SystemClassAccessor extends ClassLoader {
55
+ public Class <?> getSystemClass (String className ) throws ClassNotFoundException {
56
+ return findSystemClass (className );
57
+ }
58
+ }
59
+
46
60
/**
47
61
* A public static variable to indicate the current java vendor is
48
- * IBM java or not.
62
+ * IBM and the type is Java Technology Edition which provides its
63
+ * own implementations of many security packages and Cipher suites.
64
+ * Note that these are not provided in Semeru runtimes:
65
+ * See https://developer.ibm.com/languages/java/semeru-runtimes for details.
49
66
*/
50
- public static final boolean IBM_JAVA = JAVA_VENDOR_NAME .contains ("IBM" );
67
+ public static final boolean IBM_JAVA = JAVA_VENDOR_NAME .contains ("IBM" ) &&
68
+ hasIbmTechnologyEditionModules ();
69
+
70
+ private static boolean hasIbmTechnologyEditionModules () {
71
+ return Arrays .asList (
72
+ "com.ibm.security.auth.module.JAASLoginModule" ,
73
+ "com.ibm.security.auth.module.Win64LoginModule" ,
74
+ "com.ibm.security.auth.module.NTLoginModule" ,
75
+ "com.ibm.security.auth.module.AIX64LoginModule" ,
76
+ "com.ibm.security.auth.module.LinuxLoginModule" ,
77
+ "com.ibm.security.auth.module.Krb5LoginModule"
78
+ ).stream ().anyMatch ((module ) -> isSystemClassAvailable (module ));
79
+ }
80
+
81
+ /**
82
+ * In rare cases where different behaviour is performed based on the JVM vendor
83
+ * this method should be used to test for a unique JVM class provided by the
84
+ * vendor rather than using the vendor method. For example if on JVM provides a
85
+ * different Kerberos login module testing for that login module being loadable
86
+ * before configuring to use it is preferable to using the vendor data.
87
+ *
88
+ * @param className the name of a class in the JVM to test for
89
+ * @return true if the class is available, false otherwise.
90
+ */
91
+ private static boolean isSystemClassAvailable (String className ) {
92
+ return AccessController .doPrivileged ((PrivilegedAction <Boolean >) () -> {
93
+ try {
94
+ // Using ClassLoader.findSystemClass() instead of
95
+ // Class.forName(className, false, null) because Class.forName with a null
96
+ // ClassLoader only looks at the boot ClassLoader with Java 9 and above
97
+ // which doesn't look at all the modules available to the findSystemClass.
98
+ new SystemClassAccessor ().getSystemClass (className );
99
+ return true ;
100
+ } catch (Exception ignored ) {
101
+ return false ;
102
+ }
103
+ });
104
+ }
51
105
52
106
public static void main (String [] args ) {
53
107
System .out .println (PLATFORM_NAME );
0 commit comments