remove oshi dependency. #278

pull/539/head^2
hengyunabc 6 years ago
parent 54fbb6e602
commit 857488fffd

@ -16,10 +16,6 @@
<groupId>com.alibaba.middleware</groupId> <groupId>com.alibaba.middleware</groupId>
<artifactId>cli</artifactId> <artifactId>cli</artifactId>
</dependency> </dependency>
<dependency>
<groupId>com.github.oshi</groupId>
<artifactId>oshi-core</artifactId>
</dependency>
<dependency> <dependency>
<groupId>ch.qos.logback</groupId> <groupId>ch.qos.logback</groupId>

@ -0,0 +1,111 @@
package com.taobao.arthas.boot;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* A class for executing on the command line and returning the result of
* execution.
*
* @author alessandro[at]perucchi[dot]org
*/
public class ExecutingCommand {
private static final Logger LOG = LoggerFactory.getLogger(ExecutingCommand.class);
private ExecutingCommand() {
}
/**
* Executes a command on the native command line and returns the result.
*
* @param cmdToRun
* Command to run
* @return A list of Strings representing the result of the command, or empty
* string if the command failed
*/
public static List<String> runNative(String cmdToRun) {
String[] cmd = cmdToRun.split(" ");
return runNative(cmd);
}
/**
* Executes a command on the native command line and returns the result line by
* line.
*
* @param cmdToRunWithArgs
* Command to run and args, in an array
* @return A list of Strings representing the result of the command, or empty
* string if the command failed
*/
public static List<String> runNative(String[] cmdToRunWithArgs) {
Process p = null;
try {
p = Runtime.getRuntime().exec(cmdToRunWithArgs);
} catch (SecurityException e) {
LOG.trace("Couldn't run command {}: {}", Arrays.toString(cmdToRunWithArgs), e);
return new ArrayList<String>(0);
} catch (IOException e) {
LOG.trace("Couldn't run command {}: {}", Arrays.toString(cmdToRunWithArgs), e);
return new ArrayList<String>(0);
}
ArrayList<String> sa = new ArrayList<String>();
BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
try {
String line;
while ((line = reader.readLine()) != null) {
sa.add(line);
}
p.waitFor();
} catch (IOException e) {
LOG.trace("Problem reading output from {}: {}", Arrays.toString(cmdToRunWithArgs), e);
return new ArrayList<String>(0);
} catch (InterruptedException ie) {
LOG.trace("Interrupted while reading output from {}: {}", Arrays.toString(cmdToRunWithArgs), ie);
Thread.currentThread().interrupt();
} finally {
IOUtils.close(reader);
}
return sa;
}
/**
* Return first line of response for selected command.
*
* @param cmd2launch
* String command to be launched
* @return String or empty string if command failed
*/
public static String getFirstAnswer(String cmd2launch) {
return getAnswerAt(cmd2launch, 0);
}
/**
* Return response on selected line index (0-based) after running selected
* command.
*
* @param cmd2launch
* String command to be launched
* @param answerIdx
* int index of line in response of the command
* @return String whole line in response or empty string if invalid index or
* running of command fails
*/
public static String getAnswerAt(String cmd2launch, int answerIdx) {
List<String> sa = ExecutingCommand.runNative(cmd2launch);
if (answerIdx >= 0 && answerIdx < sa.size()) {
return sa.get(answerIdx);
}
return "";
}
}

@ -0,0 +1,38 @@
package com.taobao.arthas.boot;
/**
*
* @author hengyunabc 2018-11-08
*
*/
public class OSUtils {
static PlatformEnum platform;
static {
String osName = System.getProperty("os.name");
if (osName.startsWith("Linux")) {
platform = PlatformEnum.LINUX;
} else if (osName.startsWith("Mac") || osName.startsWith("Darwin")) {
platform = PlatformEnum.MACOSX;
} else if (osName.startsWith("Mac") || osName.startsWith("Darwin")) {
platform = PlatformEnum.MACOSX;
} else if (osName.startsWith("Windows")) {
platform = PlatformEnum.WINDOWS;
} else {
platform = PlatformEnum.UNKNOWN;
}
}
public static boolean isWindows() {
return platform == PlatformEnum.WINDOWS;
}
public static boolean isLinux() {
return platform == PlatformEnum.LINUX;
}
public static boolean isMac() {
return platform == PlatformEnum.MACOSX;
}
}

@ -0,0 +1,22 @@
package com.taobao.arthas.boot;
/**
* Enum of supported operating systems.
*
*/
public enum PlatformEnum {
/**
* Microsoft Windows
*/
WINDOWS,
/**
* A flavor of Linux
*/
LINUX,
/**
* macOS (OS X)
*/
MACOSX,
UNKNOWN;
}

@ -5,6 +5,7 @@ import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.lang.management.ManagementFactory;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Iterator; import java.util.Iterator;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
@ -15,10 +16,6 @@ import java.util.Scanner;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import oshi.SystemInfo;
import oshi.software.os.OSProcess;
import oshi.software.os.OperatingSystem;
/** /**
* *
* @author hengyunabc 2018-11-06 * @author hengyunabc 2018-11-06
@ -26,23 +23,41 @@ import oshi.software.os.OperatingSystem;
*/ */
public class ProcessUtils { public class ProcessUtils {
private static final Logger logger = LoggerFactory.getLogger(ProcessUtils.class); private static final Logger logger = LoggerFactory.getLogger(ProcessUtils.class);
private static String PID = "-1";
static {
// https://stackoverflow.com/a/7690178
String jvmName = ManagementFactory.getRuntimeMXBean().getName();
int index = jvmName.indexOf('@');
if (index > 0) {
try {
PID = Long.toString(Long.parseLong(jvmName.substring(0, index)));
} catch (Throwable e) {
// ignore
}
}
}
public static String getPid() {
return PID;
}
public static int select(boolean v) { public static int select(boolean v) {
Map<Integer, String> processMap = listProcessByJps(v); Map<Integer, String> processMap = listProcessByJps(v);
if(processMap.isEmpty()) {
processMap = listProcessByOshi();
}
if(processMap.isEmpty()) { if (processMap.isEmpty()) {
System.out.println("Can not find java process."); logger.info("Can not find java process.");
return -1; return -1;
} }
//print list // print list
int count = 1; int count = 1;
for(String process : processMap.values()) { for (String process : processMap.values()) {
if(count == 1) { if (count == 1) {
System.out.println("* [" + count + "]: " + process); System.out.println("* [" + count + "]: " + process);
}else { } else {
System.out.println(" [" + count + "]: " + process); System.out.println(" [" + count + "]: " + process);
} }
count++; count++;
@ -50,20 +65,20 @@ public class ProcessUtils {
// read choice // read choice
String line = new Scanner(System.in).nextLine(); String line = new Scanner(System.in).nextLine();
if(line.trim().isEmpty()) { if (line.trim().isEmpty()) {
// get the first process id // get the first process id
return processMap.keySet().iterator().next(); return processMap.keySet().iterator().next();
} }
int choice = new Scanner(line).nextInt(); int choice = new Scanner(line).nextInt();
if(choice <= 0 || choice > processMap.size()) { if (choice <= 0 || choice > processMap.size()) {
return -1; return -1;
} }
Iterator<Integer> idIter = processMap.keySet().iterator(); Iterator<Integer> idIter = processMap.keySet().iterator();
for(int i = 1; i <= choice; ++i) { for (int i = 1; i <= choice; ++i) {
if(i == choice) { if (i == choice) {
return idIter.next(); return idIter.next();
} }
idIter.next(); idIter.next();
@ -72,28 +87,11 @@ public class ProcessUtils {
return -1; return -1;
} }
private static Map<Integer, String> listProcessByOshi() {
SystemInfo info = new SystemInfo();
OperatingSystem operatingSystem = info.getOperatingSystem();
Map<Integer, String> result = new LinkedHashMap<Integer, String>();
OSProcess[] processes = operatingSystem.getProcesses(-1, null);
for (OSProcess p : processes) {
System.err.println(p);
System.err.println(p.getPath());
String path = p.getPath();
String name = new File(path).getName();
if (name.equals("java") || name.equals("java.exe")) {
result.put(p.getProcessID(), p.getProcessID() + " " + path);
}
}
return result;
}
private static Map<Integer, String> listProcessByJps(boolean v) { private static Map<Integer, String> listProcessByJps(boolean v) {
Map<Integer, String> result = new LinkedHashMap<Integer, String>(); Map<Integer, String> result = new LinkedHashMap<Integer, String>();
File jps = findJps(); File jps = findJps();
if(jps == null) { if (jps == null) {
return result; return result;
} }
@ -111,8 +109,12 @@ public class ProcessUtils {
// read the output from the command // read the output from the command
String line = null; String line = null;
int currentPid = Integer.parseInt(ProcessUtils.getPid());
while ((line = stdInput.readLine()) != null) { while ((line = stdInput.readLine()) != null) {
int pid = new Scanner(line).nextInt(); int pid = new Scanner(line).nextInt();
if (pid == currentPid) {
continue;
}
result.put(pid, line); result.put(pid, line);
} }
} catch (Throwable e) { } catch (Throwable e) {
@ -125,51 +127,46 @@ public class ProcessUtils {
public static void startArthasCore(int targetPid, List<String> attachArgs) { public static void startArthasCore(int targetPid, List<String> attachArgs) {
// find java/java.exe, then try to find tools.jar // find java/java.exe, then try to find tools.jar
SystemInfo info = new SystemInfo(); String javaHome = System.getProperty("java.home");
OperatingSystem operatingSystem = info.getOperatingSystem();
OSProcess processe = operatingSystem.getProcess(targetPid);
if(processe == null) {
throw new IllegalArgumentException("process do not exist! pid: " + targetPid);
}
String path = processe.getPath(); float javaVersion = Float.parseFloat(System.getProperty("java.specification.version"));
// some app like eclipse process path is not java/java.exe // find java/java.exe
if(!path.endsWith("java") && path.endsWith("java.exe")) { File javaPath = findJava();
OSProcess myselfProcess = operatingSystem.getProcess(operatingSystem.getProcessId()); if (javaPath == null) {
path = myselfProcess.getPath(); throw new IllegalArgumentException(
logger.warn("The target process is not an normal java process. try to start by using current java."); "Can not find java/java.exe executable file under java home: " + javaHome);
} }
File javaBinDir = new File(path).getParentFile(); File toolsJar = new File(javaHome, "../lib/tools.jar");
if (!toolsJar.exists()) {
// current/jre/bin/java
// current/bin/java
// current/lib/tools.jar
// after jdk9, there is no tools.jar
File toolsJar = new File(javaBinDir , "../lib/tools.jar");
if(!toolsJar.exists()) {
// maybe jre // maybe jre
toolsJar = new File(javaBinDir , "../../lib/tools.jar"); toolsJar = new File(javaHome, "../../lib/tools.jar");
}
if (javaVersion < 9.0f) {
if (!toolsJar.exists()) {
throw new IllegalArgumentException("Can not find tools.jar under java home: " + javaHome);
}
} }
List<String> command = new ArrayList<String>(); List<String> command = new ArrayList<String>();
command.add(path); command.add(javaPath.getAbsolutePath());
if(toolsJar.exists()) { if (toolsJar.exists()) {
command.add("-Xbootclasspath/a:" + toolsJar.getAbsolutePath()); command.add("-Xbootclasspath/a:" + toolsJar.getAbsolutePath());
} }
command.addAll(attachArgs); command.addAll(attachArgs);
// "${JAVA_HOME}"/bin/java \ // "${JAVA_HOME}"/bin/java \
// ${opts} \ // ${opts} \
// -jar "${arthas_lib_dir}/arthas-core.jar" \ // -jar "${arthas_lib_dir}/arthas-core.jar" \
// -pid ${TARGET_PID} \ // -pid ${TARGET_PID} \
// -target-ip ${TARGET_IP} \ // -target-ip ${TARGET_IP} \
// -telnet-port ${TELNET_PORT} \ // -telnet-port ${TELNET_PORT} \
// -http-port ${HTTP_PORT} \ // -http-port ${HTTP_PORT} \
// -core "${arthas_lib_dir}/arthas-core.jar" \ // -core "${arthas_lib_dir}/arthas-core.jar" \
// -agent "${arthas_lib_dir}/arthas-agent.jar" // -agent "${arthas_lib_dir}/arthas-agent.jar"
ProcessBuilder pb = new ProcessBuilder(command); ProcessBuilder pb = new ProcessBuilder(command);
try { try {
@ -205,7 +202,7 @@ public class ProcessUtils {
redirectStderr.join(); redirectStderr.join();
int exitValue = proc.exitValue(); int exitValue = proc.exitValue();
if(exitValue != 0) { if (exitValue != 0) {
logger.error("attach fail, targetPid: " + targetPid); logger.error("attach fail, targetPid: " + targetPid);
System.exit(1); System.exit(1);
} }
@ -215,6 +212,21 @@ public class ProcessUtils {
} }
private static File findJava() {
String javaHome = System.getProperty("java.home");
String[] paths = { "bin/java", "bin/java.exe", "../bin/java", "../bin/java.exe" };
for (String path : paths) {
File jpsFile = new File(javaHome, path);
if (jpsFile.exists()) {
return jpsFile;
}
}
logger.debug("can not find java under current java home: " + javaHome);
return null;
}
private static File findJps() { private static File findJps() {
String javaHome = System.getProperty("java.home"); String javaHome = System.getProperty("java.home");
String[] paths = { "bin/jps", "bin/jps.exe", "../bin/jps", "../bin/jps.exe" }; String[] paths = { "bin/jps", "bin/jps.exe", "../bin/jps", "../bin/jps.exe" };
@ -226,6 +238,7 @@ public class ProcessUtils {
} }
} }
logger.debug("can not find jps under current java home: " + javaHome);
return null; return null;
} }

@ -6,9 +6,6 @@ import java.util.List;
import javax.net.ServerSocketFactory; import javax.net.ServerSocketFactory;
import oshi.PlatformEnum;
import oshi.SystemInfo;
import oshi.util.ExecutingCommand;
/** /**
* *
@ -19,8 +16,7 @@ public class SocketUtils {
public static int findTcpListenProcess(int port) { public static int findTcpListenProcess(int port) {
try { try {
PlatformEnum platformEnum = SystemInfo.getCurrentPlatformEnum(); if (OSUtils.isWindows()) {
if (PlatformEnum.WINDOWS.equals(platformEnum)) {
String[] command = { "netstat", "-ano", "-p", "TCP" }; String[] command = { "netstat", "-ano", "-p", "TCP" };
List<String> lines = ExecutingCommand.runNative(command); List<String> lines = ExecutingCommand.runNative(command);
for (String line : lines) { for (String line : lines) {
@ -36,7 +32,7 @@ public class SocketUtils {
} }
} }
if (PlatformEnum.MACOSX.equals(platformEnum) || PlatformEnum.LINUX.equals(platformEnum)) { if (OSUtils.isLinux() || OSUtils.isMac()) {
String pid = ExecutingCommand.getFirstAnswer("lsof -t -s TCP:LISTEN -i TCP:" + port); String pid = ExecutingCommand.getFirstAnswer("lsof -t -s TCP:LISTEN -i TCP:" + port);
if (!pid.trim().isEmpty()) { if (!pid.trim().isEmpty()) {
return Integer.parseInt(pid); return Integer.parseInt(pid);

@ -172,11 +172,6 @@
<version>2.14.6</version> <version>2.14.6</version>
</dependency> </dependency>
<dependency>
<groupId>com.github.oshi</groupId>
<artifactId>oshi-core</artifactId>
<version>3.9.1</version>
</dependency>
</dependencies> </dependencies>
</dependencyManagement> </dependencyManagement>

Loading…
Cancel
Save