diff --git a/jetty-home/src/main/resources/bin/jetty.sh b/jetty-home/src/main/resources/bin/jetty.sh index ebcf0f43296c..de54453f0c64 100755 --- a/jetty-home/src/main/resources/bin/jetty.sh +++ b/jetty-home/src/main/resources/bin/jetty.sh @@ -495,13 +495,10 @@ case "$ACTION" in # FIXME: Broken solution: wordsplitting, pathname expansion, arbitrary command execution, etc. su - "$JETTY_USER" $SU_SHELL -c " cd \"$JETTY_BASE\" - echo ${RUN_ARGS[*]} start-log-file=\"$JETTY_START_LOG\" | xargs ${JAVA} > /dev/null & - disown \$! - echo \$! > \"$JETTY_PID\"" + echo ${RUN_ARGS[*]} --pid-file=\"$JETTY_PID\" start-log-file=\"$JETTY_START_LOG\" | xargs ${JAVA} > /dev/null & + " else - echo ${RUN_ARGS[*]} | xargs ${JAVA} > /dev/null & - disown $! - echo $! > "$JETTY_PID" + echo ${RUN_ARGS[*]} | xargs ${JAVA} --pid-file="$JETTY_PID" > /dev/null & fi fi diff --git a/jetty-home/src/main/resources/etc/jetty-pid.xml b/jetty-home/src/main/resources/etc/jetty-pid.xml new file mode 100644 index 000000000000..573953cdd27f --- /dev/null +++ b/jetty-home/src/main/resources/etc/jetty-pid.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/jetty-start/src/main/java/org/eclipse/jetty/start/StartArgs.java b/jetty-start/src/main/java/org/eclipse/jetty/start/StartArgs.java index b1554fa0237f..d1e6e42e6237 100644 --- a/jetty-start/src/main/java/org/eclipse/jetty/start/StartArgs.java +++ b/jetty-start/src/main/java/org/eclipse/jetty/start/StartArgs.java @@ -202,6 +202,7 @@ public class StartArgs private boolean help = false; private boolean stopCommand = false; + private String pidFile = null; private List listModules = null; private List showModules = null; private boolean listClasspath = false; @@ -919,6 +920,11 @@ public String getModuleGraphFilename() return moduleGraphFilename; } + public String getPidFile() + { + return pidFile; + } + public Props getProperties() { return properties; @@ -1169,6 +1175,13 @@ public void parse(final String rawarg, String source) return; } + if (arg.startsWith("--pid-file=")) + { + setProperty("jetty.pid.file", pidFile, source); + xmlRefs.add("etc/jetty-pid.xml"); + return; + } + if (arg.startsWith("--download=")) { addFile(null, Props.getValue(arg)); diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/component/PidFileLifeCycleListener.java b/jetty-util/src/main/java/org/eclipse/jetty/util/component/PidFileLifeCycleListener.java new file mode 100644 index 000000000000..76e3ca66d8c5 --- /dev/null +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/component/PidFileLifeCycleListener.java @@ -0,0 +1,73 @@ +// +// ======================================================================== +// Copyright (c) 1995-2023 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package org.eclipse.jetty.util.component; + +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class PidFileLifeCycleListener implements LifeCycle.Listener +{ + private static final Logger LOG = LoggerFactory.getLogger(PidFileLifeCycleListener.class); + + private final Path pidFile; + + public PidFileLifeCycleListener(String filename) + { + pidFile = Paths.get(filename); + } + + @Override + public void lifeCycleStarting(LifeCycle event) + { + long pid = ProcessHandle.current().pid(); + try + { + Files.writeString(pidFile, Long.toString(pid), StandardCharsets.UTF_8); + } + catch (IOException e) + { + LOG.warn("Unable to create pidFile: {}", pidFile, e); + } + } + + @Override + public void lifeCycleFailure(LifeCycle event, Throwable cause) + { + removePid(); + } + + @Override + public void lifeCycleStopped(LifeCycle event) + { + removePid(); + } + + private void removePid() + { + try + { + Files.deleteIfExists(pidFile); + } + catch (IOException e) + { + LOG.warn("Unable to remove pidFile: {}", pidFile, e); + } + } +}