Skip to content

Commit 74dff52

Browse files
authored
add support for concurrent runs, better agent support, running a locally built jar (#7)
* add support for unique working dir - allows multiple script runners to be run concurrently - add some additional safe guard checks - improve readme - move JFR logs to logs directory * ad support for using a locally built jar using -DluceeJar=/path/to/jar * add docs about using SystemOutput() * improve execute documentation and examples * Update README.md * improve webroot handling, add tests * escape windows cmd webroots * add jfr support, cleanup readme, add examples * add flightRecordingSettings and PrintInlining * use javax or jakarta jars based on version
1 parent e6dfe6b commit 74dff52

16 files changed

Lines changed: 1696 additions & 81 deletions

.github/workflows/main.yml

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,13 @@ jobs:
3131
run: ant -DluceeVersionQuery="6/all/jar" -Dexecute="/debug.cfm"
3232

3333
- name: Run Lucee 6 Stable
34-
run: ant -DluceeVersion="6.0.3.1" -Dexecute="/debug.cfm" -Dtruth="cfml rocks" -Dauthor="Zac Spitzer"
34+
run: ant -DluceeVersion="6.2.2.91" -Dexecute="/debug.cfm" -Dtruth="cfml rocks" -Dauthor="Zac Spitzer"
3535

3636
- name: Run Lucee 5 (using Lucee light, no extensions)
3737
run: ant -DluceeVersion="light-5.4.2.17" -Dexecute="/debug.cfm"
3838

3939
- name: Run Lucee 6 (using Lucee zero, no extensions, no admin, no docs)
40-
run: ant -DluceeVersion="zero-6.0.3.1" -Dexecute="/debug.cfm"
40+
run: ant -DluceeVersion="zero-6.2.2.91" -Dexecute="/debug.cfm"
4141

4242
- name: Run Latest Lucee 5 RC Light
4343
run: ant -DluceeVersionQuery="5/rc/light" -Dexecute="/debug.cfm"
@@ -48,3 +48,9 @@ jobs:
4848
- name: Run Latest Stable Lucee 5, compile webroot (invalid code)
4949
continue-on-error: true
5050
run: ant -DluceeVersionQuery="5/stable/jar" -Dexecute="/index.cfm" -Dcompile="true" -Dwebroot="${{ github.workspace }}/sampleBad/"
51+
52+
- name: Test concurrent execution with unique working directories
53+
run: |
54+
ant -DuniqueWorkingDir="true" -Dexecute="/debug.cfm" &
55+
ant -DuniqueWorkingDir="true" -Dexecute="/debug.cfm" &
56+
wait
Lines changed: 228 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,228 @@
1+
name: Webroot Handling Matrix
2+
on:
3+
push:
4+
pull_request:
5+
workflow_dispatch:
6+
concurrency:
7+
group: ${{ github.workflow }}-${{ github.ref }}
8+
cancel-in-progress: true
9+
jobs:
10+
macos-bash:
11+
name: MacOS Bash
12+
runs-on: macos-latest
13+
steps:
14+
- uses: actions/checkout@v4
15+
- name: Cache Maven packages
16+
uses: actions/cache@v4
17+
with:
18+
path: ~/.m2/repository
19+
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
20+
restore-keys: |
21+
${{ runner.os }}-maven-
22+
- name: Set up Java
23+
uses: actions/setup-java@v4
24+
with:
25+
distribution: 'temurin'
26+
java-version: '21'
27+
- name: Run all webroot/execute combinations
28+
shell: bash
29+
env:
30+
LUCEE_VERSION_QUERY: 7/all/zero
31+
working-directory: ${{ github.workspace }}/tests/webroot
32+
run: |
33+
luceeVersionQuery="${LUCEE_VERSION_QUERY:-7/all/zero}"
34+
pwd
35+
webroots=( '.' "${{ github.workspace }}/tests/webroot" )
36+
executes=( 'index.cfm' 'test.cfm' 'sub/test.cfm' )
37+
failed=0
38+
for w in "${webroots[@]}"; do
39+
for e in "${executes[@]}"; do
40+
echo "ant -buildfile ../../build.xml -Dwebroot=$w -Dexecute=\"$e\" -DpreCleanup=false -DpostCleanup=false -DluceeVersionQuery=$luceeVersionQuery"
41+
ant -buildfile ../../build.xml -Dwebroot=$w -Dexecute="$e" -DpreCleanup=false -DpostCleanup=false -DluceeVersionQuery="$luceeVersionQuery"
42+
if [ $? -ne 0 ]; then
43+
failed=1
44+
platform="macos-latest"
45+
shell="bash"
46+
echo -e "## Platform: $platform | Shell: $shell\n(pwd): $(pwd)\n### ant -buildfile build.xml -Dwebroot=$w -Dexecute=\"$e\" -DpreCleanup=false -DpostCleanup=false -DluceeVersionQuery=$luceeVersionQuery\nFAILED: $w / $e\n" >> "$GITHUB_STEP_SUMMARY"
47+
fi
48+
done
49+
done
50+
exit $failed
51+
ubuntu-bash:
52+
name: Ubuntu Bash
53+
runs-on: ubuntu-latest
54+
steps:
55+
- uses: actions/checkout@v4
56+
- name: Cache Maven packages
57+
uses: actions/cache@v4
58+
with:
59+
path: ~/.m2/repository
60+
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
61+
restore-keys: |
62+
${{ runner.os }}-maven-
63+
- name: Set up Java
64+
uses: actions/setup-java@v4
65+
with:
66+
distribution: 'temurin'
67+
java-version: '21'
68+
- name: Run all webroot/execute combinations
69+
shell: bash
70+
env:
71+
LUCEE_VERSION_QUERY: 7/all/zero
72+
working-directory: ${{ github.workspace }}/tests/webroot
73+
run: |
74+
luceeVersionQuery="${LUCEE_VERSION_QUERY:-7/all/zero}"
75+
pwd
76+
webroots=( '.' "${{ github.workspace }}/tests/webroot" )
77+
executes=( 'index.cfm' 'test.cfm' 'sub/test.cfm' )
78+
failed=0
79+
for w in "${webroots[@]}"; do
80+
for e in "${executes[@]}"; do
81+
echo "ant -buildfile ../../build.xml -Dwebroot=$w -Dexecute=\"$e\" -DpreCleanup=false -DpostCleanup=false -DluceeVersionQuery=$luceeVersionQuery"
82+
ant -buildfile ../../build.xml -Dwebroot=$w -Dexecute="$e" -DpreCleanup=false -DpostCleanup=false -DluceeVersionQuery="$luceeVersionQuery"
83+
if [ $? -ne 0 ]; then
84+
failed=1
85+
platform="ubuntu-latest"
86+
shell="bash"
87+
echo -e "## Platform: $platform | Shell: $shell\n(pwd): $(pwd)\n### ant -buildfile build.xml -Dwebroot=$w -Dexecute=\"$e\" -DpreCleanup=false -DpostCleanup=false -DluceeVersionQuery=$luceeVersionQuery\nFAILED: $w / $e\n" >> "$GITHUB_STEP_SUMMARY"
88+
fi
89+
done
90+
done
91+
exit $failed
92+
93+
windows-cmd:
94+
name: Windows CMD
95+
runs-on: windows-latest
96+
steps:
97+
- uses: actions/checkout@v4
98+
- name: Cache Maven packages
99+
uses: actions/cache@v4
100+
with:
101+
path: ~/.m2/repository
102+
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
103+
restore-keys: |
104+
${{ runner.os }}-maven-
105+
- name: Set up Java
106+
uses: actions/setup-java@v4
107+
with:
108+
distribution: 'temurin'
109+
java-version: '21'
110+
- name: Run all webroot/execute combinations
111+
shell: cmd
112+
env:
113+
LUCEE_VERSION_QUERY: 7/all/zero
114+
working-directory: ${{ github.workspace }}/tests/webroot
115+
run: |
116+
@echo off
117+
setlocal enabledelayedexpansion
118+
for %%w in (.) do (
119+
for %%e in (index.cfm test.cfm sub\test.cfm) do (
120+
echo %%w / %%e
121+
ant -buildfile=..\..\build.xml "-Dwebroot=%%w" "-Dexecute=%%e" -DpreCleanup=false -DpostCleanup=false -DluceeVersionQuery=%LUCEE_VERSION_QUERY%
122+
if errorlevel 1 (
123+
set cmd=ant -buildfile=build.xml -Dwebroot=%%w -Dexecute=%%e -DpreCleanup=false -DpostCleanup=false -DluceeVersionQuery=%LUCEE_VERSION_QUERY%
124+
echo FAILED: %%w / %%e: !cmd!>> %GITHUB_STEP_SUMMARY%
125+
echo(>> %GITHUB_STEP_SUMMARY%
126+
exit /b 1
127+
)
128+
)
129+
)
130+
for %%w in ("%GITHUB_WORKSPACE%\tests\webroot") do (
131+
for %%e in (index.cfm test.cfm sub/test.cfm) do (
132+
ant -buildfile=..\..\build.xml -Dwebroot=%%w -Dexecute=%%e -DpreCleanup=false -DpostCleanup=false -DluceeVersionQuery=%LUCEE_VERSION_QUERY%
133+
if errorlevel 1 (
134+
set cmd=ant -buildfile=build.xml -Dwebroot=%%w -Dexecute=%%e -DpreCleanup=false -DpostCleanup=false -DluceeVersionQuery=%LUCEE_VERSION_QUERY%
135+
echo FAILED: %%w / %%e: !cmd!>> %GITHUB_STEP_SUMMARY%
136+
echo(>> %GITHUB_STEP_SUMMARY%
137+
exit /b 1
138+
)
139+
)
140+
)
141+
142+
endlocal
143+
windows-pwsh:
144+
name: Windows PowerShell
145+
runs-on: windows-latest
146+
steps:
147+
- uses: actions/checkout@v4
148+
- name: Cache Maven packages
149+
uses: actions/cache@v4
150+
with:
151+
path: ~/.m2/repository
152+
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
153+
restore-keys: |
154+
${{ runner.os }}-maven-
155+
- name: Set up Java
156+
uses: actions/setup-java@v4
157+
with:
158+
distribution: 'temurin'
159+
java-version: '21'
160+
- name: Run all webroot/execute combinations
161+
shell: pwsh
162+
env:
163+
LUCEE_VERSION_QUERY: 7/all/zero
164+
working-directory: ${{ github.workspace }}/tests/webroot
165+
run: |
166+
$webroots = @('.', "${{ github.workspace }}\tests\webroot")
167+
pwd
168+
$executes = @('index.cfm', 'test.cfm', 'sub/test.cfm')
169+
foreach ($w in $webroots) {
170+
foreach ($e in $executes) {
171+
$luceeVersionQuery = $env:LUCEE_VERSION_QUERY
172+
$cmd = "ant -buildfile=../../build.xml `"-Dwebroot=$w`" `"-Dexecute=$e`" -DpreCleanup=false -DpostCleanup=false -DluceeVersionQuery=$luceeVersionQuery"
173+
Write-Host $cmd
174+
$LASTEXITCODE = 0
175+
iex $cmd
176+
if ($LASTEXITCODE -ne 0) {
177+
$cmd = "ant -buildfile=../../build.xml `"-Dwebroot=$w`" `"-Dexecute=$e`" -DpreCleanup=false -DpostCleanup=false -DluceeVersionQuery=$luceeVersionQuery"
178+
$platform = "windows-latest"
179+
$shell = "pwsh"
180+
$summary = @()
181+
$summary += "## Platform: $platform | Shell: $shell"
182+
$summary += "(pwd): $(pwd)"
183+
$summary += "### $cmd"
184+
$summary += "FAILED: $w / $e"
185+
$summary -join "`n" | Out-File -Append -FilePath $env:GITHUB_STEP_SUMMARY
186+
}
187+
}
188+
}
189+
windows-bash:
190+
name: Windows Bash
191+
runs-on: windows-latest
192+
steps:
193+
- uses: actions/checkout@v4
194+
- name: Cache Maven packages
195+
uses: actions/cache@v4
196+
with:
197+
path: ~/.m2/repository
198+
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
199+
restore-keys: |
200+
${{ runner.os }}-maven-
201+
- name: Set up Java
202+
uses: actions/setup-java@v4
203+
with:
204+
distribution: 'temurin'
205+
java-version: '21'
206+
- name: Run all webroot/execute combinations
207+
shell: bash
208+
env:
209+
LUCEE_VERSION_QUERY: 7/all/zero
210+
working-directory: ${{ github.workspace }}/tests/webroot
211+
run: |
212+
luceeVersionQuery="${LUCEE_VERSION_QUERY:-7/all/zero}"
213+
webroots=( '.' "${{ github.workspace }}/tests/webroot" )
214+
executes=( 'index.cfm' 'test.cfm' 'sub/test.cfm' )
215+
failed=0
216+
for w in "${webroots[@]}"; do
217+
for e in "${executes[@]}"; do
218+
echo "ant -buildfile ../../build.xml -Dwebroot=$w -Dexecute=\"$e\" -DpreCleanup=false -DpostCleanup=false -DluceeVersionQuery=$luceeVersionQuery"
219+
ant -buildfile ../../build.xml -Dwebroot=$w -Dexecute="$e" -DpreCleanup=false -DpostCleanup=false -DluceeVersionQuery="$luceeVersionQuery"
220+
if [ $? -ne 0 ]; then
221+
failed=1
222+
platform="windows-latest"
223+
shell="bash"
224+
echo -e "## Platform: $platform | Shell: $shell\n### ant -buildfile build.xml -Dwebroot=$w -Dexecute=\"$e\" -DpreCleanup=false -DpostCleanup=false -DluceeVersionQuery=$luceeVersionQuery\nFAILED: $w / $e\n" >> "$GITHUB_STEP_SUMMARY"
225+
fi
226+
done
227+
done
228+
exit $failed

.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
11
lucee-download-cache
22
temp
33
bin
4+
logs
5+
/temp-unique
6+
/agent-tests
7+
/.claude
8+
/test-output

CHANGELOG.md

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
# Changelog
2+
3+
All notable changes to the Lucee Script Runner project will be documented in this file.
4+
5+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7+
8+
## [Unreleased]
9+
10+
### Added
11+
12+
- **Local JAR Support**: Added `luceeJar` parameter to test locally built Lucee JARs without publishing
13+
- Accepts full path to a local JAR file
14+
- Overrides both `luceeVersion` and `luceeVersionQuery`
15+
- Perfect for Lucee core developers testing builds
16+
- **Unique Working Directories**: Added `uniqueWorkingDir` parameter with three modes:
17+
- `false` (default): Uses standard temp/lucee directory
18+
- `true`: Auto-generates unique directory with timestamp and random ID
19+
- Custom path: Uses specified directory path
20+
- **Concurrent Execution Support**: Multiple script-runner instances can now run simultaneously without conflicts
21+
- **Race Condition Detection**: Automatic detection and prevention of directory conflicts
22+
- **Improved JFR Logging**:
23+
- JFR files now output to organized `logs/` directory
24+
- Descriptive filenames: `timestamp-lucee-version-webroot-script-javaversion.jfr`
25+
- Added `logs/` to `.gitignore`
26+
- **Enhanced Error Messages**:
27+
- Git Bash path conversion detection with specific solutions
28+
- Execute script validation with exact file path shown
29+
- Windows trailing backslash validation
30+
- **Cross-Platform Path Handling**: Robust path concatenation logic for Windows and Unix systems
31+
- **Version Detection & Servlet API Handling**:
32+
- Automatic detection of Lucee 5/6 vs 7+ to select correct servlet dependencies
33+
- New `detect-version-type` target inspects version strings and JAR filenames
34+
- Split Maven pom files: `pom-javax.xml` (Lucee 5/6) and `pom-jakarta.xml` (Lucee 7+)
35+
- Seamless handling of javax to jakarta servlet API transition
36+
- Build target reordering so version detection happens before dependency resolution
37+
- **Java Agent Support**:
38+
- `-DjavaAgent=` - Path to Java agent JAR (profilers, debuggers like luceedebug)
39+
- `-DjavaAgentArgs=` - Arguments passed to the agent
40+
- `-Djdwp=` - Enable JDWP debugging agent with suspend=n (default: false)
41+
- `-DjdwpPort=` - JDWP port configuration (default: 9999)
42+
- Automatic `--add-opens=java.base/java.lang=ALL-UNNAMED` when using agents
43+
- **Advanced JVM Options**:
44+
- `-DjvmArgs=` - Raw JVM arguments string for custom configurations
45+
- `-DFlightRecordingSettings=` - JFR settings profile (default/profile/custom.jfc)
46+
- `-DPrintInlining=` - JVM compilation diagnostics (PrintInlining, PrintCompilation, UnlockDiagnosticVMOptions)
47+
- `-DPrintGCDetails=` - Detailed garbage collection logging
48+
- `-DUseEpsilonGC=` - Epsilon no-op garbage collector with AlwaysPreTouch for testing
49+
- **Version Query Format Enhancement**:
50+
- `luceeVersion` now accepts version query format (e.g., `7.0/stable/light`)
51+
- Maintains backward compatibility with `luceeVersionQuery` parameter
52+
- Unified version handling logic across both parameters
53+
54+
### Changed
55+
56+
- **Updated Lucee Version**: Standardized all references to version 7.0.1.100 across codebase
57+
- **JFR Filename Format**: Changed from `lucee-version.jar-javaversion.jfr` to descriptive format with timestamp and context
58+
- **Documentation**: Updated README.md with comprehensive working directory behavior explanations
59+
- **Build Process**:
60+
- Uncommented `include template` execution path in build-run-cfml.xml
61+
- Build target dependencies reordered: `detect-version-type` now runs before `setEnv`
62+
- Enhanced conditional property checking for javaAgent, jvmProperties, jvmArgs
63+
- Echo statements now show which servlet type is selected (javax vs jakarta)
64+
- **Error Handling**:
65+
- `_internalRequest` now captures and validates HTTP status codes
66+
- Non-200 status codes throw descriptive errors with LDEV-6086 reference
67+
- Better debugging information for script execution failures
68+
69+
### Fixed
70+
71+
- **File Path Validation Bug**: Fixed concatenation logic for execute script validation
72+
- **Git Bash Path Conversion Issues**: Added detection and helpful error messages for MSYS path conversion problems
73+
- **Build Script Path Resolution**: Fixed relative path issues when using unique working directories
74+
- **Request Timeout Detection**: Internal requests now properly detect and report non-200 status codes (LDEV-6086)
75+
76+
### Technical Details
77+
78+
#### New Ant Properties
79+
80+
- `uniqueWorkingDir`: Controls working directory behavior
81+
- `webroot.name`: Extracted basename of webroot for JFR filenames
82+
- `execute.clean`: Cleaned execute path (removes leading slashes) for JFR filenames
83+
- `execute.fullpath`: Properly concatenated full path for file validation
84+
- `javaAgent`: Path to Java agent JAR file
85+
- `javaAgentArgs`: Arguments passed to Java agent
86+
- `jdwp`: Enable JDWP debugging agent (suspend=n)
87+
- `jdwpPort`: JDWP port configuration (default: 9999)
88+
- `jvmArgs`: Raw JVM arguments string
89+
- `FlightRecordingSettings`: JFR settings profile configuration
90+
- `PrintInlining`: JVM compilation diagnostics flag
91+
- `PrintGCDetails`: Garbage collection logging flag
92+
- `UseEpsilonGC`: Epsilon no-op GC flag
93+
- `pom.file`: Dynamically selected pom file (pom-javax.xml or pom-jakarta.xml)
94+
- `version.major.extracted`: Extracted major version number for servlet API detection
95+
- `usesJavax`: Boolean flag indicating if javax servlet API is used (vs jakarta)
96+
- `servlet.type`: Servlet API type in use (javax or jakarta)
97+
98+
#### Build Process Improvements
99+
100+
- Added `set-unique-working-dir` target with timestamp generation and race condition checks
101+
- Enhanced `run-cfml` target with improved validation and path handling
102+
- Updated GitHub Actions workflow with concurrent execution tests
103+
- New `detect-version-type` target for automatic servlet API detection:
104+
- Parses version strings from `luceeVersion`, `luceeVersionQuery`, or `luceeJar` filename
105+
- Extracts major version number using regex
106+
- Selects appropriate pom file before dependency resolution
107+
- Supports various version formats: `7.0.0.1`, `lucee-7.0.jar`, `7/snapshot/zero`, file paths
108+
- Internal request result validation with status code checking
109+
110+
#### Error Handling
111+
112+
- Early validation of execute script existence under webroot
113+
- Specific error messages for common Git Bash issues
114+
- Clear guidance on workarounds and solutions
115+
- HTTP status code validation for internal requests (detects timeouts and failures)
116+
117+
### Migration Notes
118+
119+
- Existing usage remains unchanged (fully backward compatible)
120+
- New JFR files will appear in `logs/` directory instead of project root
121+
- Git users should add `logs/` to their `.gitignore` if not already present
122+
- Lucee 5/6 and 7+ now use different servlet dependencies automatically (javax vs jakarta)
123+
- Version query format can now be used with `luceeVersion` parameter directly
124+
- All new parameters are optional and have sensible defaults

0 commit comments

Comments
 (0)