From 655aa60a10254088deb4c93d11fc8116847b9210 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Efe=20G=C3=B6kdemir?= Date: Thu, 24 Sep 2026 09:55:34 +0300 Subject: [PATCH] Kill process descendants on execution timeout MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Efe Gökdemir --- .../ProcessBuilderExecutorSupport.java | 6 ++-- .../executor/support/ProcessTreeKiller.java | 30 ++++++++++++++++++ .../executor/support/ProcessTreeKiller.java | 31 +++++++++++++++++++ 3 files changed, 64 insertions(+), 3 deletions(-) create mode 100644 maven-executor/src/main/java/org/apache/maven/executor/support/ProcessTreeKiller.java create mode 100644 maven-executor/src/main/java9/org/apache/maven/executor/support/ProcessTreeKiller.java diff --git a/maven-executor/src/main/java/org/apache/maven/executor/support/ProcessBuilderExecutorSupport.java b/maven-executor/src/main/java/org/apache/maven/executor/support/ProcessBuilderExecutorSupport.java index 4f8b29d..c68d90c 100644 --- a/maven-executor/src/main/java/org/apache/maven/executor/support/ProcessBuilderExecutorSupport.java +++ b/maven-executor/src/main/java/org/apache/maven/executor/support/ProcessBuilderExecutorSupport.java @@ -91,7 +91,7 @@ protected ExecutorResult doExecuteProcess(ExecutorRequest execution, ProcessBuil } return new SimpleExecutionResult(execution, exitCode == 0, exitCode, stdOutString, stdErrString); } else { - process.destroyForcibly(); + ProcessTreeKiller.destroy(process); throw new ExecutorException("Process timeout: " + execution); } } else { @@ -108,11 +108,11 @@ protected ExecutorResult doExecuteProcess(ExecutorRequest execution, ProcessBuil } } catch (IOException e) { if (process != null) { - process.destroyForcibly(); + ProcessTreeKiller.destroy(process); } throw new ExecutorException("IO problem while executing command: " + execution, e); } catch (InterruptedException e) { - process.destroyForcibly(); + ProcessTreeKiller.destroy(process); throw new ExecutorException("Interrupted while executing command: " + execution, e); } } diff --git a/maven-executor/src/main/java/org/apache/maven/executor/support/ProcessTreeKiller.java b/maven-executor/src/main/java/org/apache/maven/executor/support/ProcessTreeKiller.java new file mode 100644 index 0000000..0754f31 --- /dev/null +++ b/maven-executor/src/main/java/org/apache/maven/executor/support/ProcessTreeKiller.java @@ -0,0 +1,30 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.maven.executor.support; + +/** + * Terminates a process and, on Java 9 and later, its descendants. + */ +final class ProcessTreeKiller { + private ProcessTreeKiller() {} + + static void destroy(Process process) { + process.destroyForcibly(); + } +} diff --git a/maven-executor/src/main/java9/org/apache/maven/executor/support/ProcessTreeKiller.java b/maven-executor/src/main/java9/org/apache/maven/executor/support/ProcessTreeKiller.java new file mode 100644 index 0000000..a591157 --- /dev/null +++ b/maven-executor/src/main/java9/org/apache/maven/executor/support/ProcessTreeKiller.java @@ -0,0 +1,31 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.maven.executor.support; + +/** + * Terminates a process and its descendants. + */ +final class ProcessTreeKiller { + private ProcessTreeKiller() {} + + static void destroy(Process process) { + process.toHandle().descendants().forEach(ProcessHandle::destroyForcibly); + process.destroyForcibly(); + } +}