/externalized

A handy DSL that makes it easier to work with external processes in Java

Primary LanguageJavaOtherNOASSERTION

Externalized Build Status

A handy DSL to make it easier to work with external processes in Java.

Usage

Sample

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.

Listeners

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 a List<String>
  • LoggingListener - pipes all output to an Slf4j logger of your choosing
  • PipingListener - 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();

Binary I/O

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();

Run Java from Java

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();

Maven

Available on Maven central.

<dependency>
  <groupId>com.github.cb372</groupId>
  <artifactId>externalized</artifactId>
  <version>0.4.0</version>
</dependency>

Dependencies

  • Java 7 or newer
  • slf4j API

Licence

Apache 2.0