Operating System - OpenVMS
cancel
Showing results for 
Search instead for 
Did you mean: 

Java Process.destroy() of DCL script not killing process

 
Sebastian Bazley
Regular Advisor

Java Process.destroy() of DCL script not killing process

The following code:

Process p = Runtime.getRuntime().exec("cmd");
p.destroy();
p.waitFor();

works fine if the "cmd" is an executable file.
However, if the "cmd" is a DCL script, then the destroy() method does not seem to work - the script just carries on as if the destroy() had not been called.

Is there a (Java) solution to this?
9 REPLIES
Hein van den Heuvel
Honored Contributor

Re: Java Process.destroy() of DCL script not killing process

I believe Java (used to) uses SYS$FORCEX to run down an image, not SYS$DELPRC to kill the process.

See for example an old c.o.v entry by Kerry Main:

http://unix.derkeiler.com/Newsgroups/comp.os.vms/2003-09/2210.html

The exact Java/JVM/OpenVMS version used may well be critical to understand what is happening. What versions are used?

google: openvms destroy forcex java

fwiw,

Hein.
John Gillings
Honored Contributor

Re: Java Process.destroy() of DCL script not killing process

Sebastian,

This should be easy to check. Build an image that sleeps for a short period then returns status 1. Write a procedure:

$ loop: RUN sleeper
$ SHOW SYM $STATUS
$ GOTO loop

and test your destroy script. A $FORCEX from another process should change the value of $STATUS returned.

You may also want to experiment with different ON settings. Perhaps try "ON WARNING THEN EXIT". However, the behaviour is likely to depend on exactly what your procedure is doing at the time. If it's not running a user mode image, the $FORCEX might be lost.

Perhaps there's a Process.kill (or similar) which uses $DELPRC instead of $FORCEX?
A crucible of informative mistakes
Sebastian Bazley
Regular Advisor

Re: Java Process.destroy() of DCL script not killing process

The Java version I'm using is:

java version "1.4.2"
Java(TM) 2 Runtime Environment, Standard Edition
Java HotSpot(TM) Server VM (build 1.4.2-2 11/03/2005-08:43 IA64, mixed mode)

I've also tried:

java version "1.5.0"
Java(TM) 2 Runtime Environment, Standard Edition
Classic VM (build 1.5.0-3, 03/01/2007-14:39, native threads, jit)
Sebastian Bazley
Regular Advisor

Re: Java Process.destroy() of DCL script not killing process

Oops, forgot VMS versions:

Java 1.4.2 is running on:
an HP rx2600 (1.40GHz/1.5MB) running OpenVMS V8.3

Java 1.5 is running on:
a DEC 3000 Model 400 running OpenVMS V7.3-2
(actually it's Personal Alpha ;-)
Sebastian Bazley
Regular Advisor

Re: Java Process.destroy() of DCL script not killing process

Further to Hein's c.o.v. reference:

I've tried replacing the WAIT command in the DCL test script with a C program that does a sleep - and destroy() works fine if the C program is running when the destroy() is issued. Not yet tried it between program invocations. This was on 1.4.2.

The behaviour of destroy() is very odd ;-)
John Gillings
Honored Contributor

Re: Java Process.destroy() of DCL script not killing process

Sebastian,

>The behaviour of destroy() is very odd ;-)

Yes and no. It makes perfect sense when you understand the underlying mechanisms. The difference between $FORCEX and $DELPRC, and the operating modes of processes.

$DELPRC is potentially dangerous because it doesn't give the process an opportunity to clean up. $FORCEX is preferable because the process exit handlers can run. BUT if the exit handlers don't terminate, or the process is running in an inner mode, it has no effect.

The "usual" way of implementing a soft process kill is to issue a $FORCEX, wait a short while, and if the process is still alive issue a $DELPRC. I guess whoever implemented destroy chose not to do it that way.

A big hammer which will get around your problem would be to write a program which accepts a command as a parameter then executes it as a "system()" command (ie: a subprocess). That way the your process "p" is always running user mode image. It will have subprocess executing your DCL script. The parent is therefore killable with destroy(), and it takes the child with it.

It costs you an extra process creation and the resources associated with an additional process but will reliably do what you want.

(Hext's rule - one further level of indirection solves all problems ;-)
A crucible of informative mistakes
Sebastian Bazley
Regular Advisor

Re: Java Process.destroy() of DCL script not killing process

OK. Further experiments show that the DCL script only exits if the destroy() is received by an external program AND the script does not use SET NOON.

However, the Javadoc for Process.destroy() (Sun 1.4) says:

"Kills the subprocess. The subprocess represented by this Process object is forcibly terminated."

Seems to me that the VMS implementation does not obey the Javadoc and is therefore faulty...
John Gillings
Honored Contributor

Re: Java Process.destroy() of DCL script not killing process

>Seems to me that the VMS implementation
>does not obey the Javadoc and is therefore
>faulty...

Sebastian,

I agree! Please make a formal report, with a complete example (write a self contained command procedure which generates all the necessary files and executes a failing case).

Sometimes problems reported in this forum make their way into engineering, but more often than not they don't. In these days of "management by metrics", engineers are evaluated by how many beans the counters can see. If the report doesn't come in by the "right" door, it's invisible. ITRC points don't translate into anything HP management care about.
A crucible of informative mistakes
Sebastian Bazley
Regular Advisor

Re: Java Process.destroy() of DCL script not killing process

I'd be happy to create a test case.

However, where should I report it?

I'm not working for a company with a support contract ...