English 中文(简体)
Deciding between Apache Commons exec or ProcessBuilder
原标题:

I am trying to decide as to whether to use ProcessBuilder or Commons exec,

My requirements are that I am simply trying to create a daemon process whose stdout/stdin/stderr I do not care about. In addition I want to execute a kill to destroy this process when the time comes.

I am using Java on Linux.

I know that both have their pains and pitfalls (such as being sure to use separate thread to swallow streams can lead to blocking or deadlocks, and closing the streams so not to leave open files hanging around) and wanted to know if anyone had suggestions one way or the other as well as any good resources to follow.

最佳回答

commons-exec is not the best library I ve ever used but it does solve the biggest pitfall in Java process invocation which is handling/consuming stdout/sterr properly. I ve used ProcessBuilder in the past, which is fine, and commons-exec now which is also fine and handles most of the common cases easily.

问题回答

The ZT Process Executor library is an alternative to Apache Commons Exec. It has functionality to run commands, capture their output, set timeouts, verify program exit status etc.

I have used it a little and I find it well-designed reasonably well-documented.

Example from the documentation

Executing a command, pumping the stderr to a logger, returning the output as UTF8 string.

 String output = new ProcessExecutor().command("java", "-version")
    .redirectError(Slf4jStream.of(getClass()).asInfo())
    .readOutput(true).execute()
    .outputUTF8();

Its documentation lists the following advantages over Commons Exec:

  • Improved handling of streams
  • Reading/writing to streams
  • Redirecting stderr to stdout
  • Improved handling of timeouts
  • Improved checking of exit codes
  • Improved API
  • One liners for quite complex usecases
  • One liners to get process output into a String
  • Access to the Process object available
  • Support for async processes ( Future )
  • Improved logging with SLF4J API
  • Support for multiple processes

May be my Exec library could be of any interest to you?

If you want to use a daemon process, maybe Apache Commons Daemon would be more appropriate?

Commons Daemon does the job of starting a Java process as a daemon, but it doesn t do it the way one would expect. For example, when a standard C program starts a daemon (take apache or sshd for example), they perform some config sanity checks and other things (like locking a lockfile) before forking into the background. Apache Commons Daemon is a c program that launches a java app and doesn t let you put the sanity checks in the Java code AFAIK and thus breaks what I would consider important daemon facilities.

Thus, if you are looking to implement a daemon launcher that behaves similar to sshd, apache, etc. then I would suggest commons exec.

Now days you can perform most tasks pretty easily using ProcessBuilder, and the need for libraries such as ZT Process Executor or Commons Exec is not so great any more.

This is great, because together with the ability to run Java programs without a separate compilation step (java SomeProgram.java), you can now use Java for shell scripting tasks.

The following code demonstrates how to fulfil the requirements given in the question:

var process = new ProcessBuilder()
        .redirectError(Redirect.DISCARD)
        .redirectOutput(Redirect.DISCARD)
        .start();

if (!process.waitFor(10, TimeUnit.SECONDS)) {
    process.destroyForcibly();
}

if (process.exitValue() != 0) {
    // Handle error
}

One thing that is often necessary for shell script style programs is to capture the output of an external command. This is still a bit tricky in Java, but it can be done using the snippet in this answer.





相关问题
Spring Properties File

Hi have this j2ee web application developed using spring framework. I have a problem with rendering mnessages in nihongo characters from the properties file. I tried converting the file to ascii using ...

Logging a global ID in multiple components

I have a system which contains multiple applications connected together using JMS and Spring Integration. Messages get sent along a chain of applications. [App A] -> [App B] -> [App C] We set a ...

Java Library Size

If I m given two Java Libraries in Jar format, 1 having no bells and whistles, and the other having lots of them that will mostly go unused.... my question is: How will the larger, mostly unused ...

How to get the Array Class for a given Class in Java?

I have a Class variable that holds a certain type and I need to get a variable that holds the corresponding array class. The best I could come up with is this: Class arrayOfFooClass = java.lang....

SQLite , Derby vs file system

I m working on a Java desktop application that reads and writes from/to different files. I think a better solution would be to replace the file system by a SQLite database. How hard is it to migrate ...

热门标签