-
Notifications
You must be signed in to change notification settings - Fork 31
Introduce process API #418
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<project xmlns="http://maven.apache.org/POM/4.0.0" | ||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
<modelVersion>4.0.0</modelVersion> | ||
<parent> | ||
<groupId>io.smallrye.common</groupId> | ||
<artifactId>smallrye-common-parent</artifactId> | ||
<version>3.0.0-SNAPSHOT</version> | ||
</parent> | ||
|
||
<artifactId>smallrye-common-process</artifactId> | ||
|
||
<name>SmallRye Common: Process</name> | ||
<description>Process management utilities</description> | ||
|
||
<dependencies> | ||
<dependency> | ||
<groupId>${project.groupId}</groupId> | ||
<artifactId>smallrye-common-function</artifactId> | ||
</dependency> | ||
<dependency> | ||
<groupId>${project.groupId}</groupId> | ||
<artifactId>smallrye-common-os</artifactId> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.jboss.logging</groupId> | ||
<artifactId>jboss-logging</artifactId> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.jboss.logging</groupId> | ||
<artifactId>jboss-logging-annotations</artifactId> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.junit.jupiter</groupId> | ||
<artifactId>junit-jupiter-engine</artifactId> | ||
<scope>test</scope> | ||
</dependency> | ||
</dependencies> | ||
<build> | ||
<plugins> | ||
<plugin> | ||
<groupId>org.apache.maven.plugins</groupId> | ||
<artifactId>maven-compiler-plugin</artifactId> | ||
<configuration> | ||
<annotationProcessorPaths> | ||
<annotationProcessorPath> | ||
<groupId>org.jboss.logging</groupId> | ||
<artifactId>jboss-logging-processor</artifactId> | ||
</annotationProcessorPath> | ||
</annotationProcessorPaths> | ||
</configuration> | ||
</plugin> | ||
<plugin> | ||
<artifactId>maven-javadoc-plugin</artifactId> | ||
<configuration> | ||
<docfilessubdirs>true</docfilessubdirs> | ||
</configuration> | ||
</plugin> | ||
<plugin> | ||
<artifactId>maven-surefire-plugin</artifactId> | ||
<configuration> | ||
<systemPropertyVariables> | ||
<java.util.logging.config.class>io.smallrye.common.process.LoggingConfigurator</java.util.logging.config.class> | ||
</systemPropertyVariables> | ||
</configuration> | ||
</plugin> | ||
</plugins> | ||
</build> | ||
|
||
<profiles> | ||
<profile> | ||
<id>coverage</id> | ||
<properties> | ||
<argLine>@{jacocoArgLine}</argLine> | ||
</properties> | ||
<build> | ||
<plugins> | ||
<plugin> | ||
<groupId>org.jacoco</groupId> | ||
<artifactId>jacoco-maven-plugin</artifactId> | ||
<executions> | ||
<execution> | ||
<id>report</id> | ||
<phase>verify</phase> | ||
<goals> | ||
<goal>report</goal> | ||
</goals> | ||
</execution> | ||
</executions> | ||
</plugin> | ||
</plugins> | ||
</build> | ||
</profile> | ||
</profiles> | ||
|
||
|
||
</project> |
160 changes: 160 additions & 0 deletions
160
process/src/main/java/io/smallrye/common/process/AbnormalExitException.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,160 @@ | ||
package io.smallrye.common.process; | ||
|
||
import java.io.Serial; | ||
import java.util.List; | ||
|
||
import io.smallrye.common.os.OS; | ||
|
||
/** | ||
* An exception indicating that a process has exited with an abnormal status. | ||
* Any additional problems will be recorded as suppressed exceptions. | ||
*/ | ||
public class AbnormalExitException extends ProcessExecutionException { | ||
@Serial | ||
private static final long serialVersionUID = -2058346021193103167L; | ||
|
||
/** | ||
* The process exit code, if known. | ||
*/ | ||
private int exitCode = -1; | ||
/** | ||
* Set to {@code true} if the soft timeout was known to have elapsed. | ||
*/ | ||
private boolean softTimeoutElapsed; | ||
/** | ||
* Set to {@code true} if the hard timeout was known to have elapsed. | ||
*/ | ||
private boolean hardTimeoutElapsed; | ||
/** | ||
* The captured lines of error output. | ||
*/ | ||
private List<String> errorOutput = List.of(); | ||
|
||
/** | ||
* Constructs a new {@code AbnormalExitException} instance. The message is left blank ({@code null}), and no | ||
* cause is specified. | ||
*/ | ||
public AbnormalExitException() { | ||
} | ||
|
||
/** | ||
* Constructs a new {@code AbnormalExitException} instance with an initial message. No | ||
* cause is specified. | ||
* | ||
* @param msg the message | ||
*/ | ||
public AbnormalExitException(final String msg) { | ||
super(msg); | ||
} | ||
|
||
/** | ||
* Constructs a new {@code AbnormalExitException} instance with an initial cause. If | ||
* a non-{@code null} cause is specified, its message is used to initialize the message of this | ||
* {@code ProcessException}; otherwise the message is left blank ({@code null}). | ||
* | ||
* @param cause the cause | ||
*/ | ||
public AbnormalExitException(final Throwable cause) { | ||
super(cause); | ||
} | ||
|
||
/** | ||
* Constructs a new {@code AbnormalExitException} instance with an initial message and cause. | ||
* | ||
* @param msg the message | ||
* @param cause the cause | ||
*/ | ||
public AbnormalExitException(final String msg, final Throwable cause) { | ||
super(msg, cause); | ||
} | ||
|
||
/** | ||
* {@return the exit code of the process} | ||
*/ | ||
public int exitCode() { | ||
return exitCode; | ||
} | ||
|
||
/** | ||
* Set the exit code of the process. | ||
* | ||
* @param exitCode the exit code | ||
*/ | ||
public void setExitCode(final int exitCode) { | ||
this.exitCode = exitCode; | ||
} | ||
|
||
/** | ||
* {@return {@code true} if the soft timeout elapsed before the process exited} | ||
*/ | ||
public boolean softTimeoutElapsed() { | ||
return softTimeoutElapsed; | ||
} | ||
|
||
/** | ||
* Set whether the soft timeout elapsed before the process exited. | ||
* | ||
* @param softTimeoutElapsed {@code true} if the soft timeout elapsed before the process exited | ||
*/ | ||
public void setSoftTimeoutElapsed(final boolean softTimeoutElapsed) { | ||
this.softTimeoutElapsed = softTimeoutElapsed; | ||
} | ||
|
||
/** | ||
* {@return {@code true} if the hard timeout elapsed before the process exited} | ||
*/ | ||
public boolean hardTimeoutElapsed() { | ||
return hardTimeoutElapsed; | ||
} | ||
|
||
/** | ||
* Set whether the hard timeout elapsed before the process exited. | ||
* | ||
* @param hardTimeoutElapsed {@code true} if the hard timeout elapsed before the process exited | ||
*/ | ||
public void setHardTimeoutElapsed(final boolean hardTimeoutElapsed) { | ||
this.hardTimeoutElapsed = hardTimeoutElapsed; | ||
} | ||
|
||
/** | ||
* {@return the captured error output of the process execution, if any} | ||
*/ | ||
public List<String> errorOutput() { | ||
return errorOutput; | ||
} | ||
|
||
/** | ||
* Set the captured error output of the process execution. | ||
* | ||
* @param errorOutput the captured error output of the process execution | ||
*/ | ||
public void setErrorOutput(final List<String> errorOutput) { | ||
this.errorOutput = List.copyOf(errorOutput); | ||
} | ||
|
||
public StringBuilder toString(StringBuilder b) { | ||
super.toString(b); | ||
b.append(" with exit code ").append(exitCode); | ||
if (OS.current() != OS.WINDOWS && exitCode > 128 && exitCode <= 192) { | ||
// todo: add signal names and descriptions to OS module? | ||
b.append(" (possibly due to signal ").append(exitCode - 128).append(')'); | ||
} | ||
if (softTimeoutElapsed) { | ||
if (hardTimeoutElapsed) { | ||
b.append(" after soft and hard timeouts elapsed"); | ||
} else { | ||
b.append(" after soft timeout elapsed"); | ||
} | ||
} else if (hardTimeoutElapsed) { | ||
b.append(" after hard timeout elapsed"); | ||
} | ||
List<String> errorOutput = this.errorOutput; | ||
if (!errorOutput.isEmpty()) { | ||
b.append(" with error output:"); | ||
for (String line : errorOutput) { | ||
b.append("\n > ").append(line); | ||
} | ||
} | ||
return b; | ||
} | ||
} |
85 changes: 85 additions & 0 deletions
85
process/src/main/java/io/smallrye/common/process/AbstractExecutionException.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
package io.smallrye.common.process; | ||
|
||
import java.io.Serial; | ||
|
||
/** | ||
* The base type of all execution exception types. | ||
*/ | ||
public abstract class AbstractExecutionException extends RuntimeException { | ||
@Serial | ||
private static final long serialVersionUID = 7071176650961828059L; | ||
|
||
/** | ||
* Constructs a new {@code AbstractExecutionException} instance with an initial message and cause, | ||
* and configuring whether the stack trace is writable. | ||
* | ||
* @param message the message | ||
* @param cause the cause | ||
* @param writableStackTrace {@code true} to allow writable stack traces | ||
*/ | ||
protected AbstractExecutionException(final String message, final Throwable cause, final boolean writableStackTrace) { | ||
super(message, cause, true, writableStackTrace); | ||
} | ||
|
||
/** | ||
* Constructs a new {@code AbstractExecutionException} instance. The message is left blank ({@code null}), and no | ||
* cause is specified. | ||
*/ | ||
protected AbstractExecutionException() { | ||
} | ||
|
||
/** | ||
* Constructs a new {@code AbstractExecutionException} instance with an initial message. No | ||
* cause is specified. | ||
* | ||
* @param msg the message | ||
*/ | ||
protected AbstractExecutionException(final String msg) { | ||
super(msg); | ||
} | ||
|
||
/** | ||
* Constructs a new {@code AbstractExecutionException} instance with an initial cause. If | ||
* a non-{@code null} cause is specified, its message is used to initialize the message of this | ||
* {@code AbstractExecutionException}; otherwise the message is left blank ({@code null}). | ||
* | ||
* @param cause the cause | ||
*/ | ||
protected AbstractExecutionException(final Throwable cause) { | ||
super(cause); | ||
} | ||
|
||
/** | ||
* Constructs a new {@code AbstractExecutionException} instance with an initial message and cause. | ||
* | ||
* @param msg the message | ||
* @param cause the cause | ||
*/ | ||
protected AbstractExecutionException(final String msg, final Throwable cause) { | ||
super(msg, cause); | ||
} | ||
|
||
/** | ||
* Render this exception to the given string builder. | ||
* | ||
* @param sb the string builder (must not be {@code null}) | ||
* @return the same string builder (not {@code null}) | ||
*/ | ||
public StringBuilder toString(StringBuilder sb) { | ||
String className = getClass().getName(); | ||
sb.append(className); | ||
String message = getLocalizedMessage(); | ||
if (message != null) { | ||
sb.append(':').append(' '); | ||
sb.append(message); | ||
} | ||
return sb; | ||
} | ||
|
||
/** | ||
* {@return a short description of this exception} | ||
*/ | ||
public final String toString() { | ||
return toString(new StringBuilder()).toString(); | ||
} | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is this stderr only ? what about stdout?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could capture stdout here, but doing so would mean adding "tee" support broadly. This can be done, but would require more effort. It's also possible that we could introduce this in the future.