how to run s subprogram silently?

M

Marteno Rodia

Hello,
today I have another newbie's question:

I have an external Java application and I need to invoke it in my
code. I have even access to the source code of this application so I
can do something like this:

String[] args = {"something", "something_else", "another_argument"};
ExtApp.main(args);

The problem is I want to run ExtApp silently - it means I don't want
it to print any messages on the error and standard output stream...
I'd like to redirect this information to a file or just ignore it. How
to do it?

MR
 
A

Andreas Leitgeb

Marteno Rodia said:
I have an external Java application and I need to invoke it in my
code. I have even access to the source code of this application so I
can do something like this:
String[] args = {"something", "something_else", "another_argument"};
ExtApp.main(args);

This way of calling it will run the nested app as part your application,
and if the nested one happens to do System.exit() at its end, your
application is terminated as well. Also, if the nested app starts off
threads, then its main() method may return while other threads are still
active, and daemon-threads may not be cleaned up, as the jvm is still
running.

If that all is no problem, then your main app could save away System.out
and System.err (if it needs those, itself) and replace them with some
null streams (e.g. /dev/null opened by an OutputStream) that the
nested application will see.

If the applications do not really cooperate, then you're probably
better off, starting another virtual machine per Runtime.exec().
 
M

Marteno Rodia

If the applications do not really cooperate, then you're probably
better off, starting another virtual machine per Runtime.exec().

Reading all your responses I realised that I'm facing a greater
problem than I excpected. The first, I don't want my subprogram, which
hapens to invoke the exit() function in some cases, to stop the entire
application (the "superprogram" ;) ). The second, there are multiple
threads in both the subprogram and superprogram, and I'd like to
intercept or suppress messages being printed on error and output
streams by the subprogram, while messages originating from all the
other threads of the superprogram should be visible. How to do it?
After reading the documentation and Internet resources, I came to
conclusion that I should use Runtime.exec() and then
Process.getInputStream() to capture the output stream! (the output of
the subprogram is the input of the superprogram).

Is it really the only possible solution? I would prefer not to invoke
my subprogram as an external application, but rather just like a
method.

MR
 
N

Nigel Wade

Marteno said:
Reading all your responses I realised that I'm facing a greater
problem than I excpected. The first, I don't want my subprogram, which
hapens to invoke the exit() function in some cases, to stop the entire
application (the "superprogram" ;) ). The second, there are multiple
threads in both the subprogram and superprogram, and I'd like to
intercept or suppress messages being printed on error and output
streams by the subprogram, while messages originating from all the
other threads of the superprogram should be visible. How to do it?
After reading the documentation and Internet resources, I came to
conclusion that I should use Runtime.exec() and then
Process.getInputStream() to capture the output stream! (the output of
the subprogram is the input of the superprogram).

Is it really the only possible solution? I would prefer not to invoke
my subprogram as an external application, but rather just like a
method.

MR

The only other solution I can think of (you say you have full access to the
source of the "sub-program"?) would be to use a Logger rather than
System.out/.err. If your "sub-program" is running within the same JVM as the
main program then it will share System.out/.err and you cannot separate their
output. If your sub-program uses a Logger for output then you should be able to
control that quite adequately.
 
C

charlesbos73

After reading the documentation and Internet resources, I came to
conclusion that I should use Runtime.exec() and then

that would be one way of doing it

Process.getInputStream() to capture the output stream! (the output of
the subprogram is the input of the superprogram).

No, that is not mandatory at all.

If you want to go the Runtime.exec() route, then I'd
simply give you the following advice that shall save
you a lot of "stream processing" / "stream consuming"
headaches:

wrap the call to your Java program inside a script
that suppresses all outputs from your Java program.

Instead of doing Runtime.exec( "Java prog" )

you do Runtime.exec ( "script that wraps Java prog" )

For example a Bash shell script (for, say, Linux and OS X),
doing that could look like:

#!/bin/bash
#
# Shell script that suppresses output
#
java -jar myprog.jar >/dev/null 2>/dev/null

Under Windows a simple @echo off at the beginning
of a batch script would do.

If you do actually care about the output, redirect
to a file instead of /dev/null and parse that file.

That shall be incredibly easier than trying to
consume the streams yourself from your "outter"
Java program.

Especially if, in your case, you really don't need
these outputs. Simply Runtime.exec the wrapper
script without waiting.

This is such a common concern that there ought to be some
helper methods/libs (maybe in Jakarta commons?) mimicking
the way C# does it:

process.StartInfo.Arguments = "> NULL";

And poof, no more outputs :)


P.S: don't try to suppress the output directly
from Runtime.exec(...) for the redirection symbols
don't work as you'd think.
 
A

Andreas Leitgeb

Reading all your responses I realised that I'm facing a greater
problem than I excpected. The first, I don't want my subprogram, which
hapens to invoke the exit() function in some cases, to stop the entire
application (the "superprogram" ;) ).

If you have the source of the subprogram, you could of course
replace all System.exit() invocations by something else, and
furthermore all System.out.println's (and it's siblings) by
your own methods that append the data to some global ArrayList
:)
After reading the documentation and Internet resources, I came to
conclusion that I should use Runtime.exec() and then
Process.getInputStream() to capture the output stream! (the output of
the subprogram is the input of the superprogram).

This is an entirely different approach, and it depends on the actual
involved applications, whether this one is easier or harder than the
abovementioned approach.
Is it really the only possible solution? I would prefer not to invoke
my subprogram as an external application, but rather just like a
method.

But hey, you're just invoking a method Process.exec afterall :)

A third approach would be one used by application servers, which do some
ClassLoader stuff to give each servlet some separate environment and
doing stuff to inhibit System.exit(), but I think doing that yourself
in your superprogram may be the hardest way.

I'm not aware of a simple (and platform-neutral) method to "call that class'
Main in a fork of this JVM as an entirely separate system process" although
I'd agree it would be a very useful one.
Not sure, if such a method could be built upon Process.exec() and some
system properties that reliably point to the same "java"/"java.exe" program
that is already running the current invoking code. Quite surely you'd
still have a similar api like Process.exec() wrt the standard channels.
 
A

Andreas Leitgeb

Andreas Leitgeb said:
If you have the source of the subprogram, you could of course
replace all System.exit() invocations by something else, and
furthermore all System.out.println's (and it's siblings) by
your own methods that append the data to some global ArrayList
:)

This one in a nutshell: make a reusable library out of your subprogram.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,431
Messages
2,571,677
Members
48,796
Latest member
Greg L.

Latest Threads

Top