View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.maven.surefire.booter;
20  
21  /**
22   * Interface for checking if a process (typically the parent Maven plugin) is still alive.
23   * <p>
24   * Implementations allow the forked JVM to detect when its parent Maven process
25   * has terminated, enabling cleanup and preventing orphaned processes.
26   *
27   * @since 3.5.5
28   */
29  public interface ProcessChecker {
30  
31      /**
32       * Creates the appropriate {@link ProcessChecker} implementation for the given parent PID.
33       * <p>
34       * On Java 9+, uses {@code ProcessHandleChecker} which leverages the {@code ProcessHandle} API.
35       * On Java 8, falls back to {@link PpidChecker} which uses native commands.
36       *
37       * @param ppid the parent process ID as a string, or {@code null}
38       * @return a new checker instance, or {@code null} if ppid is {@code null}
39       */
40      static ProcessChecker of(String ppid) {
41          if (ppid == null) {
42              return null;
43          }
44          if (ProcessHandleChecker.isAvailable()) {
45              return new ProcessHandleChecker(ppid);
46          }
47          return new PpidChecker(ppid);
48      }
49  
50      /**
51       * Returns whether the ProcessHandle API is available in the current JVM.
52       *
53       * @return {@code true} if running on Java 9+ with ProcessHandle available
54       */
55      static boolean isProcessHandleSupported() {
56          return ProcessHandleChecker.isAvailable();
57      }
58  
59      /**
60       * Checks whether this checker can be used to monitor the process.
61       * <p>
62       * This method must return {@code true} before {@link #isProcessAlive()} can be called.
63       * @deprecated with using ProcessHandleChecker on Java 9+, this method will always return {@code true} and can be removed in a future release.
64       * @return {@code true} if the checker is operational and can monitor the process
65       */
66      @Deprecated
67      boolean canUse();
68  
69      /**
70       * Checks if the process is still alive.
71       * <p>
72       * This method can only be called after {@link #canUse()} has returned {@code true}.
73       *
74       * @return {@code true} if the process is still running; {@code false} if it has terminated
75       *         or if the PID has been reused by a different process
76       * @throws IllegalStateException if {@link #canUse()} returns {@code false} or if the checker
77       *                               has been stopped
78       */
79      boolean isProcessAlive();
80  
81      /**
82       * Stops the checker and releases any resources.
83       * <p>
84       * After calling this method, {@link #canUse()} will return {@code false}.
85       */
86      void stop();
87  
88      /**
89       * Destroys any active commands or subprocesses used by this checker.
90       * <p>
91       * This is called during shutdown to ensure clean termination.
92       */
93      void destroyActiveCommands();
94  
95      /**
96       * Checks if the checker has been stopped.
97       *
98       * @return {@code true} if {@link #stop()} or {@link #destroyActiveCommands()} has been called
99       */
100     boolean isStopped();
101 
102     /**
103      * Returns information about the process being checked.
104      *
105      * @return the process information, or {@code null} if not yet initialized
106      */
107     ProcessInfo processInfo();
108 }