slachiewicz opened a new issue, #13895: URL: https://github.com/apache/maven/issues/13895
Plugins and shared libraries that run external programs have no API for it in Maven 4. They use `org.apache.maven.shared.utils.cli` (maven-invoker, maven-jarsigner, and the jarsigner, jlink and jmod plugins) or plexus-utils `Commandline`, which is the same design with the same history of cmd.exe quoting bugs (codehaus-plexus/plexus-utils#37, apache/maven-shared-utils#434). The `cli` package is the last part of maven-shared-utils without a replacement; everything else there maps to plexus-utils, commons-io, the JDK or `MessageBuilderFactory` (apache/maven-shared-utils#452 has the usage table). The Maven 4 API has `OsService`, `JavaToolchain` and `TempFileService`, but nothing that starts a process. This proposes a process execution service in the Maven 4 API. The list below is what the current users rely on, taken from maven-invoker and maven-jarsigner and from the shared-utils API. Building a command: - executable, ordered arguments, with a way to insert leading arguments (invoker puts the `mvn` script first, then the user's options) - working directory - environment: inherit the parent environment or not, add or override variables - a stdin source (file, `InputStream`, or none) - executable resolution: `PATH` lookup with Windows extensions (`.exe`, `.cmd`, `.bat`), and a tool taken from a `JavaToolchain` (`jarsigner`, `javadoc`, `jlink`, `jmod`) instead of the running JDK Running it: - direct `ProcessBuilder` execution by default, no shell wrapper - an explicit opt-in to run through the platform shell for scripts, with quoting that is correct on cmd.exe (special characters `& < > ( ) @ ^ |`, `/D` to skip AutoRun) and on `sh`; this is where every `Commandline` implementation has had bugs - synchronous execution returning the exit code; a non-zero exit code is a result, not an exception - a timeout that destroys the process tree (`ProcessHandle.descendants()`), reported as a distinct outcome - asynchronous execution with cancellation - the child process is destroyed on JVM shutdown unless the caller opts out (shared-utils does this through `ShutdownHookUtils`) Output: - line consumers for stdout and stderr with an explicit charset, pumped on their own threads so a full pipe never blocks the child - convenience: capture to a string, redirect to a file, inherit the parent's streams, merge stderr into stdout Safety and diagnostics: - arguments that can be marked as secrets, so the logged form shows `*****` while the process gets the value (jarsigner's `-storepass` and `-keypass`; shared-utils `Arg.setMask`) - a `toString()` of the resolved command that is safe to log and that matches what the OS receives - typed failures: could not start, timed out, interrupted Out of scope: anything Maven-specific such as invoking Maven itself (maven-invoker builds on this), and the user-facing configuration of exec-maven-plugin. @gnodet, this comes out of the maven-shared-utils cleanup. Could you say whether a service like this fits the API, and if so where it belongs, in `maven-api-core` next to `OsService` or in its own module? -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
