or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

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

executable-finder.mddocs/

0

# Executable Discovery

1

2

Cross-platform utility for finding executables on the system PATH with automatic handling of platform-specific file extensions and search paths.

3

4

## Capabilities

5

6

### ExecutableFinder Class

7

8

Locates executables by scanning the file system and PATH environment variable, with intelligent handling of platform-specific executable extensions and search locations.

9

10

```java { .api }

11

public class ExecutableFinder {

12

/**

13

* Find executable by scanning file system and PATH

14

* @param named the name of the executable to find

15

* @return absolute path to executable, or null if not found

16

*/

17

public String find(String named);

18

}

19

```

20

21

**Usage Examples:**

22

23

```java

24

import org.openqa.selenium.os.ExecutableFinder;

25

26

ExecutableFinder finder = new ExecutableFinder();

27

28

// Find browser drivers

29

String chromeDriver = finder.find("chromedriver");

30

String geckoDriver = finder.find("geckodriver");

31

String edgeDriver = finder.find("msedgedriver");

32

33

// Find system utilities

34

String gitPath = finder.find("git");

35

String pythonPath = finder.find("python");

36

String javacPath = finder.find("javac");

37

38

if (chromeDriver != null) {

39

System.out.println("ChromeDriver found at: " + chromeDriver);

40

} else {

41

System.err.println("ChromeDriver not found on PATH");

42

}

43

44

// Use with ExternalProcess

45

if (gitPath != null) {

46

ExternalProcess process = ExternalProcess.builder()

47

.command(gitPath, Arrays.asList("--version"))

48

.start();

49

50

if (process.waitFor(Duration.ofSeconds(5))) {

51

System.out.println("Git version: " + process.getOutput().trim());

52

}

53

}

54

```

55

56

### Search Algorithm

57

58

The ExecutableFinder implements a comprehensive search strategy that handles platform differences automatically:

59

60

**Search Order:**

61

1. **Direct Path Check**: If the provided name is already an absolute or relative path to an executable file

62

2. **Windows Extension Check**: On Windows, automatically try adding `.exe` extension

63

3. **PATH Environment Scanning**: Search each directory in the PATH environment variable

64

4. **Platform-Specific Extensions**: Try all appropriate extensions for the current platform

65

5. **macOS Specific Paths**: On macOS, additionally search paths defined in `/etc/paths`

66

67

**Platform-Specific Extensions:**

68

- **Windows**: `""`, `.cmd`, `.exe`, `.com`, `.bat`

69

- **Unix/Linux/macOS**: `""` (no extension)

70

71

**Environment Variable Handling:**

72

- Searches `PATH` environment variable (case-insensitive lookup)

73

- Uses `File.pathSeparator` for splitting PATH entries (`;` on Windows, `:` on Unix)

74

- Handles missing or empty PATH gracefully

75

76

**macOS Enhancement:**

77

- Reads `/etc/paths` file for additional system paths

78

- Gracefully handles missing `/etc/paths` file

79

- Each line in `/etc/paths` is treated as an additional search directory

80

81

### File System Checks

82

83

The finder performs comprehensive checks to ensure discovered files are actually executable:

84

85

**Validation Criteria:**

86

- File must exist on the file system

87

- Must not be a directory

88

- Must have executable permissions (`File.canExecute()`)

89

90

**Error Handling:**

91

- Returns `null` if no executable found (never throws exceptions)

92

- Handles I/O errors gracefully during file system access

93

- Manages permissions errors when checking executability

94

95

**Cross-Platform Considerations:**

96

- Respects platform-specific permission models

97

- Handles symbolic links appropriately

98

- Works with both absolute and relative paths in PATH entries

99

100

### Integration with Process Management

101

102

ExecutableFinder is commonly used with process management classes to locate executables before launching:

103

104

```java

105

import org.openqa.selenium.os.ExecutableFinder;

106

import org.openqa.selenium.os.ExternalProcess;

107

108

// Pattern: Locate then execute

109

ExecutableFinder finder = new ExecutableFinder();

110

String executable = finder.find("my-tool");

111

112

if (executable != null) {

113

ExternalProcess process = ExternalProcess.builder()

114

.command(executable, Arrays.asList("arg1", "arg2"))

115

.start();

116

// ... manage process

117

} else {

118

throw new IllegalStateException("Required executable 'my-tool' not found on PATH");

119

}

120

121

// Legacy API integration (deprecated)

122

String driverPath = finder.find("chromedriver");

123

if (driverPath != null) {

124

CommandLine cmd = new CommandLine(driverPath, "--port=9515");

125

cmd.execute();

126

}

127

```

128

129

This pattern ensures robust executable discovery before attempting to launch processes, providing clear error messages when required tools are not available in the environment.