Reputation: 19442
I've inherited a Java web-services code-base (BEA/Oracle Weblogic) and need to start/launch an external background application from a web-service.
I've already tried:
ProcessBuilder pb = new ProcessBuilder(arg);
pb.start();
as well as:
Runtime.exec(cmdString);
But am experiencing strange behaviors when launching applications in this manner (i.e. the launched application stops working even though the process is still active. -- The application works fine when manually run from a normal command line).
Is there a better way to launch an external processes?
EDIT: ----------------------
I have some additional information that may help shed some light on the problem.
waitfor()
) in the webservice will not be an ideal scenario.I have had success when I use process builder to start a bash script, where the external application is launched as a background process (using "&").
#!/bin/bash
java -jar myApp.jar &
This obviously creates an orphaned process but at least the application does continue to execute.
Upvotes: 2
Views: 4123
Reputation: 66681
Firstly, is this happening on Windows or on Linux? Also, what is the launched application supposed to more or less do? (is it a script? is it a binary? is it your binary?)
EDIT
OK, so starting a bash
script (using ProcessBuilder
) which in turns spawns a new JVM (java -jar myApp.jar
) works.
What happens exactly when you try to spawn the new JVM directly using ProcessBuilder
? You originally said:
the launched application stops working
bash
script?ProcessBuilder
methods (and in which order) when you try to launch Java directly and this new JVM stops working? (e.g. provide annotated code)lsof
on your *nix machine, what file is shown to be associated with file descriptor 2 (look at the FD
column) when running: lsof -p 1234
(where 1234
is the process ID of the "hung" JVM?) It might be interesting to attach the entire output of the lsof
command here.kill -QUIT 1234
(where 1234
is the process ID of the "hung" JVM?)Upvotes: 2
Reputation: 2436
Simply put: if the launched application writes to SDTOUT/STDIN and you don't flush them frequently (see Process.getErrorStream/Process.getInputStream) then the process will block when the buffer is full (that is really small, 4KB or less).
I recommend you to invoke ProcessBuilder.redirectErrorStream() before starting the process. Then, after that, create a thread with the run() method along the lines of:
public void run() {
BufferedReader reader =
new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
}
Upvotes: 2
Reputation: 1067
By "stops working even though the process is still active" I am assuming you might be expecting some output from the application you have launched and not getting anything.
Try using the following:
ProcessBuilder pb = new ProcessBuilder(arg);
Process p = pb.start();
p.waitFor();
waitFor() causes the current thread to wait, if necessary, until the process represented by this Process object has terminated.
http://java.sun.com/javase/6/docs/api/java/lang/Process.html#waitFor()
Upvotes: 2
Reputation: 54421
Are you properly handling the standard input and output of the process? If the standard input or output is being processed by your application and you are not properly handling it, then the process you execute will hang waiting for I/O.
A way to test this is to write a script that runs your program, redirecting standard input, output and error to files. Then have your web service app run the script instead of the program. If the program runs to completion this way, then the problem is handling of the output of the process.
Upvotes: 1
Reputation: 38116
I'm guessing that the problem might be the thread that launches the process gets TERMINATED or whatever after the request is over. Try having a single thread in the applicaton that you are sure is kept alive always, you can use this for starting the processes by making calls to it from other threads.
Upvotes: 0