CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-org-seleniumhq-selenium--selenium-os

Operating system utilities for Selenium WebDriver, providing cross-platform process management and executable discovery capabilities

Pending
Overview
Eval results
Files

modern-process.mddocs/

Modern Process Management

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.

Capabilities

ExternalProcess Builder

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

/**
 * Creates a new builder instance for constructing ExternalProcess
 * @return Builder instance for fluent configuration
 */
public static ExternalProcess.Builder builder();

public static class Builder {
    /**
     * Set the executable command with arguments
     * @param executable the executable to run
     * @param arguments the arguments to pass
     * @return this instance for chaining
     */
    public Builder command(String executable, List<String> arguments);
    
    /**
     * Set the executable command with arguments
     * @param command the executable followed by arguments
     * @return this instance for chaining
     */
    public Builder command(List<String> command);
    
    /**
     * Set the executable command with arguments
     * @param command the executable followed by arguments
     * @return this instance for chaining
     */
    public Builder command(String... command);
    
    /**
     * Get the current command configuration
     * @return unmodifiable list of command and arguments
     */
    public List<String> command();
    
    /**
     * Set a single environment variable
     * @param name environment variable name (must not be null)
     * @param value environment variable value (must not be null)
     * @return this instance for chaining
     * @throws IllegalArgumentException if name or value is null
     */
    public Builder environment(String name, String value);
    
    /**
     * Get the environment variables map
     * @return editable map of environment variables
     */
    public Map<String, String> environment();
    
    /**
     * Get the working directory
     * @return current working directory or null if not set
     */
    public File directory();
    
    /**
     * Set the working directory from string path
     * @param directory path to working directory
     * @return this instance for chaining
     */
    public Builder directory(String directory);
    
    /**
     * Set the working directory
     * @param directory working directory File object
     * @return this instance for chaining
     */
    public Builder directory(File directory);
    
    /**
     * Copy output to additional stream
     * @param stream where to copy combined stdout and stderr
     * @return this instance for chaining
     */
    public Builder copyOutputTo(OutputStream stream);
    
    /**
     * Set output buffer size
     * @param toKeep number of bytes to buffer (default 32768)
     * @return this instance for chaining
     */
    public Builder bufferSize(int toKeep);
    
    /**
     * Build and start the external process
     * @return ExternalProcess instance
     * @throws UncheckedIOException if process creation fails
     */
    public ExternalProcess start() throws UncheckedIOException;
}

Usage Examples:

import org.openqa.selenium.os.ExternalProcess;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.util.Arrays;

// Basic process execution
ExternalProcess process = ExternalProcess.builder()
    .command("echo", Arrays.asList("Hello", "World"))
    .start();

// Advanced configuration
ByteArrayOutputStream output = new ByteArrayOutputStream();
ExternalProcess process = ExternalProcess.builder()
    .command("java", Arrays.asList("-jar", "myapp.jar", "--config", "prod.yml"))
    .environment("JAVA_OPTS", "-Xmx2g")
    .environment("LOG_LEVEL", "DEBUG")
    .directory(new File("/opt/myapp"))
    .copyOutputTo(output)
    .bufferSize(16384)
    .start();

ExternalProcess Management

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

public class ExternalProcess {
    /**
     * Get combined stdout and stderr as String in default charset
     * @return buffered output as String
     */
    public String getOutput();
    
    /**
     * Get combined stdout and stderr as String in specified encoding
     * @param encoding the charset to use for decoding
     * @return buffered output as String in specified encoding
     */
    public String getOutput(Charset encoding);
    
    /**
     * Check if the process is still running
     * @return true if process is alive, false if terminated
     */
    public boolean isAlive();
    
    /**
     * Wait for process completion within timeout
     * @param duration maximum time to wait
     * @return true if process completed within timeout, false if timeout occurred
     * @throws InterruptedException if current thread is interrupted
     */
    public boolean waitFor(Duration duration) throws InterruptedException;
    
    /**
     * Get the exit code of the completed process
     * @return process exit code
     * @throws IllegalStateException if process is still running
     */
    public int exitValue();
    
    /**
     * Initiate graceful shutdown with 4-second timeout
     */
    public void shutdown();
    
    /**
     * Initiate shutdown with custom timeout
     * @param timeout maximum time to wait for graceful shutdown before force kill
     */
    public void shutdown(Duration timeout);
}

Usage Examples:

import org.openqa.selenium.os.ExternalProcess;
import java.time.Duration;
import java.nio.charset.StandardCharsets;

// Start and wait for process
ExternalProcess process = ExternalProcess.builder()
    .command("curl", Arrays.asList("-s", "https://api.example.com/status"))
    .start();

// Wait with timeout
boolean completed = process.waitFor(Duration.ofSeconds(30));
if (completed) {
    int exitCode = process.exitValue();
    String output = process.getOutput(StandardCharsets.UTF_8);
    
    if (exitCode == 0) {
        System.out.println("API Response: " + output);
    } else {
        System.err.println("Command failed with exit code: " + exitCode);
        System.err.println("Error output: " + output);
    }
} else {
    System.err.println("Process timed out, shutting down...");
    process.shutdown(Duration.ofSeconds(5));
}

// Check if still running
if (process.isAlive()) {
    System.err.println("Process still running after shutdown attempt");
}

Process Lifecycle Management

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

Process States:

  • Starting: Process is being created and initialized
  • Running: Process is actively executing (isAlive() returns true)
  • Completed: Process has finished execution (exit code available)
  • Shutdown: Process is being terminated gracefully or forcibly

Shutdown Behavior:

  1. Normal termination attempted using ProcessHandle.destroy()
  2. Wait for graceful shutdown within specified timeout
  3. Force termination using ProcessHandle.destroyForcibly() if still running
  4. Worker thread cleanup and resource deallocation

Error Scenarios:

  • UncheckedIOException: Process creation fails (invalid executable, permission issues)
  • InterruptedException: Thread interrupted during wait operations
  • Output buffer overflow: Handled automatically with circular buffering

Resource Management:

  • Output streams are automatically managed and cleaned up
  • Worker threads are daemon threads that don't prevent JVM shutdown
  • Process handles are properly closed on completion or shutdown

Install with Tessl CLI

npx tessl i tessl/maven-org-seleniumhq-selenium--selenium-os

docs

executable-finder.md

index.md

legacy-process.md

modern-process.md

tile.json