I am investigating a Java issue (using IBM JVM 1.4.2 64-bit) on Red Hat Linux. I am wondering if anyone has seen this error message before and knows if there is a workaround to this problem?
Source:
import sun.misc.Signal;
import sun.misc.SignalHandler;
public class SignalTest extends Thread
{
private static Signal signal = new Signal("INT");
private static ShutdownHandler handler = new ShutdownHandler();
private static class ShutdownHandler implements SignalHandler
{
public void handle(Signal sig)
{
}
}
public static void main(String[] args)
{
try
{
Signal.handle(signal, handler);
}
catch(Throwable e)
{
e.printStackTrace();
}
try { Thread.sleep(5000); } catch(Exception e) { e.printStackTrace(); }
System.exit(0);
}
}
Output:
java.lang.IllegalArgumentException <Signal already used by VM: INT>
java.lang.IllegalArgumentException: Signal already used by VM: INT
at
com.ibm.misc.SignalDispatcher.registerSignal(SignalDispatcher.java:145)
at sun.misc.Signal.handle(Signal.java:199)
at xxx
Additional Information:
I found out something strange. The reason why it fails is because I am running the program inside a shell script as a background process.
i.e. sigtest.sh:
#!/bin/bash
java -cp . SignalTest >> sigtest.log 2>&1 &
If I run the program from the command line, or remove the "&" (i.e. make it a foreground process inside the shell script), it doesn't have a problem... I don't understand why this is the case.
Try starting the JVM with an -Xrs option which is valid on the IBM JVM according to this anyway. That might prevent the conflict.
EDIT: In response to your underlying desire, look at:
Runtime.getRuntime().addShutdownHook(Thread)
You subclass a thread object, and it will start as part of the shutdown (take out that -Xrs for this to work well). Some things (like calling halt on Runtime) can stop that from happening, so you do need to be aware of the possibility that it just won't end up happening.
This is may very well be a JVM implementation specific problem. We are using an undocumented / unsupported API (sun.misc.Signal/SignalHandler
) and therefore no contract on the behavior of the API is guaranteed.
The IBM JVM implementation could do signal-handling-related-things differently from the SUN JVM implementation and thus cause this problem. So that this specific use case works in the SUN JVM but not in the IBM JVM.
But try out the following (I can't try it out myself):
Do all combinations off starting the JVM with one/two/three of those parameters and there possible value combinations.
-Xrs
option specified / not specifiedibm.signalhandling.sigint
set to true
/ false
ibm.signalhandling.rs
set to true
/ false
(The properties where found via google in several error dumps but I can't find any specific documentation on them)
I don't know if the IBM JVM also supports this special flag but you could try adding this too which in SUN JVM seems to be specific for some problems with signal handlers under linux/solaris
-XX:-AllowUserSignalHandlers
Or try using a native signal handler if that is an option for you. Check out the code samples provided:
Although it doesn't relate to your specific problem, an IBM article on JVM signal handling (slightly dated but still mostly correct). With samples for native code signal handlers:
Revelations on Java signal handling and termination
But I guess this may all be to no avail as the IBM JVM implementation could rely on handling SIGINT
itself to function correctly and thus never giving you a chance to handle SIGINT
yourself.
Btw. from the description to the -Xrs
flag I understand that it actually may hinder you to do what you want. It says
When
-Xrs
is used on Sun's JVM, the signal masks for SIGINT, SIGTERM, SIGHUP, and SIGQUIT are not changed by the JVM, and signal handlers for these signals are not installed.
Or it could mean that only the JVM default actions for the signals aren't executed. Or it could depend on the JVM implementation what is really meant.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With