ja-netfilter/src/main/java/com/janetfilter/core/attach/VMSelector.java

112 lines
4.1 KiB
Java

package com.janetfilter.core.attach;
import com.janetfilter.core.utils.DateUtils;
import com.janetfilter.core.utils.ProcessUtils;
import com.janetfilter.core.utils.WhereIsUtils;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
public class VMSelector {
private final File thisJar;
private List<VMDescriptor> descriptors;
public VMSelector(File thisJar) {
this.thisJar = thisJar;
}
private List<VMDescriptor> getVMList() throws Exception {
File jpsCommand = WhereIsUtils.findJPS();
if (null == jpsCommand) {
throw new Exception("jps command not found");
}
List<String> list = new ArrayList<>();
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ProcessUtils.start(new ProcessBuilder(jpsCommand.getAbsolutePath(), "-lv"), bos);
String line;
BufferedReader reader = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(bos.toByteArray())));
while ((line = reader.readLine()) != null) {
list.add(line);
}
String processId = ProcessUtils.currentId();
return list.stream()
.map(s -> {
String[] section = (s + " ").split(" ", 3);
return new VMDescriptor(section[0].trim(), section[1].trim(), section[2].trim());
})
.filter(d -> !d.getId().equals(processId) && !"sun.tools.jps.Jps".equals(d.getClassName()) && !"jdk.jcmd/sun.tools.jps.Jps".equals(d.getClassName()))
.sorted(Comparator.comparingInt(d -> Integer.parseInt(d.getId())))
.collect(Collectors.toList());
}
private String getInput() throws IOException {
return new BufferedReader(new InputStreamReader(System.in)).readLine().trim();
}
private void processSelect() throws Exception {
System.out.print(" Select: ");
String input = getInput();
switch (input) {
case "Q":
case "q":
System.exit(0);
case "R":
case "r":
System.out.println(" =========================== " + DateUtils.formatDateTime() + " ============================");
select();
return;
default:
VMDescriptor targetVmDescriptor;
try {
int seq = Integer.parseInt(input);
targetVmDescriptor = descriptors.get(seq - 1);
} catch (NumberFormatException | IndexOutOfBoundsException e) {
System.err.println("> Invalid input: " + input);
processSelect();
return;
}
System.out.print(" Agent args: ");
input = getInput();
try {
VMLauncher.launch(thisJar, targetVmDescriptor, input);
} catch (Exception e) {
System.err.println("> Attach failed.");
e.printStackTrace(System.err);
}
}
}
public void select() throws Exception {
boolean first = null == descriptors;
List<VMDescriptor> temp = getVMList();
if (null != descriptors && !descriptors.isEmpty()) {
temp.forEach(d -> d.setOld(descriptors.stream().anyMatch(d1 -> d.getId().equals(d1.getId()))));
}
descriptors = temp;
System.out.println(" Java Virtual Machine List: (Select and attach" + (first ? "" : ", + means the new one") + ")");
int index = 1;
for (VMDescriptor d : descriptors) {
System.out.printf(" %3d]:%s%s %s%n", index++, d.getOld() ? " " : "+", d.getId(), d.getClassName());
}
System.out.println(" r]: <Refresh virtual machine list>");
System.out.println(" q]: <Quit the ja-netfilter>");
processSelect();
}
}