Skip to content

Commit

Permalink
chore(run-IT): fetch process id via java.lang.Process#pid() (camunda#…
Browse files Browse the repository at this point in the history
…3465)

Related to camunda#3436
  • Loading branch information
yanavasileva authored Jun 7, 2023
1 parent 166d947 commit 140ff57
Showing 1 changed file with 8 additions and 54 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.Field;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
Expand All @@ -36,10 +35,6 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.sun.jna.Pointer;
import com.sun.jna.platform.win32.Kernel32;
import com.sun.jna.platform.win32.WinNT;

/**
* Container that handles a managed Spring Boot application that is started by
* the distro's startup scripts
Expand All @@ -63,6 +58,7 @@ public class SpringBootManagedContainer {

protected Thread shutdownThread;
protected Process startupProcess;
protected static long pid;

protected List<File> configurationFiles = new ArrayList<>();

Expand Down Expand Up @@ -106,18 +102,18 @@ public void start() {
startupProcessBuilder.directory(new File(baseDirectory));
log.info("Starting Spring Boot application with: " + startupProcessBuilder.command());
startupProcess = startupProcessBuilder.start();
pid = startupProcess.pid();
new Thread(new ConsoleConsumer()).start();
final Process proc = startupProcess;

shutdownThread = new Thread(() -> {
if (proc != null) {
killProcess(proc, true);
if (startupProcess != null) {
killProcess( true);
}
});
Runtime.getRuntime().addShutdownHook(shutdownThread);

if (!isStarted(RAMP_UP_SECONDS * 1000)) {
killProcess(startupProcess, false);
killProcess(false);
throw new TimeoutException(String.format("Managed Spring Boot application was not started within [%d] s", RAMP_UP_SECONDS));
}
} catch (final Exception ex) {
Expand All @@ -134,7 +130,7 @@ public void stop() {
try {
if (startupProcess != null) {
if (isRunning()) {
killProcess(startupProcess, false);
killProcess(false);
if (!isShutDown(RAMP_DOWN_SECONDS * 1000)) {
throw new RuntimeException("Could not kill the application.");
}
Expand Down Expand Up @@ -208,26 +204,23 @@ protected void processOptionsRequests(String urlToCall) throws IOException {
// kill processes
// ---------------------------

protected static void killProcess(Process process, boolean failOnException) {
protected static void killProcess(boolean failOnException) {
try {
Process p = null;
Integer pid = null;

// must kill a hierachy of processes: the script process (which corresponds to the pid value)
// and the Java process it has spawned
if (isUnixLike()) {
pid = unixLikeProcessId(process);
p = new ProcessBuilder("pkill", "-TERM", "-P", String.valueOf(pid)).start();
} else {
pid = windowsProcessId(process);
p = new ProcessBuilder("taskkill", "/F", "/T", "/pid", String.valueOf(pid)).start();
}
int exitCode = p.waitFor();
if (exitCode != 0) {
log.warn("Attempt to terminate process with pid {} returned with exit code {}", pid, exitCode);
}
} catch (Exception e) {
String message = String.format("Couldn't kill process %s", process);
String message = String.format("Couldn't kill process %s", pid);
if (failOnException) {
throw new RuntimeException(message, e);
} else {
Expand All @@ -240,45 +233,6 @@ protected static boolean isUnixLike() {
return !System.getProperty("os.name").startsWith("Windows", 0);
}

protected static Integer unixLikeProcessId(Process process) {
Class<?> clazz = process.getClass();
try {
if (clazz.getName().equals("java.lang.UNIXProcess")) {
Field pidField = clazz.getDeclaredField("pid");
pidField.setAccessible(true);
Object value = pidField.get(process);
if (value instanceof Integer) {
log.debug("Detected pid: {}", value);
return (Integer) value;
}
}
} catch (SecurityException | IllegalAccessException | IllegalArgumentException | NoSuchFieldException ex) {
throw new RuntimeException("Cannot fetch unix pid!", ex);
}
return null;
}

protected static Integer windowsProcessId(Process process) {
if (process.getClass().getName().equals("java.lang.Win32Process") || process.getClass().getName().equals("java.lang.ProcessImpl")) {
/* determine the pid on windows plattforms */
try {
Field f = process.getClass().getDeclaredField("handle");
f.setAccessible(true);
long handl = f.getLong(process);

Kernel32 kernel = Kernel32.INSTANCE;
WinNT.HANDLE handle = new WinNT.HANDLE();
handle.setPointer(Pointer.createConstant(handl));
int ret = kernel.GetProcessId(handle);
log.debug("Detected pid: {}", ret);
return ret;
} catch (Throwable ex) {
throw new RuntimeException("Cannot fetch windows pid!", ex);
}
}
return null;
}

public void replaceConfigurationYml(String filePath, InputStream source) {
try {
Files.deleteIfExists(Paths.get(baseDirectory, filePath));
Expand Down

0 comments on commit 140ff57

Please sign in to comment.