A handy DSL to make it easier to work with external processes in Java.
ExternalProcess process = Command.parse("myscript.sh -a -b -c foo bar")
.withEnvVar("WIBBLE", "wobble") // add environment variables to the process's environment
.withWorkingDirectory(new File("/tmp")) // set the working directory
.processStdOut(consume()
.asText()
.withCharset("UTF-8")
.pipingToStdOut() // pipe process's stdout to our own stdout
.withPrefix("out>") // with "out>" prepended to every line
)
.processStdErr(consume()
.asText()
.withCharset("UTF-8")
.withLogging(usingLogger(myErrorLogger).atErrorLevel().withPrefix("Error in script!! - "))
)
.start();
See here for more examples.
You can register one or more listeners to be notified of data received on a process's stdout or stderr.
The following StreamListener
implementations are provided:
OutputCollectingListener
- saves all output from a given stream as aList<String>
LoggingListener
- pipes all output to an Slf4j logger of your choosingPipingListener
- pipes all output to our own stdout/stderr
You can easily provide your own custom listeners. Just write an implementation of StreamListener and use it as follows:
ExternalProcess process = Command.parse("foo bar baz")
.processStdOut(consume().asText().withListener(myCustomListener))
.start();
If you need to communicate with an external process using raw bytes, à la ImageMagick, you can collect stdout as binary:
BinaryOutputCollectingExternalProcess process = command("/usr/local/ImageMagick/bin/convert")
.collectStdOut().asBinary()
.start();
If you need to more complex processing of binary output, or you're worried about OutOfMemory problems, write your own custom listener and use it as follows:
ExternalProcess process = command("...")
.processStdOut(consume().asBinary().withBufferSize(2048).withListener(myCustomListener))
.start();
Yo dawg, I heard you like Java...
There is also a DSL for constructing Java commands, so you can easily run a Java class in a separate process.
By default the child process will use the same JDK/JRE and classpath as the currently running JVM.
ExternalProcess process = command(java()
.withJvmArgs("-verbose:gc", "-Xloggc:gc.log", "-Xmx512m")
.withSysProp("foo", "bar") // will be passed as -Dfoo=bar
.mainClass(PrintHello.class) // the class to run
.withArgs("hello", "world"))
.withWorkingDirectory(...) // you can configure everything you would with a normal process
.processStdOut(...)
.start();
Available on Maven central.
<dependency>
<groupId>com.github.cb372</groupId>
<artifactId>externalized</artifactId>
<version>0.4.0</version>
</dependency>
- Java 7 or newer
- slf4j API
Apache 2.0