diff --git a/core/src/main/groovy/noe/common/newcmd/KillCmdBuilder.java b/core/src/main/groovy/noe/common/newcmd/KillCmdBuilder.java index a19217c2..14954f37 100644 --- a/core/src/main/groovy/noe/common/newcmd/KillCmdBuilder.java +++ b/core/src/main/groovy/noe/common/newcmd/KillCmdBuilder.java @@ -67,8 +67,8 @@ public KillCmdBuilder addProcessId(final String... processIds) { * @param processIds process ids to kill as integer * @return this */ - public KillCmdBuilder addProcessId(final int... processIds) { - for(int processId: processIds) { + public KillCmdBuilder addProcessId(final long... processIds) { + for(long processId: processIds) { String stringProcessId = String.valueOf(processId); addProcessId(stringProcessId); } diff --git a/core/src/main/groovy/noe/common/newcmd/ListProcess.java b/core/src/main/groovy/noe/common/newcmd/ListProcess.java index 11557889..c36b7f6f 100644 --- a/core/src/main/groovy/noe/common/newcmd/ListProcess.java +++ b/core/src/main/groovy/noe/common/newcmd/ListProcess.java @@ -180,7 +180,7 @@ public Collection listParentPids(final int processId) throws IOExceptio * @return list of map where information about processes in the tree is saved * @throws IOException when not possible to run the process list command */ - public List> listProcessTree(final int processId) throws IOException { + public List> listProcessTree(final long processId) throws IOException { ListProcessData data = listAll(PsCmdFormat.PROCESS_ID, PsCmdFormat.PARENT_PROCESS_ID, PsCmdFormat.COMMAND); ImmutableList.Builder> psTreeBuilder = ImmutableList.>builder(); @@ -196,7 +196,7 @@ public List> listProcessTree(final int processId) throw List listOfIdsToCheck = new ArrayList(); List listOfIdsInProgress = new ArrayList(); - listOfIdsToCheck.add(Integer.toString(processId)); + listOfIdsToCheck.add(Long.toString(processId)); // passing through ps results to get all the process three (filter returns filtered copy of data) while (!listOfIdsToCheck.isEmpty()) { @@ -246,7 +246,7 @@ public ListProcessData listProcessInfo(final int processId) throws IOException { * @return process info * @throws IOException when some error on execution happens */ - public String printProcessInfo(final int processId) throws IOException, InterruptedException { + public String printProcessInfo(final long processId) throws IOException, InterruptedException { CmdBuilder builder = new CmdBuilder(""); if (platform.isWindows()) { builder.setBaseCommand("wmic"); diff --git a/core/src/main/groovy/noe/common/newcmd/ListProcessData.java b/core/src/main/groovy/noe/common/newcmd/ListProcessData.java index 0f238e7a..ddb2e787 100644 --- a/core/src/main/groovy/noe/common/newcmd/ListProcessData.java +++ b/core/src/main/groovy/noe/common/newcmd/ListProcessData.java @@ -116,7 +116,7 @@ public int size() { * @param processId process id that should be search in data * @return info on data */ - public Map get(final int processId) { + public Map get(final long processId) { String processIdAsString = String.valueOf(processId); if(listing.get(processIdAsString) == null) { return null; @@ -328,15 +328,36 @@ public int compare(final Map left, final Map> processTree = listProcessUtil.listProcessTree(pid); @@ -594,10 +594,10 @@ public class Cmd { killBuilder.addProcessId(pid); return Cmd.executeCommand(killBuilder.build().getCommandLine(), new File(".")) != null } else { - int[] processTreePidArray = new int[processTree.size()]; + long[] processTreePidArray = new long[processTree.size()]; int i = 0; for(Map processTreeRecord: processTree) { - processTreePidArray[i++] = Integer.valueOf(processTreeRecord.get(PsCmdFormat.PROCESS_ID)); + processTreePidArray[i++] = Long.valueOf(processTreeRecord.get(PsCmdFormat.PROCESS_ID)); } log.debug("*nix platform: destroying process tree of {} as list of pids {}", pid, processTreePidArray); @@ -742,8 +742,8 @@ public class Cmd { } - static Set retrievePidsByRegexpFromProcOutput(Process proc, regexp) { - Set pids = new HashSet<>() + static Set retrievePidsByRegexpFromProcOutput(Process proc, regexp) { + Set pids = new HashSet<>() proc.in.eachLine { line -> log.debug("Found process to matching ${regexp}: ${line}") @@ -751,7 +751,7 @@ public class Cmd { if (match.groupCount() > 0 && match.size() > 0 && match[0].size() > 0) { String pid = match[0][1] try { - pids.add(Integer.parseInt(pid)) + pids.add(Long.parseLong(pid)) } catch (NumberFormatException ex) { log.debug("We don't care that line contained an invalid processCode to parse: ${pid}. Continuing...") } @@ -761,9 +761,9 @@ public class Cmd { } - static Integer extractPid(identifier) { + static Long extractPid(identifier) { log.debug("Extracting pid using identifier ${identifier}") - List pids = extractPids(identifier, false) + List pids = extractPids(identifier, false) if (pids.isEmpty()) { return null } @@ -788,8 +788,8 @@ public class Cmd { } } - static List extractUNIXPids(identifier, getAll = true) { - List pids = [] + static List extractUNIXPids(identifier, getAll = true) { + List pids = [] final String ALL_FAILED = "All pid extraction options have failed, including the last resort 'pargs' one. This means that the application the pid of which we were trying to" + "extract hadn't been started in a supported way. Hint: domain.sh? any custom launch script?" /** @@ -841,7 +841,7 @@ public class Cmd { /** * Now, we will collect all java processes. */ - List javaPids = [] + List javaPids = [] proc2.in.eachLine { line -> def match = line =~ psRegExp log.trace("Java processes match.groupCount(): ${match.groupCount()}") @@ -852,7 +852,7 @@ public class Cmd { } String pid = match[0][1] try { - javaPids.add(Integer.parseInt(pid)) + javaPids.add(Long.parseLong(pid)) } catch (NumberFormatException ex) { log.error("Error trying to parse process ID from: \"${pid}\"") throw ex @@ -896,7 +896,7 @@ public class Cmd { log.trace("1) match proc4.text: ${line}") String pid = match[0][1] try { - pids.add(Integer.parseInt(pid)) + pids.add(Long.parseLong(pid)) } catch (NumberFormatException ex) { log.error("Error trying to parse process ID from: \"${pid}\"") throw ex @@ -906,8 +906,8 @@ public class Cmd { return pids } - static List extractWindowsPids(identifier, getAll = true) { - List pids = [] + static List extractWindowsPids(identifier, getAll = true) { + List pids = [] /** * WINDOWS STUFF @@ -952,7 +952,7 @@ public class Cmd { if (match.size() > 0 && match[0].size() >= 2 && possibleWindowTitlesIds.any { it == match[0][2]}) { String pid = match[0][1] try { - pids.add(Integer.parseInt(pid)) + pids.add(Long.parseLong(pid)) } catch (NumberFormatException ex) { log.error("Error trying to parse process ID from: \"${pid}\"") throw ex @@ -968,7 +968,7 @@ public class Cmd { return pids } - static boolean killSpecifiedProcesses(Collection pidList = []) { + static boolean killSpecifiedProcesses(Collection pidList = []) { if (!pidList) { log.debug("No process IDs given => nothing to kill") return false @@ -1012,7 +1012,7 @@ public class Cmd { /** * Wait until is PID removed from system - at max. timeout */ - static boolean waitForPidRemoved(Integer pid, int timeout = 30) { + static boolean waitForPidRemoved(Long pid, int timeout = 30) { if (!pid) return true int now = 0 @@ -1036,11 +1036,11 @@ public class Cmd { /** * Check if PID exists in a system - process is present in system */ - static boolean pidExists(Integer pid) { + static boolean pidExists(Long pid) { def res = false try { - res = getPidList().contains(Integer.valueOf(pid)) + res = getPidList().contains(pid) } catch (e) { } @@ -1054,7 +1054,7 @@ public class Cmd { * * @return true if none of the pids provided exist in the system, false otherwise */ - static boolean waitForPidsRemoved(List pids, int timeout, TimeUnit timeUnit) { + static boolean waitForPidsRemoved(List pids, int timeout, TimeUnit timeUnit) { long maxTime = System.currentTimeMillis() + timeUnit.toMillis(timeout) boolean anyPidExist = !getPidList().intersect(pids).isEmpty() while (anyPidExist && System.currentTimeMillis() <= maxTime) { @@ -1096,7 +1096,7 @@ public class Cmd { /** * Extract all PIDS from the underlying system */ - static List getPidList() { + static List getPidList() { def res = [] def row = [] def command @@ -1118,7 +1118,7 @@ public class Cmd { else row = line.split() as List // on all tested system is PID in 2nd col - if (!row[1].contains("PID")) res << Integer.parseInt(row[1].replaceAll('"', '')) + if (!row[1].contains("PID")) res << Long.parseLong(row[1].replaceAll('"', '')) } return res diff --git a/core/src/main/groovy/noe/common/utils/processid/ProcessUtils.groovy b/core/src/main/groovy/noe/common/utils/processid/ProcessUtils.groovy index f08dea61..c23d995c 100644 --- a/core/src/main/groovy/noe/common/utils/processid/ProcessUtils.groovy +++ b/core/src/main/groovy/noe/common/utils/processid/ProcessUtils.groovy @@ -1,9 +1,11 @@ package noe.common.utils.processid; import com.sun.jna.Pointer; +import noe.common.utils.Java; import noe.common.utils.Platform; import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; /** * Util class that helps getting different information from Process object. @@ -11,10 +13,14 @@ import java.lang.reflect.Field; * Borrowed implementation of methods for retrieving processId from Process class from other Red Hat test suites */ public final class ProcessUtils { - public static final int UNDEFINED_PROCESS_ID = -1; + public static final long UNDEFINED_PROCESS_ID = Long.MIN_VALUE; private static final Platform platform = new Platform(); - public static int getProcessId(final Process process) { + public static long getProcessId(final Process process) { + if (Java.isJdkXOrHigher("9")) { + return getProcessIdJava9AndNewer(process); + } + if (platform.isWindows()) { return getWindowsProcessId(process); } else { @@ -28,12 +34,10 @@ public final class ProcessUtils { * @param process running process * @return process id */ - public static int getWindowsProcessId(final Process process) { - int processId = UNDEFINED_PROCESS_ID; - + public static long getWindowsProcessId(final Process process) { if (process.getClass().getName().equals("java.lang.Win32Process") || process.getClass().getName().equals("java.lang.ProcessImpl")) { - /* determine the process id on windows plattforms */ + /* determine the process id on windows platforms */ try { Field f = process.getClass().getDeclaredField("handle"); f.setAccessible(true); @@ -42,12 +46,12 @@ public final class ProcessUtils { Kernel32 kernel = Kernel32.INSTANCE; W32API.HANDLE handle = new W32API.HANDLE(); handle.setPointer(Pointer.createConstant(handl)); - processId = kernel.GetProcessId(handle); + return kernel.GetProcessId(handle); } catch (Throwable e) { - throw new RuntimeException("Not able to get process id on Windows " + processId, e); + throw new RuntimeException("Not able to get process id of process " + process, e); } } - return processId; + return UNDEFINED_PROCESS_ID; } /** @@ -56,8 +60,8 @@ public final class ProcessUtils { * @param process running process * @return process id */ - public static int getUnixProcessId(final Process process) { - int processId = UNDEFINED_PROCESS_ID; + public static long getUnixProcessId(final Process process) { + long processId = UNDEFINED_PROCESS_ID; if (process.getClass().getName().equals("java.lang.UNIXProcess") || process.getClass().getName().equals("java.lang.ProcessImpl")) { @@ -65,15 +69,26 @@ public final class ProcessUtils { try { Field f = process.getClass().getDeclaredField("pid"); f.setAccessible(true); - processId = f.getInt(process); + processId = f.getLong(process); } catch (Throwable e) { - throw new RuntimeException("Not able to get process id on Unix " + processId, e); + throw new RuntimeException("Not able to get process id of process " + process, e); } } return processId; } + private static long getProcessIdJava9AndNewer(final Process process) { + try { + // although the method is public, we are using reflection to execute it to be able to compile on JDK8 + // as the method exists only in JDK9+ + return (long) Process.class.getDeclaredMethod("pid").invoke(process); + } catch (SecurityException | NoSuchMethodException e) { + throw new RuntimeException("Not able to get process id of process " + process, e); + } + } + + /** * Checks whether process is alive (still running) or not. * @param proc - process to be checked diff --git a/core/src/main/groovy/noe/ews/server/httpd/HttpdRpm.groovy b/core/src/main/groovy/noe/ews/server/httpd/HttpdRpm.groovy index 060e8e54..3eb55815 100644 --- a/core/src/main/groovy/noe/ews/server/httpd/HttpdRpm.groovy +++ b/core/src/main/groovy/noe/ews/server/httpd/HttpdRpm.groovy @@ -64,13 +64,13 @@ class HttpdRpm extends Httpd { return new File("/var/run/${serviceName}/${serviceName}.pid") } - Integer extractPid() { + Long extractPid() { def pidAsStr = new ByteArrayOutputStream() if (Cmd.executeCommandRedirectIO("sudo cat ${getPidFile()}", null, null, pidAsStr, System.err) == 0) { pidAsStr = pidAsStr.toString() pidAsStr = pidAsStr.trim() pidAsStr = pidAsStr.replaceAll('"', '') - pid = Integer.valueOf(pidAsStr) + pid = Long.valueOf(pidAsStr) return pid } else { diff --git a/core/src/main/groovy/noe/ews/server/tomcat/TomcatSolaris.groovy b/core/src/main/groovy/noe/ews/server/tomcat/TomcatSolaris.groovy index 3b5a502d..b20d6cd5 100644 --- a/core/src/main/groovy/noe/ews/server/tomcat/TomcatSolaris.groovy +++ b/core/src/main/groovy/noe/ews/server/tomcat/TomcatSolaris.groovy @@ -101,10 +101,10 @@ class TomcatSolaris extends Tomcat { return result } - Integer extractPid() { + Long extractPid() { try { String pidFromFile = JBFile.read(pidFile).trim().replaceAll('"', '') - pid = Integer.valueOf(pidFromFile) + pid = Long.valueOf(pidFromFile) } catch (e) { pid = super.extractPid() } diff --git a/core/src/main/groovy/noe/rhel/server/httpd/HttpdBaseOS.groovy b/core/src/main/groovy/noe/rhel/server/httpd/HttpdBaseOS.groovy index 436de274..4f938b95 100644 --- a/core/src/main/groovy/noe/rhel/server/httpd/HttpdBaseOS.groovy +++ b/core/src/main/groovy/noe/rhel/server/httpd/HttpdBaseOS.groovy @@ -64,8 +64,8 @@ class HttpdBaseOS extends Httpd { return new File("/var/run/${serviceName}/${serviceName}.pid") } - Integer extractPid() { - int pid + Long extractPid() { + long pid try { String pidFromFile = JBFile.read(pidFile).trim().replaceAll('"','') pid = Integer.valueOf(pidFromFile) diff --git a/core/src/main/groovy/noe/rhel/server/tomcat/TomcatRpm.groovy b/core/src/main/groovy/noe/rhel/server/tomcat/TomcatRpm.groovy index d9de83b9..de49b7d2 100644 --- a/core/src/main/groovy/noe/rhel/server/tomcat/TomcatRpm.groovy +++ b/core/src/main/groovy/noe/rhel/server/tomcat/TomcatRpm.groovy @@ -81,7 +81,7 @@ class TomcatRpm extends Tomcat { // Try to search for 'CATALINA_PID' in file content def m = fileText =~ /CATALINA_PID=(.*)/ - // Get value - actually we want last occurence of CATALINA_PID as that + // Get value - actually we want last occurrence of CATALINA_PID as that // possibly rewrites all preceding occurrences. for (int i = m.size()-1; i >= 0; i--) { if (m[i].size() > 1) { @@ -108,12 +108,12 @@ class TomcatRpm extends Tomcat { } } - Integer extractPid() { + Long extractPid() { try { def pidAsStr = pidFile.text pidAsStr = pidAsStr.trim() pidAsStr = pidAsStr.replaceAll('"', '') - pid = Integer.valueOf(pidAsStr) + pid = Long.valueOf(pidAsStr) } catch (e) { log.debug("PID file is not accessible. But continuing ...") diff --git a/core/src/main/groovy/noe/server/Fuse.groovy b/core/src/main/groovy/noe/server/Fuse.groovy index 81491a54..0aeb4859 100644 --- a/core/src/main/groovy/noe/server/Fuse.groovy +++ b/core/src/main/groovy/noe/server/Fuse.groovy @@ -76,7 +76,7 @@ public class Fuse extends ServerAbstract { } @Override - Integer extractPid() { + Long extractPid() { File instancePropsFile = new File(basedir, "instances${platform.sep}instance.properties") if (instancePropsFile.exists()) { int serverPid = retrievePidFromInstancesPropsFile(instancePropsFile) diff --git a/core/src/main/groovy/noe/server/Httpd.groovy b/core/src/main/groovy/noe/server/Httpd.groovy index ff7c641a..3b4d5b9f 100644 --- a/core/src/main/groovy/noe/server/Httpd.groovy +++ b/core/src/main/groovy/noe/server/Httpd.groovy @@ -372,7 +372,7 @@ abstract class Httpd extends ServerAbstract { } } - Integer extractPid() { + Long extractPid() { String stringPid = null File pidFile = getPidFile() if (!pidFile.exists()) { @@ -383,7 +383,7 @@ abstract class Httpd extends ServerAbstract { if ( stringPid.isEmpty() ) { throw new RuntimeException("Extraction of httpd PID went wrong, ${pidFile} is empty") } - pid = stringPid.toInteger() + pid = stringPid.toLong() return pid } diff --git a/core/src/main/groovy/noe/server/ServerAbstract.groovy b/core/src/main/groovy/noe/server/ServerAbstract.groovy index afbb31a9..eadc3f4a 100644 --- a/core/src/main/groovy/noe/server/ServerAbstract.groovy +++ b/core/src/main/groovy/noe/server/ServerAbstract.groovy @@ -47,7 +47,7 @@ abstract class ServerAbstract implements IApp { // process management Process process // running server process (if was started on background) - Integer pid // process pid + Long pid // process pid String processCode // for process identification String runAs // under who user run the process, empty value means actual user String runContext // commandline context @@ -216,8 +216,8 @@ abstract class ServerAbstract implements IApp { * - server run with some unique id (processCode) * - running process is filtered by this id */ - Integer extractPid() { - Integer extractedPid = null + Long extractPid() { + Long extractedPid = null if (process != null && ProcessUtils.isProcAlive(process)) { log.debug("Process is running, trying to extract pid directly from it") extractedPid = ProcessUtils.getProcessId(process)