Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java error: java.lang.IllegalArgumentException: Signal already used by VM: INT

Tags:

java

jvm

signals

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.

like image 881
Jin Kim Avatar asked Jun 26 '09 17:06

Jin Kim


2 Answers

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.

like image 29
Yishai Avatar answered Oct 05 '22 17:10

Yishai


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.

  1. the -Xrs option specified / not specified
  2. the property ibm.signalhandling.sigint set to true / false
  3. the property 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:

  • in the link below
  • Catching SIGINT in a Java application under UNIX
  • Check signal handling, native signal chainging
  • JDK 6 HotSpot VM - Signal Handling on Solaris OS and Linux

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.

like image 148
jitter Avatar answered Oct 05 '22 17:10

jitter