Rocky
Rocky

Reputation: 1

Perl calls java - How do I prevent an exception display?

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

Answers (1)

TrueY
TrueY

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

Related Questions