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 * https://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
20 package org.apache.commons.exec;
21
22 import java.io.File;
23 import java.io.IOException;
24 import java.nio.file.Path;
25 import java.util.Map;
26
27 /**
28 * The main abstraction to start an external process.
29 *
30 * The interface allows to:
31 * <ul>
32 * <li>set a current working directory for the subprocess</li>
33 * <li>provide a set of environment variables passed to the subprocess</li>
34 * <li>capture the subprocess output of stdout and stderr using an ExecuteStreamHandler</li>
35 * <li>kill long-running processes using an ExecuteWatchdog</li>
36 * <li>define a set of expected exit values</li>
37 * <li>terminate any started processes when the main process is terminating using a ProcessDestroyer</li>
38 * </ul>
39 * <p>
40 * The following example shows the basic usage:
41 * </p>
42 *
43 * <pre>
44 * Executor exec = DefaultExecutor.builder().get();
45 * CommandLine cl = new CommandLine("ls -l");
46 * int exitValue = exec.execute(cl);
47 * </pre>
48 */
49
50 public interface Executor {
51
52 /** Invalid exit code. */
53 int INVALID_EXITVALUE = 0xdeadbeef;
54
55 /**
56 * Executes a command synchronously. The child process inherits all environment variables of the parent process.
57 *
58 * @param command the command to execute.
59 * @return process exit value.
60 * @throws ExecuteException execution of subprocess failed or the subprocess returned an exit value indicating a failure {@link Executor#setExitValue(int)}.
61 * @throws IOException If an I/O error occurs.
62 */
63 int execute(CommandLine command) throws ExecuteException, IOException;
64
65 /**
66 * Executes a command asynchronously. The child process inherits all environment variables of the parent process. Result provided to callback handler.
67 *
68 * @param command the command to execute.
69 * @param handler capture process termination and exit code.
70 * @throws ExecuteException execution of subprocess failed.
71 * @throws IOException If an I/O error occurs.
72 */
73 void execute(CommandLine command, ExecuteResultHandler handler) throws ExecuteException, IOException;
74
75 /**
76 * Executes a command synchronously.
77 *
78 * @param command the command to execute.
79 * @param environment The environment for the new process. If null, the environment of the current process is used.
80 * @return process exit value.
81 * @throws ExecuteException execution of subprocess failed or the subprocess returned an exit value indicating a failure {@link Executor#setExitValue(int)}.
82 * @throws IOException If an I/O error occurs.
83 */
84 int execute(CommandLine command, Map<String, String> environment) throws ExecuteException, IOException;
85
86 /**
87 * Executes a command asynchronously. The child process inherits all environment variables of the parent process. Result provided to callback handler.
88 *
89 * @param command the command to execute.
90 * @param environment The environment for the new process. If null, the environment of the current process is used.
91 * @param handler capture process termination and exit code.
92 * @throws ExecuteException execution of subprocess failed.
93 * @throws IOException If an I/O error occurs.
94 */
95 void execute(CommandLine command, Map<String, String> environment, ExecuteResultHandler handler) throws ExecuteException, IOException;
96
97 /**
98 * Sets the handler for cleanup of started processes if the main process is going to terminate.
99 *
100 * @return the ProcessDestroyer.
101 */
102 ProcessDestroyer getProcessDestroyer();
103
104 /**
105 * Gets the StreamHandler used for providing input and retrieving the output.
106 *
107 * @return the StreamHandler.
108 */
109 ExecuteStreamHandler getStreamHandler();
110
111 /**
112 * Gets the watchdog used to kill of processes running, typically, too long time.
113 *
114 * @return the watchdog.
115 */
116 ExecuteWatchdog getWatchdog();
117
118 /**
119 * Gets the working directory of the created process.
120 *
121 * @return the working directory.
122 */
123 File getWorkingDirectory();
124
125 /**
126 * Gets the working directory of the created process.
127 *
128 * @return the working directory.
129 * @since 1.5.0
130 */
131 default Path getWorkingDirectoryPath() {
132 return getWorkingDirectory().toPath();
133 }
134
135 /**
136 * Tests whether {@code exitValue} signals a failure. If no exit values are set than the default conventions of the OS is used. e.g. most OS regard an exit
137 * code of '0' as successful execution and everything else as failure.
138 *
139 * @param exitValue the exit value (return code) to be checked.
140 * @return {@code true} if {@code exitValue} signals a failure.
141 */
142 boolean isFailure(int exitValue);
143
144 /**
145 * Sets the {@code exitValue} of the process to be considered successful. If a different exit value is returned by the process then
146 * {@link org.apache.commons.exec.Executor#execute(CommandLine)} will throw an {@link org.apache.commons.exec.ExecuteException}.
147 *
148 * @param value the exit code representing successful execution.
149 */
150 void setExitValue(int value);
151
152 /**
153 * Sets a list of {@code exitValue} of the process to be considered successful. The caller can pass one of the following values.
154 * <ul>
155 * <li>an array of exit values to be considered successful</li>
156 * <li>an empty array for auto-detect of successful exit codes relying on {@link org.apache.commons.exec.Executor#isFailure(int)}</li>
157 * <li>null to indicate to skip checking of exit codes</li>
158 * </ul>
159 *
160 * If an undefined exit value is returned by the process then {@link org.apache.commons.exec.Executor#execute(CommandLine)} will throw an
161 * {@link org.apache.commons.exec.ExecuteException}.
162 *
163 * @param values a list of the exit codes.
164 */
165 void setExitValues(int[] values);
166
167 /**
168 * Sets the handler for cleanup of started processes if the main process is going to terminate.
169 *
170 * @param processDestroyer the ProcessDestroyer.
171 */
172 void setProcessDestroyer(ProcessDestroyer processDestroyer);
173
174 /**
175 * Sets a custom the StreamHandler used for providing input and retrieving the output. If you don't provide a proper stream handler the executed process
176 * might block when writing to stdout and/or stderr (see {@link Process Process}).
177 *
178 * @param streamHandler the stream handler.
179 */
180 void setStreamHandler(ExecuteStreamHandler streamHandler);
181
182 /**
183 * Sets the watchdog used to kill of processes running, typically, too long time.
184 *
185 * @param watchDog the watchdog.
186 */
187 void setWatchdog(ExecuteWatchdog watchDog);
188
189 /**
190 * Sets the working directory of the created process. The working directory must exist when you start the process.
191 *
192 * @param dir the working directory.
193 */
194 void setWorkingDirectory(File dir);
195
196 }