Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

ProcessBuilder.start() without waiting?

4,213 views
Skip to first unread message

Steve Sobol

unread,
Aug 14, 2008, 2:05:06 AM8/14/08
to
I'd like to execute an external program using start() but the JVM waits until
the executed program exits before continuing execution. Is there any way to
use start() synchronously?

Thanks

--
Steve Sobol / Victorville, CA, USA
It's all fun and games until someone starts a bonfire in the living room.

Peter Duniho

unread,
Aug 14, 2008, 2:21:58 AM8/14/08
to
On Wed, 13 Aug 2008 23:05:06 -0700, Steve Sobol <sjs...@justthe.net>
wrote:

> I'd like to execute an external program using start() but the JVM waits
> until
> the executed program exits before continuing execution. Is there any way
> to
> use start() synchronously?

What JVM are you using? ProcessBuilder.start() should return before the
process exits. After all, what point would there be in it returning the
Process object if by the time you got it, the associated process was gone?

(By the way, the phrase "use start() synchronously" actually implies the
opposite of what you seem to be looking for. That is, "synchronously"
means that you wait. "Asynchronously" would mean it returns before it's
completed).

Pete

EJP

unread,
Aug 14, 2008, 2:28:32 AM8/14/08
to
Steve Sobol wrote:
> I'd like to execute an external program using start() but the JVM waits until
> the executed program exits before continuing execution.

No it doesn't. ProcessBuilder.start(), which presumably is what you are
talking about, is asynchronous.

Possibly your code is faulty?

Andrea Francia

unread,
Aug 14, 2008, 3:24:56 AM8/14/08
to
Steve Sobol wrote:
> I'd like to execute an external program using start() but the JVM waits until
> the executed program exits before continuing execution.

This is strange. Post the code so someone could review it.

> Is there any way to
> use start() synchronously?
>
> Thanks
>
>
>


--
Andrea Francia
http://www.andreafrancia.it/

Daniele Futtorovic

unread,
Aug 14, 2008, 5:22:47 AM8/14/08
to
On 14/08/2008 08:05, Steve Sobol allegedly wrote:
> I'd like to execute an external program using start() but the JVM waits until
> the executed program exits before continuing execution. Is there any way to
> use start() synchronously?

Don't call waitFor()?

--
DF.

Steve Sobol

unread,
Aug 14, 2008, 10:15:36 AM8/14/08
to
On 2008-08-14, Peter Duniho <NpOeS...@nnowslpianmk.com> wrote:

> What JVM are you using?

1.6 Update N beta something, I forget which beta.

> ProcessBuilder.start() should return before the
> process exits.

It does, but I want to launch a program and exit the JVM immediately, so
I do a pb.start() and then a System.exit(0), and the calling program does not
exit immediately, it waits until the called program terminates.

> (By the way, the phrase "use start() synchronously" actually implies the
> opposite of what you seem to be looking for. That is, "synchronously"
> means that you wait. "Asynchronously" would mean it returns before it's
> completed).

Thank you.

Steve Sobol

unread,
Aug 14, 2008, 10:17:19 AM8/14/08
to
On 2008-08-14, Andrea Francia <andrea....@gmx.REMOVE_FROM_HERE_ohohohioquestoèdatogliereohohoho_TO_HERE.it> wrote:
> Steve Sobol wrote:
>> I'd like to execute an external program using start() but the JVM waits until
>> the executed program exits before continuing execution.
>
> This is strange. Post the code so someone could review it.
>

String path = dt.getUpdateFile().getAbsolutePath();
System.out.println("Path: " + path + "/" +
dt.getUpdateFile().getParent());
ProcessBuilder pb = new ProcessBuilder("start",path);
pb.start();
System.exit(0); // Does not get executed until the called prog ends

Knute Johnson

unread,
Aug 14, 2008, 11:45:32 AM8/14/08
to
Steve Sobol wrote:
> On 2008-08-14, Andrea Francia <andrea....@gmx.REMOVE_FROM_HERE_ohohohioquestoèdatogliereohohoho_TO_HERE.it> wrote:
>> Steve Sobol wrote:
>>> I'd like to execute an external program using start() but the JVM waits until
>>> the executed program exits before continuing execution.
>> This is strange. Post the code so someone could review it.
>>
>
> String path = dt.getUpdateFile().getAbsolutePath();
> System.out.println("Path: " + path + "/" +
> dt.getUpdateFile().getParent());
> ProcessBuilder pb = new ProcessBuilder("start",path);
> pb.start();
> System.exit(0); // Does not get executed until the called prog ends
>
>
>

From the docs;

"There is no requirement that a process represented by a Process object
execute asynchronously or concurrently with respect to the Java process
that owns the Process object."

If you have a GUI program, maybe you could just close the frame and
nobody would be the wiser. Then it will exit when the process stops.

--

Knute Johnson
email s/nospam/knute2008/

--
Posted via NewsDemon.com - Premium Uncensored Newsgroup Service
------->>>>>>http://www.NewsDemon.com<<<<<<------
Unlimited Access, Anonymous Accounts, Uncensored Broadband Access

Andrea Francia

unread,
Aug 14, 2008, 1:20:52 PM8/14/08
to
Steve Sobol wrote:
> On 2008-08-14, Andrea Francia <andrea....@gmx.REMOVE_FROM_HERE_ohohohioquestoèdatogliereohohoho_TO_HERE.it> wrote:
>> Steve Sobol wrote:
>>> I'd like to execute an external program using start() but the JVM waits until
>>> the executed program exits before continuing execution.
>> This is strange. Post the code so someone could review it.
>>
>
> String path = dt.getUpdateFile().getAbsolutePath();
> System.out.println("Path: " + path + "/" +
> dt.getUpdateFile().getParent());
> ProcessBuilder pb = new ProcessBuilder("start",path);
> pb.start();

I think you should read (and maybe discard) the standard output and
error of the child process otherwise it may hang waiting when the buffer
became empty.

You can use something like that to discard the standard output:

03 (new Thread() {
04 public void run() {
05 try {
06 while(process.getInputStream().read()!=-1);
07 } catch (IOException ex) {
08 }
09 }}).start();

The same thing is true for the standard error. But in this case you can
use the ProcessBuilder#redirectErrorStream(true)

> System.exit(0); // Does not get executed until the called prog ends

To avoid this:

Under linux use the "nohup" utility that detaches the subprocess from
its parent and attach under the init process (PID=1).

Under Windows, I don't know, I thought that using the 'start' command
will suffice.

Steve Sobol

unread,
Aug 14, 2008, 5:10:56 PM8/14/08
to
On 2008-08-14, Knute Johnson <nos...@rabbitbrush.frazmtn.com> wrote:

> If you have a GUI program, maybe you could just close the frame and
> nobody would be the wiser. Then it will exit when the process stops.

Nope. The situation is this:

** I check online for updates to a Java program I'm writing.
** If I find one, I download it and execute it; in this case, it's an
installer that will overwrite the program's JARs, etc., so I want the
program to NOT be running while the installer is running.

Perhaps ProcessBuilder.start() isn't the right approach to use.

Knute Johnson

unread,
Aug 14, 2008, 8:14:46 PM8/14/08
to
Steve Sobol wrote:
> On 2008-08-14, Knute Johnson <nos...@rabbitbrush.frazmtn.com> wrote:
>
>> If you have a GUI program, maybe you could just close the frame and
>> nobody would be the wiser. Then it will exit when the process stops.
>
> Nope. The situation is this:
>
> ** I check online for updates to a Java program I'm writing.
> ** If I find one, I download it and execute it; in this case, it's an
> installer that will overwrite the program's JARs, etc., so I want the
> program to NOT be running while the installer is running.
>
> Perhaps ProcessBuilder.start() isn't the right approach to use.
>
>

I've had a similar problem. We had an application that we wanted to do
remote updating on. We sent the file and wrote it out to disk with a
different name than the current program and then started it with Process
just like you are doing. Jar files don't need the .jar extension to
work by the way. This wasn't a 100% successful and the project folded
up anyway so we didn't pursue it to a conclusion. Buy my last thought
on the subject was to use a control program to load the actual program
from disk. This way the files could be overwritten or at least I think
they can be. It appears to be a conundrum and if you come up with a
good solution, please post it here.

Mark Space

unread,
Aug 14, 2008, 9:18:06 PM8/14/08
to
Knute Johnson wrote:

> I've had a similar problem. We had an application that we wanted to do
> remote updating on. We sent the file and wrote it out to disk with a
> different name than the current program and then started it with Process
> just like you are doing. Jar files don't need the .jar extension to
> work by the way. This wasn't a 100% successful and the project folded

I don't have any experience with this sort of thing, but I was thinking
a JNI method might be in order. Call the native method so that it can
launch the app however the OS needs to so it's not a subprocess/child
whatever and the parent app can exit immediately with out leaving
zombies around.

On the Java side, you can wrap this up in a Java class that grabs the OS
and hardware from the properties, and then decides which of several
native method stubs it needs to launch.

Yeah if someone want to do this for me I'd like to see the result too. ;-)

Steve Sobol

unread,
Aug 20, 2008, 2:50:56 PM8/20/08
to


Nah. Figured it out.

But first I had to go through a buttload of pain using JNI, which I
THOUGHT would be the best bet.

Then I realized where the solution lies. The first app that uses this update
utility I'm writing will be a program that presents a popup menu in
the Windows system tray and allows you to open URLs and documents and launch
programs from it. Well, the main app calls RUNDLL32.EXE, a Windows program
that lets you call DLL functions from the command line or a batch file, and
uses RUNDLL32 to call ShellExec.

ShellExec is a Windows library call that launches an app. Or you can pass it a
URL or the path to a document, and if a default app or handler is registered
for the type of URL or document you're opening, it'll automatically open it
(for example, http:// URLs would, by default, open in the default web
browser, and .doc files open in Microsoft Word by default).

ShellExec creates a new process where the new app will run, and exits
immediately. It's perfect!

public void launch(String path) {
String commandLine = "rundll32 shell32.dll,ShellExec_RunDLL " + path;
String[] args = commandLine.split(" ");
ProcessBuilder pb = new ProcessBuilder(args);
try {
pb.start();
} catch (Exception exc) {
JOptionPane.showMessageDialog(null, exc.getMessage(),
"Can't launch file/program", JOptionPane.ERROR_MESSAGE);
}
}

A call to launch() followed by a System.exit(0) works EXACTLY the way I
want it to work.

For Linux/FreeBSD/OS X, what I'll probably do is write a small C program
that forks a new process and uses execl, and call it this way. I can write
that program in such a way that it will be uber-portable.

Thanks to everyone for the suggestions.

0 new messages