8230857: Avoid reflection in sun.tools.common.ProcessHelper
Reviewed-by: sspitsyn, dholmes
This commit is contained in:
parent
f92526e6fd
commit
8551294077
src/jdk.jcmd
linux/classes/sun/tools/common
share/classes/sun/tools/common
test/jdk/sun/tools/jcmd
@ -23,29 +23,21 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.tools;
|
||||
package sun.tools.common;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.jar.Attributes;
|
||||
import java.util.jar.JarFile;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* A helper class that retrieves the main class name for
|
||||
* a running Java process using the proc filesystem (procfs)
|
||||
*/
|
||||
public class ProcessHelper implements sun.tools.common.ProcessHelper {
|
||||
|
||||
final class ProcessHelper {
|
||||
|
||||
private static final String CMD_PREFIX = "cmd:";
|
||||
private static final ProcessHelper INSTANCE = new ProcessHelper();
|
||||
|
||||
public static ProcessHelper getInstance() {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the main class name for the given Java process by parsing the
|
||||
@ -57,8 +49,7 @@ public class ProcessHelper implements sun.tools.common.ProcessHelper {
|
||||
* @return the main class name or null if the process no longer exists or
|
||||
* was started with a native launcher (e.g. jcmd etc)
|
||||
*/
|
||||
|
||||
public String getMainClass(String pid) {
|
||||
static String getMainClass(String pid) {
|
||||
String cmdLine = getCommandLine(pid);
|
||||
if (cmdLine == null) {
|
||||
return null;
|
||||
@ -69,7 +60,7 @@ public class ProcessHelper implements sun.tools.common.ProcessHelper {
|
||||
String[] parts = cmdLine.split("\0");
|
||||
String mainClass = null;
|
||||
|
||||
if(parts.length == 0) {
|
||||
if (parts.length == 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -120,7 +111,6 @@ public class ProcessHelper implements sun.tools.common.ProcessHelper {
|
||||
mainClass = parts[i];
|
||||
}
|
||||
return mainClass;
|
||||
|
||||
}
|
||||
|
||||
private static String getCommandLine(String pid) {
|
||||
@ -134,16 +124,13 @@ public class ProcessHelper implements sun.tools.common.ProcessHelper {
|
||||
|
||||
private static boolean isModuleWhiteSpaceOption(String option) {
|
||||
return option.equals("-p") ||
|
||||
option.equals("--module-path") ||
|
||||
option.equals("--upgrade-module-path") ||
|
||||
option.equals("--add-modules") ||
|
||||
option.equals("--limit-modules") ||
|
||||
option.equals("--add-exports") ||
|
||||
option.equals("--add-opens") ||
|
||||
option.equals("--add-reads") ||
|
||||
option.equals("--patch-module");
|
||||
option.equals("--module-path") ||
|
||||
option.equals("--upgrade-module-path") ||
|
||||
option.equals("--add-modules") ||
|
||||
option.equals("--limit-modules") ||
|
||||
option.equals("--add-exports") ||
|
||||
option.equals("--add-opens") ||
|
||||
option.equals("--add-reads") ||
|
||||
option.equals("--patch-module");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -79,15 +79,10 @@ public class ProcessArgumentMatcher {
|
||||
|
||||
private static boolean check(VirtualMachineDescriptor vmd, String excludeClass, String partialMatch) {
|
||||
|
||||
String mainClass = null;
|
||||
// Try to get the main class name using (platform specific) ProcessHelper
|
||||
String mainClass = ProcessHelper.getMainClass(vmd.id());
|
||||
|
||||
// Get the main class name using platform specific helper
|
||||
ProcessHelper helper = ProcessHelper.platformProcessHelper();
|
||||
if (helper != null) {
|
||||
mainClass = helper.getMainClass(vmd.id());
|
||||
}
|
||||
|
||||
// If the main class name is still unset then retrieve it with the attach mechanism
|
||||
// If the main class name could not be retrieved by ProcessHelper, get it with the attach mechanism
|
||||
if (mainClass == null) {
|
||||
try {
|
||||
VmIdentifier vmId = new VmIdentifier(vmd.id());
|
||||
|
@ -25,33 +25,12 @@
|
||||
|
||||
package sun.tools.common;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
* A helper class to retrieve the main class name for a running
|
||||
* Java process.
|
||||
* Java process. Default implementation returns null. Platform specific
|
||||
* implementation currently available for Linux only.
|
||||
*/
|
||||
|
||||
public interface ProcessHelper {
|
||||
|
||||
/**
|
||||
* Returns an instance of the ProcessHelper class.
|
||||
*
|
||||
* @return ProcessHelper object or null if not supported on this platform.
|
||||
*/
|
||||
public static ProcessHelper platformProcessHelper() {
|
||||
try {
|
||||
Class<?> c = Class.forName("sun.tools.ProcessHelper");
|
||||
@SuppressWarnings("unchecked")
|
||||
Method m = c.getMethod("getInstance");
|
||||
return (ProcessHelper) m.invoke(null);
|
||||
} catch (ClassNotFoundException e) {
|
||||
return null;
|
||||
} catch (ReflectiveOperationException e) {
|
||||
throw new InternalError(e);
|
||||
}
|
||||
}
|
||||
|
||||
final class ProcessHelper {
|
||||
|
||||
/**
|
||||
* Returns the main class name for the given Java process
|
||||
@ -59,6 +38,7 @@ public interface ProcessHelper {
|
||||
* @param pid - process ID (pid)
|
||||
* @return main class name or null if the main class could not be retrieved
|
||||
*/
|
||||
|
||||
String getMainClass(String pid);
|
||||
static String getMainClass(String pid) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -21,16 +21,13 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import jdk.internal.module.ModuleInfoWriter;
|
||||
import jdk.test.lib.JDKToolFinder;
|
||||
import jdk.test.lib.process.ProcessTools;
|
||||
import jdk.test.lib.util.JarUtils;
|
||||
import sun.tools.common.ProcessHelper;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.lang.invoke.MethodHandle;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.lang.module.ModuleDescriptor;
|
||||
import java.lang.reflect.Method;
|
||||
import java.nio.file.FileSystems;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
@ -44,6 +41,11 @@ import java.util.jar.Manifest;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import jdk.internal.module.ModuleInfoWriter;
|
||||
import jdk.test.lib.JDKToolFinder;
|
||||
import jdk.test.lib.process.ProcessTools;
|
||||
import jdk.test.lib.util.JarUtils;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8205654
|
||||
@ -52,15 +54,13 @@ import java.util.stream.Stream;
|
||||
*
|
||||
* @requires os.family == "linux"
|
||||
* @library /test/lib
|
||||
* @modules jdk.jcmd/sun.tools.common
|
||||
* @modules jdk.jcmd/sun.tools.common:+open
|
||||
* java.base/jdk.internal.module
|
||||
* @build test.TestProcess
|
||||
* @run main/othervm TestProcessHelper
|
||||
*/
|
||||
public class TestProcessHelper {
|
||||
|
||||
private ProcessHelper PROCESS_HELPER = ProcessHelper.platformProcessHelper();
|
||||
|
||||
private static final String TEST_PROCESS_MAIN_CLASS_NAME = "TestProcess";
|
||||
private static final String TEST_PROCESS_MAIN_CLASS_PACKAGE = "test";
|
||||
private static final String TEST_PROCESS_MAIN_CLASS = TEST_PROCESS_MAIN_CLASS_PACKAGE + "."
|
||||
@ -89,6 +89,29 @@ public class TestProcessHelper {
|
||||
|
||||
private static final String[] PATCH_MODULE_OPTIONS = {"--patch-module", null};
|
||||
|
||||
private static final MethodHandle MH_GET_MAIN_CLASS = resolveMainClassMH();
|
||||
|
||||
private static MethodHandle resolveMainClassMH() {
|
||||
try {
|
||||
Method getMainClassMethod = Class
|
||||
.forName("sun.tools.common.ProcessHelper")
|
||||
.getDeclaredMethod("getMainClass", String.class);
|
||||
getMainClassMethod.setAccessible(true);
|
||||
return MethodHandles.lookup().unreflect(getMainClassMethod);
|
||||
} catch (ClassNotFoundException | NoSuchMethodException | SecurityException | IllegalAccessException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private static String callGetMainClass(Process p) {
|
||||
try {
|
||||
return (String)MH_GET_MAIN_CLASS.invoke(Long.toString(p.pid()));
|
||||
} catch (Throwable e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
new TestProcessHelper().runTests();
|
||||
}
|
||||
@ -188,7 +211,7 @@ public class TestProcessHelper {
|
||||
}
|
||||
|
||||
private void checkMainClass(Process p, String expectedMainClass) {
|
||||
String mainClass = PROCESS_HELPER.getMainClass(Long.toString(p.pid()));
|
||||
String mainClass = callGetMainClass(p);
|
||||
// getMainClass() may return null, e.g. due to timing issues.
|
||||
// Attempt some limited retries.
|
||||
if (mainClass == null) {
|
||||
@ -204,7 +227,7 @@ public class TestProcessHelper {
|
||||
} catch (InterruptedException e) {
|
||||
// ignore
|
||||
}
|
||||
mainClass = PROCESS_HELPER.getMainClass(Long.toString(p.pid()));
|
||||
mainClass = callGetMainClass(p);
|
||||
retrycount++;
|
||||
sleepms *= 2;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user