Reputation: 1
I have a perl CGI that calls a java application which in turn checks a Mysql database. If I search for an entry that does not exist, the java application displays an exception handler message on the server (requires an X display window). The exception is straight forward and understandable, however must be clicked to close it, at which point the perl CGI can continue. Customers of course cannot (and should not) see the exception message.
My question is.. how can I prevent the exception message from displaying on the server window and preventing the CGI from continuing? Is there a way to close the message from perl? I have control over the perl script, but not the java application I call.
$ENV{'DISPLAY'} = 'myserver:0.0';
$testline = system("java -Dby.product=true -jar javaApp.jar $version status>mytest.txt") >> 8;
if $version doesn't exist, I get the exception. I pipe the results to a file for later file handling in perl
Thanks. Rocky.
=====================
Thanks. I added this...
$ENV{'DISPLAY'} = 'server:0.0';
use IPC::Open2;
use POSIX ":sys_wait_h";
$pid = open2(\*CHLD_OUT, \*CHLD_IN, "java -Dby.product=true -jar javaApp.jar $version status>mytest.txt 2>/tmp/java_error.$$");
sleep(5);
kill('TERM', $pid);
If I use a known value in the database, it works fine, as before. If I search a nonexistent value, the java message still pops up. Without the sleep line, the java message does NOT popup. In other words it looks like the pid is killed, but so quickly that the result does not get fed into mytest.txt. I thought the sleep function would give some time for the java app to work and then the kill would remove the popup message. But this does not happen.
It seems likely I will have to request changes to the java application so that it does not display a message on screen in the server.
Upvotes: 0
Views: 387
Reputation: 7610
Corrected and extended
Try
system("java -Dby.product=true -jar javaApp.jar $version status 2>/dev/null >mytest.txt");
It redirects the stderr
of java
to nowhere. Or redirect to a file (like 2>/tmp/java_error.$$
) to save it debugging the error.
If it is on windows use 2>nul
.
Or use IPC::Open3 and process both input file handles as You like.
More detailed. I created a simple a.java
code which writes to stdout, stderr and throws an exception if an arg is defined:
public class a {
public static void main(String[] args) {
System.out.println("STDOUT");
System.err.println("STDERR");
if (args.length > 0) { int i = 1/0; }
}
};
I compiled and run it (don't care about the gcj warning):
$ gcj -C a.java
$ gij -cp . a
STDOUT
STDERR
$ gij -cp . a x
STDOUT
STDERR
Exception in thread "main" java.lang.ArithmeticException: / by zero
at a.main(a.java:5)
$ gij -cp . a >/dev/null
STDERR
$ gij -cp . a x 2>/dev/null
STDOUT
So the stack dump is written to the stderr as expected, so it can be redirected.
$ perl -e 'system("gij -cp . a x 2>/dev/null")'
STDOUT
The example program with IPC::Open3:
#!/usr/bin/perl
use strict;
use warnings;
use IPC::Open3 'open3';
use Symbol 'gensym';
my ($fcin, $fcout, $fcerr);
$fcerr = gensym;
my $pid = open3 $fcin, $fcout, $fcerr, "gij -cp . a x";
my @out = <$fcout>;
my @err = <$fcerr>;
my $err = waitpid $pid, 0;
print "Exit:", ($err >> 8), "\n";
print "OUT: @out\n";
print "ERR: @err\n";
Output:
Exit:72
OUT: STDOUT
ERR: STDERR
Exception in thread "main" java.lang.ArithmeticException: / by zero
at a.main(a.java:5)
Even the man page of IPC::Open3 suggests to use the IPC::Run package. I tried, but it is not the part of the normal distribution. So You can install it from CPAN if You wish.
Upvotes: 1