WebDriver remote communication library that provides the core infrastructure for browser automation across different platforms and programming languages.
—
Management of native driver executables including automatic discovery, lifecycle control, and process communication. This system handles the complexity of starting, stopping, and communicating with browser driver processes like ChromeDriver, GeckoDriver, and EdgeDriver.
Abstract base class for managing native WebDriver executables, providing lifecycle management and process communication.
/**
* Abstract base class for managing native driver executables
*/
public abstract class DriverService implements Closeable {
// Constants for log output destinations
public static final String LOG_NULL = "/dev/null";
public static final String LOG_STDERR = "/dev/stderr";
public static final String LOG_STDOUT = "/dev/stdout";
// Abstract methods - implemented by specific driver services
public abstract String getExecutable();
public abstract URL getUrl();
// Lifecycle management
public void start() throws IOException;
public void stop();
public void close();
public boolean isRunning();
// Process communication
public void sendOutputTo(OutputStream outputStream) throws IOException;
// Configuration
public void setExecutable(String executable);
/**
* Abstract builder base class for driver services
*/
public static abstract class Builder<DS extends DriverService, B extends Builder<?, ?>> {
// Common configuration methods
public B usingDriverExecutable(File file);
public B usingAnyFreePort();
public B usingPort(int port);
public B withEnvironment(Map<String, String> environment);
public B withLogFile(File logFile);
public B withLogOutput(OutputStream logOutput);
public B withSilent(boolean silent);
public B withVerbose(boolean verbose);
// Build method - returns specific driver service
public abstract DS build();
}
}Usage Examples:
// Example with a hypothetical ChromeDriverService
ChromeDriverService service = new ChromeDriverService.Builder()
.usingDriverExecutable(new File("/usr/local/bin/chromedriver"))
.usingPort(9515)
.withLogFile(new File("/tmp/chromedriver.log"))
.withVerbose(true)
.build();
// Start the service
service.start();
URL serviceUrl = service.getUrl(); // http://localhost:9515
// Check if running
boolean running = service.isRunning();
// Stop the service
service.stop();Command executor that manages a driver service, automatically starting and stopping the service as needed.
/**
* Command executor that manages a driver service lifecycle
*/
public class DriverCommandExecutor implements CommandExecutor {
// Constructors
public DriverCommandExecutor(DriverService service);
public DriverCommandExecutor(DriverService service,
Map<String, CommandInfo> additionalCommands);
// Command execution
public Response execute(Command command) throws IOException;
}Usage Examples:
import org.openqa.selenium.remote.service.DriverCommandExecutor;
import org.openqa.selenium.remote.RemoteWebDriver;
// Create driver service
ChromeDriverService service = new ChromeDriverService.Builder()
.usingAnyFreePort()
.build();
// Create command executor with service management
DriverCommandExecutor executor = new DriverCommandExecutor(service);
// Use with RemoteWebDriver - service will be started automatically
RemoteWebDriver driver = new RemoteWebDriver(executor, capabilities);
// Service is automatically stopped when driver quits
driver.quit();Utility for finding and locating driver executables on the system, with support for automatic driver management.
/**
* Utility for finding driver executables
*/
public class DriverFinder {
/**
* Find driver executable for the given builder and capabilities
* @param builder Driver service builder
* @param capabilities Browser capabilities
* @return Result containing driver information
*/
public static Result getResult(DriverService.Builder<?, ?> builder,
Capabilities capabilities);
/**
* Result of driver finding operation
*/
public static class Result {
public String getDriverPath();
public String getBrowserPath();
public String getDriverVersion();
public String getBrowserVersion();
}
}Usage Examples:
import org.openqa.selenium.remote.service.DriverFinder;
import org.openqa.selenium.chrome.ChromeOptions;
// Find Chrome driver automatically
ChromeOptions options = new ChromeOptions();
ChromeDriverService.Builder builder = new ChromeDriverService.Builder();
DriverFinder.Result result = DriverFinder.getResult(builder, options);
String driverPath = result.getDriverPath();
String browserPath = result.getBrowserPath();
String driverVersion = result.getDriverVersion();
// Use found driver
ChromeDriverService service = builder
.usingDriverExecutable(new File(driverPath))
.build();All driver services follow a consistent builder pattern for configuration:
// Generic pattern for all driver services
SpecificDriverService service = new SpecificDriverService.Builder()
.usingDriverExecutable(new File("/path/to/driver"))
.usingPort(specificPort)
.withEnvironment(environmentVariables)
.withLogFile(new File("/path/to/log"))
.withVerbose(true)
.build();// Manual lifecycle management
service.start();
try {
// Use service
RemoteWebDriver driver = new RemoteWebDriver(service.getUrl(), capabilities);
// ... perform operations
driver.quit();
} finally {
service.stop();
}
// Automatic lifecycle management with try-with-resources
try (DriverService service = builder.build()) {
service.start();
RemoteWebDriver driver = new RemoteWebDriver(service.getUrl(), capabilities);
// Service automatically stopped when try block exits
}Common configuration patterns across all driver services:
// Port configuration
.usingAnyFreePort() // Let system choose free port
.usingPort(9515) // Specific port
// Executable configuration
.usingDriverExecutable(file) // Specific executable path
// Logging configuration
.withLogFile(file) // Log to file
.withLogOutput(outputStream) // Log to stream
.withSilent(true) // Suppress output
.withVerbose(true) // Verbose logging
// Environment configuration
.withEnvironment(envMap) // Custom environment variablesDriver services integrate seamlessly with RemoteWebDriver in multiple ways:
// Direct URL usage
DriverService service = builder.build();
service.start();
RemoteWebDriver driver = new RemoteWebDriver(service.getUrl(), capabilities);
// Command executor usage (recommended)
DriverCommandExecutor executor = new DriverCommandExecutor(service);
RemoteWebDriver driver = new RemoteWebDriver(executor, capabilities);
// Builder integration (Beta)
RemoteWebDriver driver = RemoteWebDriver.builder()
.withDriverService(service)
.addAlternative(capabilities)
.build();try {
service.start();
} catch (IOException e) {
// Handle service startup failure
System.err.println("Failed to start driver service: " + e.getMessage());
// Check if executable exists
File executable = new File(service.getExecutable());
if (!executable.exists()) {
System.err.println("Driver executable not found: " + executable.getPath());
}
// Check if port is available
if (!isPortAvailable(service.getUrl().getPort())) {
System.err.println("Port already in use: " + service.getUrl().getPort());
}
}
// Monitor service health
if (service.isRunning()) {
System.out.println("Service running at: " + service.getUrl());
} else {
System.err.println("Service failed to start or has stopped");
}// Custom environment variables for driver
Map<String, String> environment = new HashMap<>();
environment.put("DISPLAY", ":99"); // For headless environments
environment.put("PATH", customPath); // Custom PATH
// Service with custom configuration
DriverService service = new SpecificDriverService.Builder()
.withEnvironment(environment)
.withLogOutput(new FileOutputStream("/var/log/driver.log"))
.usingDriverExecutable(findDriverExecutable())
.build();
// Redirect output for debugging
ByteArrayOutputStream logCapture = new ByteArrayOutputStream();
service.sendOutputTo(logCapture);
service.start();
// Later, examine captured logs
String driverLogs = logCapture.toString();// Monitor service status
public boolean isServiceHealthy(DriverService service) {
if (!service.isRunning()) {
return false;
}
try {
// Send simple HTTP request to service
HttpClient client = HttpClient.createDefault().createClient(
ClientConfig.defaultConfig().baseUrl(service.getUrl()));
HttpRequest request = new HttpRequest(HttpMethod.GET, "/status");
HttpResponse response = client.execute(request);
return response.getStatus() == 200;
} catch (Exception e) {
return false;
}
}
// Restart service if unhealthy
if (!isServiceHealthy(service)) {
service.stop();
service.start();
}Install with Tessl CLI
npx tessl i tessl/maven-org-seleniumhq-selenium--selenium-remote-driver