Global System.out/System.err redirection and static lock serialize all script runs JVM-wide

Open
#205 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
5/5
Estimated time
Over a week
Newbie friendliness
35/100
Issue type
Bug
Clarity
Mostly clear
Activity status
Active
Tech stack
java
Domain
build-system

Research direction

Start with ScriptRunner.java at lines 43 and 225, then read the evaluation sections of BeanShellScriptInterpreter.java (108-158) and GroovyScriptInterpreter.java (96-123). Trace the current stream restoration in finally blocks before assessing instance-level locking and thread/task-specific output. Done means unrelated JVM threads are not captured and independent script runs no longer serialize globally.

Written by the indexing model from the issue text.

Description

Describe the bug

Script evaluation redirects the JVM-global standard streams, and script execution is serialized behind a static lock to keep that redirection safe. Both have process-wide side effects.

The BeanShell and Groovy interpreters call System.setOut/System.setErr for the whole JVM during evaluation (BeanShellScriptInterpreter.java:108-158, GroovyScriptInterpreter.java:96-123). While a script runs:

  • output written to System.out/System.err by unrelated threads in the same JVM (e.g. a logger writing to stderr, parallel build code) is silently captured into the script log; and
  • a concurrently running script on another thread would otherwise clobber the redirected stream.

ScriptRunner guards against concurrent evaluation with a static lock (ScriptRunner.java:43, used at ScriptRunner.java:225). Consequences:

  1. All run(...) calls across all ScriptRunner instances in the JVM are serialized, which is a bottleneck for parallel/CI builds that run hook scripts in multiple modules simultaneously.
  2. Correctness of the global stream redirection depends entirely on every caller routing evaluation through that single static lock. Any future code path (or a caller invoking an interpreter directly) that evaluates outside the lock silently reintroduces cross-thread stream corruption.

Eclipse/Maven environment parallel builds; maven-script-interpreter 1.9-SNAPSHOT.

Expected behavior

Script output redirection affects only the current evaluation; unrelated threads keep writing to their own stdout/stderr, and concurrent script runs in the same JVM do not interfere.

Actual behavior

  • JVM-wide System.out/System.err redirection during evaluation captures other threads' output into the script log.
  • A single static lock serializes every ScriptRunner.run(...) call JVM-wide.

Suggested approach

  • Use a per-instance lock instead of the static lock so independent ScriptRunner instances do not serialize each other.
  • Redirect output via a stream that dispatches on the current thread/task (e.g. a ThreadLocal-based OutputStream) rather than mutating the process-global standard streams; restore the originals exactly as today in a finally block.
Dominant language
Java
Stars
14
Forks
9
Avg merge
3d 16h
Merged PRs (30d)
5

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from apache/maven-script-interpreter

All issues in apache/maven-script-interpreter

Similar issues

More Java issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.