or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

executable-finder.mdindex.mdlegacy-process.mdmodern-process.md

modern-process.mddocs/

0

# Modern Process Management

1

2

Modern, builder-pattern-based external process execution with improved resource management, flexible configuration, and robust error handling. The `ExternalProcess` API is the recommended approach for new implementations.

3

4

## Capabilities

5

6

### ExternalProcess Builder

7

8

Creates and configures external processes using a fluent builder pattern with comprehensive configuration options.

9

10

```java { .api }

11

/**

12

* Creates a new builder instance for constructing ExternalProcess

13

* @return Builder instance for fluent configuration

14

*/

15

public static ExternalProcess.Builder builder();

16

17

public static class Builder {

18

/**

19

* Set the executable command with arguments

20

* @param executable the executable to run

21

* @param arguments the arguments to pass

22

* @return this instance for chaining

23

*/

24

public Builder command(String executable, List<String> arguments);

25

26

/**

27

* Set the executable command with arguments

28

* @param command the executable followed by arguments

29

* @return this instance for chaining

30

*/

31

public Builder command(List<String> command);

32

33

/**

34

* Set the executable command with arguments

35

* @param command the executable followed by arguments

36

* @return this instance for chaining

37

*/

38

public Builder command(String... command);

39

40

/**

41

* Get the current command configuration

42

* @return unmodifiable list of command and arguments

43

*/

44

public List<String> command();

45

46

/**

47

* Set a single environment variable

48

* @param name environment variable name (must not be null)

49

* @param value environment variable value (must not be null)

50

* @return this instance for chaining

51

* @throws IllegalArgumentException if name or value is null

52

*/

53

public Builder environment(String name, String value);

54

55

/**

56

* Get the environment variables map

57

* @return editable map of environment variables

58

*/

59

public Map<String, String> environment();

60

61

/**

62

* Get the working directory

63

* @return current working directory or null if not set

64

*/

65

public File directory();

66

67

/**

68

* Set the working directory from string path

69

* @param directory path to working directory

70

* @return this instance for chaining

71

*/

72

public Builder directory(String directory);

73

74

/**

75

* Set the working directory

76

* @param directory working directory File object

77

* @return this instance for chaining

78

*/

79

public Builder directory(File directory);

80

81

/**

82

* Copy output to additional stream

83

* @param stream where to copy combined stdout and stderr

84

* @return this instance for chaining

85

*/

86

public Builder copyOutputTo(OutputStream stream);

87

88

/**

89

* Set output buffer size

90

* @param toKeep number of bytes to buffer (default 32768)

91

* @return this instance for chaining

92

*/

93

public Builder bufferSize(int toKeep);

94

95

/**

96

* Build and start the external process

97

* @return ExternalProcess instance

98

* @throws UncheckedIOException if process creation fails

99

*/

100

public ExternalProcess start() throws UncheckedIOException;

101

}

102

```

103

104

**Usage Examples:**

105

106

```java

107

import org.openqa.selenium.os.ExternalProcess;

108

import java.io.ByteArrayOutputStream;

109

import java.io.File;

110

import java.util.Arrays;

111

112

// Basic process execution

113

ExternalProcess process = ExternalProcess.builder()

114

.command("echo", Arrays.asList("Hello", "World"))

115

.start();

116

117

// Advanced configuration

118

ByteArrayOutputStream output = new ByteArrayOutputStream();

119

ExternalProcess process = ExternalProcess.builder()

120

.command("java", Arrays.asList("-jar", "myapp.jar", "--config", "prod.yml"))

121

.environment("JAVA_OPTS", "-Xmx2g")

122

.environment("LOG_LEVEL", "DEBUG")

123

.directory(new File("/opt/myapp"))

124

.copyOutputTo(output)

125

.bufferSize(16384)

126

.start();

127

```

128

129

### ExternalProcess Management

130

131

Manages running external processes with lifecycle control, output retrieval, and graceful shutdown capabilities.

132

133

```java { .api }

134

public class ExternalProcess {

135

/**

136

* Get combined stdout and stderr as String in default charset

137

* @return buffered output as String

138

*/

139

public String getOutput();

140

141

/**

142

* Get combined stdout and stderr as String in specified encoding

143

* @param encoding the charset to use for decoding

144

* @return buffered output as String in specified encoding

145

*/

146

public String getOutput(Charset encoding);

147

148

/**

149

* Check if the process is still running

150

* @return true if process is alive, false if terminated

151

*/

152

public boolean isAlive();

153

154

/**

155

* Wait for process completion within timeout

156

* @param duration maximum time to wait

157

* @return true if process completed within timeout, false if timeout occurred

158

* @throws InterruptedException if current thread is interrupted

159

*/

160

public boolean waitFor(Duration duration) throws InterruptedException;

161

162

/**

163

* Get the exit code of the completed process

164

* @return process exit code

165

* @throws IllegalStateException if process is still running

166

*/

167

public int exitValue();

168

169

/**

170

* Initiate graceful shutdown with 4-second timeout

171

*/

172

public void shutdown();

173

174

/**

175

* Initiate shutdown with custom timeout

176

* @param timeout maximum time to wait for graceful shutdown before force kill

177

*/

178

public void shutdown(Duration timeout);

179

}

180

```

181

182

**Usage Examples:**

183

184

```java

185

import org.openqa.selenium.os.ExternalProcess;

186

import java.time.Duration;

187

import java.nio.charset.StandardCharsets;

188

189

// Start and wait for process

190

ExternalProcess process = ExternalProcess.builder()

191

.command("curl", Arrays.asList("-s", "https://api.example.com/status"))

192

.start();

193

194

// Wait with timeout

195

boolean completed = process.waitFor(Duration.ofSeconds(30));

196

if (completed) {

197

int exitCode = process.exitValue();

198

String output = process.getOutput(StandardCharsets.UTF_8);

199

200

if (exitCode == 0) {

201

System.out.println("API Response: " + output);

202

} else {

203

System.err.println("Command failed with exit code: " + exitCode);

204

System.err.println("Error output: " + output);

205

}

206

} else {

207

System.err.println("Process timed out, shutting down...");

208

process.shutdown(Duration.ofSeconds(5));

209

}

210

211

// Check if still running

212

if (process.isAlive()) {

213

System.err.println("Process still running after shutdown attempt");

214

}

215

```

216

217

### Process Lifecycle Management

218

219

Best practices for managing external process lifecycles with proper resource cleanup and error handling.

220

221

**Process States:**

222

- **Starting**: Process is being created and initialized

223

- **Running**: Process is actively executing (`isAlive()` returns true)

224

- **Completed**: Process has finished execution (exit code available)

225

- **Shutdown**: Process is being terminated gracefully or forcibly

226

227

**Shutdown Behavior:**

228

1. Normal termination attempted using `ProcessHandle.destroy()`

229

2. Wait for graceful shutdown within specified timeout

230

3. Force termination using `ProcessHandle.destroyForcibly()` if still running

231

4. Worker thread cleanup and resource deallocation

232

233

**Error Scenarios:**

234

- `UncheckedIOException`: Process creation fails (invalid executable, permission issues)

235

- `InterruptedException`: Thread interrupted during wait operations

236

- Output buffer overflow: Handled automatically with circular buffering

237

238

**Resource Management:**

239

- Output streams are automatically managed and cleaned up

240

- Worker threads are daemon threads that don't prevent JVM shutdown

241

- Process handles are properly closed on completion or shutdown