blob: ae9107bcb311cf9d82036640f915baa3a6fc1de9 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.netbeans.lib.profiler.global;
import java.io.File;
import java.io.IOException;
/**
* Determination of the current platform (OS, hardware) and related services.
*
* @author Tomas Hurka
* @author Misha Dmitriev
* @author Ian Formanek
*/
public class Platform implements CommonConstants {
//~ Static fields/initializers -----------------------------------------------------------------------------------------------
/**
* Operating system is Windows NT.
*/
public static final int OS_WINNT = 1;
/**
* Operating system is Windows 95.
*/
public static final int OS_WIN95 = 2;
/**
* Operating system is Windows 98.
*/
public static final int OS_WIN98 = 4;
/**
* Operating system is Solaris.
*/
public static final int OS_SOLARIS = 8;
/**
* Operating system is Linux.
*/
public static final int OS_LINUX = 16;
/**
* Operating system is HP-UX.
*/
public static final int OS_HP = 32;
/**
* Operating system is IBM AIX.
*/
public static final int OS_AIX = 64;
/**
* Operating system is SGI IRIX.
*/
public static final int OS_IRIX = 128;
/**
* Operating system is Sun OS.
*/
public static final int OS_SUNOS = 256;
/**
* Operating system is Compaq TRU64 Unix
*/
public static final int OS_TRU64 = 512;
/**
* Operating system is OS/2.
*/
public static final int OS_OS2 = 1024;
/**
* Operating system is Mac.
*/
public static final int OS_MAC = 2048;
/**
* Operating system is Windows 2000.
*/
public static final int OS_WIN2000 = 4096;
/**
* Operating system is Compaq OpenVMS
*/
public static final int OS_VMS = 8192;
/**
* Operating system is one of the Windows variants but we don't know which one it is
*/
public static final int OS_WIN_OTHER = 16384;
/**
* Operating system is unknown.
*/
public static final int OS_OTHER = 65536;
/**
* A mask for Windows platforms.
*/
public static final int OS_WINDOWS_MASK = OS_WINNT | OS_WIN95 | OS_WIN98 | OS_WIN2000 | OS_WIN_OTHER;
/**
* A mask for Unix platforms.
*/
public static final int OS_UNIX_MASK = OS_SOLARIS | OS_LINUX | OS_HP | OS_AIX | OS_IRIX | OS_SUNOS | OS_TRU64 | OS_MAC;
/**
* The operating system on which the tool runs
*/
private static int operatingSystem = -1;
private static String jdkDenoteString;
private static int jdkVersion;
private static int sysArch; // 32/64bit architecture
//~ Methods ------------------------------------------------------------------------------------------------------------------
/**
* Given the name of the directory containing the JFluid native libaries (either just the root JFluid libs dir,
* or really the full path, depending on fullPathToLibSpecified parameter), return the full platform-dependent
* name for the "profilerinterface" library contained in that directory. If non-null jdkString is specified, it
* is used in the resulting path; otherwise the VM is queried for its version and the resulting string is used.
*
* @param fullAgentPath The path to the library
* @param fullPathToLibSpecified whether or not a full path is specified (ending at the platform level)
* @param jdkString CommonConstants.JDK_15_STRING
* @return A path to the native library to be used for this platform
*/
public static String getAgentNativeLibFullName(String fullAgentPath, boolean fullPathToLibSpecified, String jdkString,
int architecture) {
boolean is64bitArch;
if (jdkString == null) {
jdkString = getJDKVersionString();
}
if (architecture == -1) {
architecture = getSystemArchitecture();
}
is64bitArch = architecture == ARCH_64;
if (jdkString.equals(JDK_17_STRING) || jdkString.equals(JDK_18_STRING) || jdkString.equals(JDK_19_STRING) || jdkString.equals(JDK_110_BEYOND_STRING)) {
// for now, we use the same libs for 1.6 and beyond
jdkString = JDK_16_STRING;
}
String libPrefix = ""; // NOI18N
if (!isWindows()) { // Mac and UNIXes
libPrefix = "lib"; // NOI18N
}
String libSuffix = ""; // NOI18N
if (isWindows()) {
libSuffix = ".dll"; // Windows // NOI18N
} else if (isMac()) {
libSuffix = ".jnilib"; // Mac // NOI18N
} else if (isHpux()) {
libSuffix = ".sl"; // HP-UX // NOI18N
} else {
libSuffix = ".so"; // UNIXes // NOI18N
}
String libSubPath = "/"; // NOI18N
if (!fullPathToLibSpecified) {
String libSubDir;
if (isWindows()) {
libSubDir = "windows"; // NOI18N
} else if (isMac()) {
libSubDir = "mac";
} else if (isLinux()) {
libSubDir = "linux"; // NOI18N
} else if (isHpux()) {
libSubDir = "hpux"; // NOI18N
} else {
libSubDir = "solaris"; // NOI18N
}
String procArch = null;
if (is64bitArch) {
if (isLinux() || isWindows() || isSolarisIntel()) {
procArch = "amd64"; // NOI18N
} else if (isSolarisSparc()) {
procArch = "sparcv9"; // NOI18N
} else if (isHpux()) {
procArch = "pa_risc2.0w"; // NOI18N
}
} else { // 32bit
if (isSolarisIntel()) {
procArch = "i386"; // NOI18N
} else if (isSolarisSparc()) {
procArch = "sparc"; // NOI18N
} else if (isHpux()) {
procArch = "pa_risc2.0"; // NOI18N
} else if (isLinuxArm()) {
if (isLinuxArmVfpHflt()) {
procArch = "arm-vfp-hflt"; // NOI18N
} else {
procArch = "arm"; // NOI18N
}
}
}
if (procArch != null) {
libSubDir += ("-" + procArch);
}
libSubPath = "/deployed/" + jdkString + "/" + libSubDir + "/"; // NOI18N
}
String fullPath = fullAgentPath;
if (fullAgentPath.startsWith("\"")) { // NOI18N
fullPath = fullAgentPath.substring(1, fullAgentPath.length() - 1);
}
fullPath = fullPath.replace('\\', '/'); // NOI18N
return fullPath + libSubPath + libPrefix + "profilerinterface" + libSuffix; // NOI18N
}
/**
* Returns JDK minor version
*/
public static int getJDKMinorNumber(String jdkVersionString) {
if (jdkVersionString == null) {
return 0;
}
int minorIndex = jdkVersionString.lastIndexOf('_'); // NOI18N
if ((minorIndex > 0) && (minorIndex < (jdkVersionString.length() - 1))) {
String minorString = jdkVersionString.substring(minorIndex + 1);
int subverIndex = minorString.indexOf('-'); // NOI18N
if (subverIndex != -1) {
minorString = minorString.substring(0, subverIndex);
}
return Integer.parseInt(minorString);
}
return 0;
}
/**
* Returns the JFluid-internal JDK version number
*/
private static int getJDKVersionNumber(String javaVersion) {
int jdkVersion;
if (javaVersion.startsWith("1.5")) { // NOI18N
jdkVersion = JDK_15;
} else if (javaVersion.startsWith("1.6")) { // NOI18N
jdkVersion = JDK_16;
} else if (javaVersion.startsWith("1.7")) { // NOI18N
jdkVersion = JDK_17;
} else if (javaVersion.startsWith("1.8")) { // NOI18N
jdkVersion = JDK_18;
} else if (javaVersion.startsWith("1.9")) { // NOI18N
jdkVersion = JDK_19;
} else if (javaVersion.startsWith("9")) { // NOI18N
jdkVersion = JDK_19;
} else if (javaVersion.equals("CVM")) { // NOI18N
jdkVersion = JDK_CVM;
} else {
try {
if (Integer.parseInt(javaVersion.replaceAll("[.\\-+].*", "")) >= 10) {
jdkVersion = JDK_110_BEYOND;
} else {
jdkVersion = JDK_UNSUPPORTED;
}
} catch (NumberFormatException ex) {
//ignore
jdkVersion = JDK_UNSUPPORTED;
}
}
return jdkVersion;
}
/**
* Returns the JFluid-internal JDK version number
*/
public static int getJDKVersionNumber() {
if (jdkVersion == 0) {
jdkVersion = getJDKVersionNumber(getJavaVersionString());
}
return jdkVersion;
}
/**
* Returns the string for, essentially, JFluid directory corresponding to a particular JDK version the TA runs on.
* Currently it's "jdk15" for JDK 1.5 version and "jdk16" for JDK 1.6 version, "jdk17" for JDK 1.7 version,
* "jdk18" for JDK 1.8 version and "cvm" for CVM
*/
public static String getJDKVersionString(String javaVersionString) {
int jdkVersionNumber = getJDKVersionNumber(javaVersionString);
switch (jdkVersionNumber) {
case JDK_15: return JDK_15_STRING;
case JDK_16: return JDK_16_STRING;
case JDK_17: return JDK_17_STRING;
case JDK_18: return JDK_18_STRING;
case JDK_19: return JDK_19_STRING;
case JDK_110_BEYOND: return JDK_110_BEYOND_STRING;
case JDK_CVM: return JDK_CVM_STRING;
case JDK_UNSUPPORTED: return JDK_UNSUPPORTED_STRING;
}
System.err.println("Unsupported java "+javaVersionString);
return JDK_UNSUPPORTED_STRING;
}
/**
* Returns the string for, essentially, JFluid directory corresponding to a particular JDK version the TA runs on.
* Currently it's "jdk15" for JDK 1.5 version, "jdk16" for JDK 1.6 version, "jdk17" for JDK 1.7 version,
* "jdk18" for JDK 1.8 version, "jdk19" for JDK 1.9 version and "cvm" for CVM
*/
public static String getJDKVersionString() {
if (jdkDenoteString == null) {
jdkDenoteString = getJDKVersionString(getJavaVersionString());
}
return jdkDenoteString;
}
public static String getJavaVersionString() {
// This is ugly hack for CVM. CVM cannot be identified using java.version
// system property and we have to use java.vm.name which is hardcoded
// to "CVM"
String vmVersion = System.getProperty("java.vm.name"); // NOI18N
if ("CVM".equals(vmVersion)) {
return vmVersion;
}
return System.getProperty("java.version"); // NOI18N
}
public static String getJFluidNativeLibDirName(String fullJFluidPath, String jdkString, int architecture) {
String jFluidNativeLibFullName = getAgentNativeLibFullName(fullJFluidPath, false, jdkString, architecture);
return jFluidNativeLibFullName.substring(0, jFluidNativeLibFullName.lastIndexOf('/')); // NOI18N
}
/**
* Test whether we are running on Linux
*/
public static boolean isLinux() {
return (getOperatingSystem() == OS_LINUX);
}
/**
* Test whether the supplied OS name is Linux
*/
public static boolean isLinux(String osName) {
return (getOperatingSystem(osName) == OS_LINUX);
}
public static boolean isMac() {
return (getOperatingSystem() == OS_MAC);
}
public static boolean isHpux() {
return (getOperatingSystem() == OS_HP);
}
/**
* Get the operating system on which we are is running.
* Returns one of the <code>OS_*</code> constants (such as {@link #OS_WINNT})
*/
public static int getOperatingSystem() {
if (operatingSystem == -1) {
String osName = System.getProperty("os.name"); // NOI18N
operatingSystem = getOperatingSystem(osName);
}
return operatingSystem;
}
public static int getOperatingSystem(String osName) {
if ("Windows NT".equals(osName)) { // NOI18N
return OS_WINNT;
} else if ("Windows 95".equals(osName)) { // NOI18N
return OS_WIN95;
} else if ("Windows 98".equals(osName)) { // NOI18N
return OS_WIN98;
} else if ("Windows 2000".equals(osName)) { // NOI18N
return OS_WIN2000;
} else if (osName.startsWith("Windows ")) { // NOI18N
return OS_WIN_OTHER;
} else if ("Solaris".equals(osName)) { // NOI18N
return OS_SOLARIS;
} else if (osName.startsWith("SunOS")) { // NOI18N
return OS_SOLARIS;
} else if (osName.endsWith("Linux")) { // NOI18N
return OS_LINUX;
} else if ("HP-UX".equals(osName)) { // NOI18N
return OS_HP;
} else if ("AIX".equals(osName)) { // NOI18N
return OS_AIX;
} else if ("Irix".equals(osName)) { // NOI18N
return OS_IRIX;
} else if ("SunOS".equals(osName)) { // NOI18N
return OS_SOLARIS;
} else if ("Digital UNIX".equals(osName)) { // NOI18N
return OS_TRU64;
} else if ("OS/2".equals(osName)) { // NOI18N
return OS_OS2;
} else if ("OpenVMS".equals(osName)) { // NOI18N
return OS_VMS;
} else if (osName.equalsIgnoreCase("mac os x")) { // NOI18N
return OS_MAC;
} else if (osName.startsWith("Darwin")) { // NOI18N
return OS_MAC;
} else {
return OS_OTHER;
}
}
public static String getProfilerUserDir() throws IOException {
String customDir = System.getProperty("nbprofiler.home"); // NOI18N
if (customDir != null) {
File d = new File(customDir);
if (!d.exists()) {
if (!d.mkdir()) {
throw new IOException("Could not create directory " + customDir); // NOI18N
}
}
return customDir;
} else {
// use default location
String dir = System.getProperty("user.home") + File.separator + ".nbprofiler"; // NOI18N
File d = new File(dir);
if (!d.exists()) {
if (!d.mkdir()) {
throw new IOException("Could not create directory " + dir); // NOI18N
}
}
return dir;
}
}
/**
* Test whether we are running on Solaris
*/
public static boolean isSolaris() {
return (getOperatingSystem() == OS_SOLARIS);
}
/**
* Test whether we are running on Solaris on Intel processor
*/
public static boolean isSolarisIntel() {
String procArch = System.getProperty("os.arch"); // NOI18N
return isSolaris() && (procArch.endsWith("86") || procArch.equals("amd64")); // NOI18N
}
/**
* Test whether we are running on Solaris on SPARC processor
*/
public static boolean isSolarisSparc() {
String procArch = System.getProperty("os.arch"); // NOI18N
return isSolaris() && procArch.startsWith("sparc"); // NOI18N
}
/**
* Test whether we are running on Linux on ARM processor
*/
public static boolean isLinuxArm() {
String procArch = System.getProperty("os.arch"); // NOI18N
return isLinux() && procArch.startsWith("arm"); // NOI18N
}
/**
* Test whether we are running on Linux on ARM processor with Hard float ABI
*/
public static boolean isLinuxArmVfpHflt() {
String procArch = System.getProperty("sun.arch.abi"); // NOI18N
return isLinux() && isLinuxArm() && "gnueabihf".equals(procArch); // NOI18N
}
/**
* Returns system architecture: 32/64bit
*/
public static int getSystemArchitecture() {
if (sysArch == 0) {
String architecture = System.getProperty("sun.arch.data.model"); // NOI18N
sysArch = getSystemArchitecture(architecture);
}
return sysArch;
}
public static int getSystemArchitecture(String arch) {
return "64".equals(arch) ? ARCH_64 : ARCH_32;
}
/**
* Test whether we are running on some variant of Unix. Linux is included as well as the commercial vendors.
*/
public static boolean isUnix() {
return (getOperatingSystem() & OS_UNIX_MASK) != 0;
}
/**
* Test whether we are is running on some variant of Windows
*/
public static boolean isWindows() {
return (getOperatingSystem() & OS_WINDOWS_MASK) != 0;
}
/**
* Test whether the supplied OS name is some variant of Windows
*/
public static boolean isWindows(String osName) {
return (getOperatingSystem(osName) & OS_WINDOWS_MASK) != 0;
}
/**
* Returns true if current system architecture is 32bit
*/
public static boolean is32bitArchitecture() {
return getSystemArchitecture() == ARCH_32;
}
/**
* Returns true if current system architecture is 64bit
*/
public static boolean is64bitArchitecture() {
return getSystemArchitecture() == ARCH_64;
}
/**
* Returns true if the given JVM version supports dynaimc attach
*/
public static boolean supportsDynamicAttach(String jdkVersionString) {
return CommonConstants.JDK_16_STRING.equals(jdkVersionString)
|| CommonConstants.JDK_17_STRING.equals(jdkVersionString)
|| CommonConstants.JDK_18_STRING.equals(jdkVersionString)
|| CommonConstants.JDK_19_STRING.equals(jdkVersionString)
|| CommonConstants.JDK_110_BEYOND_STRING.equals(jdkVersionString);
}
/**
* Returns true if the given JVM version passed as String correctly reports "sleeping" state
*/
public static boolean supportsThreadSleepingStateMonitoring(String jdkVersionString) {
return ((jdkVersionString != null)
&& (jdkVersionString.equals(JDK_15_STRING) ||
jdkVersionString.equals(JDK_16_STRING) ||
jdkVersionString.equals(JDK_17_STRING) ||
jdkVersionString.equals(JDK_18_STRING) ||
jdkVersionString.equals(JDK_19_STRING) ||
jdkVersionString.equals(JDK_110_BEYOND_STRING) ||
jdkVersionString.equals(JDK_CVM_STRING)));
}
/**
* Returns true if the current JVM correctly reports "sleeping" state
*/
public static boolean thisVMSupportsThreadSleepingStateMonitoring() {
return supportsThreadSleepingStateMonitoring(getJDKVersionNumber());
}
/**
* Returns true if the given JVM version number correctly reports "sleeping" state
*/
private static boolean supportsThreadSleepingStateMonitoring(int jdkVersionNumber) {
return ((jdkVersionNumber == JDK_15) ||
(jdkVersionNumber == JDK_16) ||
(jdkVersionNumber == JDK_17) ||
(jdkVersionNumber == JDK_18) ||
(jdkVersionNumber == JDK_19) ||
(jdkVersionNumber == JDK_110_BEYOND) ||
(jdkVersionNumber == JDK_CVM));
}
}