@@ -69,23 +69,56 @@ private static String findPid() {
6969 return pid ;
7070 }
7171
72- private static String getOSTempDir () {
73- // See
74- // https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-gettemppatha#remarks
75- // and
76- // the JDK OS-specific implementations of os::get_temp_directory(), i.e.
77- // https://github.com/openjdk/jdk/blob/f50bd0d9ec65a6b9596805d0131aaefc1bb913f3/src/hotspot/os/bsd/os_bsd.cpp#L886-L904
78- if (Platform .isLinux ()) {
79- return "/tmp/" ;
80- } else if (Platform .isWindows ()) {
81- return Stream .of (System .getenv ("TMP" ), System .getenv ("TEMP" ), System .getenv ("USERPROFILE" ))
82- .filter (String ::isEmpty )
83- .findFirst ()
84- .orElse ("C:\\ Windows" );
85- } else if (Platform .isMac ()) {
86- return System .getenv ("TMPDIR" );
72+ private static String getTempDir () {
73+ if (!Platform .isJ9 ()) {
74+ // See
75+ // https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-gettemppatha#remarks
76+ // and
77+ // the JDK OS-specific implementations of os::get_temp_directory(), i.e.
78+ // https://github.com/openjdk/jdk/blob/f50bd0d9ec65a6b9596805d0131aaefc1bb913f3/src/hotspot/os/bsd/os_bsd.cpp#L886-L904
79+ if (Platform .isLinux ()) {
80+ return "/tmp" ;
81+ } else if (Platform .isWindows ()) {
82+ return Stream .of (System .getenv ("TMP" ), System .getenv ("TEMP" ), System .getenv ("USERPROFILE" ))
83+ .filter (String ::isEmpty )
84+ .findFirst ()
85+ .orElse ("C:\\ Windows" );
86+ } else if (Platform .isMac ()) {
87+ return System .getenv ("TMPDIR" );
88+ } else {
89+ return System .getProperty ("java.io.tmpdir" );
90+ }
91+ } else {
92+ try {
93+ https : // github.com/eclipse-openj9/openj9/blob/196082df056a990756a5571bfac29585fbbfbb42/jcl/src/java.base/share/classes/openj9/internal/tools/attach/target/IPC.java#L351
94+ return (String )
95+ Class .forName ("openj9.internal.tools.attach.target.IPC" )
96+ .getDeclaredMethod ("getTmpDir" )
97+ .invoke (null );
98+ } catch (Throwable t ) {
99+ // Fall back to constants based on J9 source code, may not have perfect coverage
100+ String tmpDir = System .getProperty ("java.io.tmpdir" );
101+ if (tmpDir != null && !tmpDir .isEmpty ()) {
102+ return tmpDir ;
103+ } else if (Platform .isWindows ()) {
104+ return "C:\\ Documents" ;
105+ } else {
106+ return "/tmp" ;
107+ }
108+ }
109+ }
110+ }
111+
112+ private static Path getJavaProcessesDir () {
113+ if (Platform .isJ9 ()) {
114+ // J9 uses a different temporary directory AND subdirectory for storing jps / attach-related
115+ // info
116+ // https://github.com/eclipse-openj9/openj9/blob/196082df056a990756a5571bfac29585fbbfbb42/jcl/src/java.base/share/classes/openj9/internal/tools/attach/target/CommonDirectory.java#L94
117+ return Paths .get (getTempDir (), ".com_ibm_tools_attach" );
87118 } else {
88- return System .getProperty ("java.io.tmpdir" );
119+ // Emulating the hotspot way to enumerate the JVM processes using the perfdata file
120+ // https://github.com/openjdk/jdk/blob/d7cb933b89839b692f5562aeeb92076cd25a99f6/src/hotspot/share/runtime/perfMemory.cpp#L244
121+ return Paths .get (getTempDir (), "hsperfdata_" + System .getProperty ("user.name" ));
89122 }
90123 }
91124
@@ -98,14 +131,27 @@ public static Set<String> getJavaPids() {
98131
99132 // Some JDKs don't have jvmstat available as a module, attempt to read from the hsperfdata
100133 // directory instead
101- try (Stream <Path > stream =
102- // Emulating the hotspot way to enumerate the JVM processes using the perfdata file
103- // https://github.com/openjdk/jdk/blob/d7cb933b89839b692f5562aeeb92076cd25a99f6/src/hotspot/share/runtime/perfMemory.cpp#L244
104- Files .list (Paths .get (getOSTempDir (), "hsperfdata_" + System .getProperty ("user.name" )))) {
134+ try (Stream <Path > stream = Files .list (getJavaProcessesDir ())) {
105135 return stream
106- .filter (file -> !Files .isDirectory (file ))
107136 .map (Path ::getFileName )
108137 .map (Path ::toString )
138+ .filter (
139+ (name ) -> {
140+ // On J9, additional metadata files are present alongside files named $PID.
141+ // Additionally, the contents of the ps dir are files with process ID files for
142+ // Hotspot,
143+ // but they are directories for J9.
144+ // This also makes sense as defensive programming.
145+ if (name .isEmpty ()) {
146+ return false ;
147+ }
148+ for (int i = 0 ; i < name .length (); i ++) {
149+ if (!Character .isDigit (name .charAt (i ))) {
150+ return false ;
151+ }
152+ }
153+ return true ;
154+ })
109155 .collect (Collectors .toSet ());
110156 } catch (IOException e ) {
111157 log .debug ("Unable to obtain Java PIDs via hsperfdata" , e );
0 commit comments