Java-Fehlermeldung: java.lang.IllegalArgumentException: Signal bereits von VM: INT
Ich untersuche, wie sich ein Java-Problem (mit der IBM JVM 1.4.2 64-bit) auf Red Hat Linux.
Ich Frage mich, ob jemand gesehen hat, diese Fehlermeldung vor, und weiß, wenn es einen workaround zu diesem problem?
Quelle:
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);
}
}
Ausgabe:
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
Zusätzliche Informationen:
Fand ich etwas seltsam.
Der Grund warum es scheitert ist, weil bei mir läuft das Programm in einem shell-Skript als Hintergrundprozess.
d.h.
sigtest.sh:
#!/bin/bash
java -cp . SignalTest >> sigtest.log 2>&1 &
Wenn ich das Programm von der Befehlszeile aus oder entfernen Sie die "&" (D. H. ein Vordergrund-Prozess innerhalb der shell-Skript), ist es nicht ein problem haben...
Ich verstehe nicht, warum dies der Fall ist.
- Jin, da dein Kommentar auf meine Antwort, die JVM ist nicht ausmalen, registrieren Sie einen Haken an dieses Ereignis. Können Sie beschreiben, mehr über das, was Sie versuchen zu erreichen? Vielleicht gibt es einen Weg, es zu tun, das ist mehr im Einklang mit der JVM Erwartung.
- Ich möchten, dass das Programm ordnungsgemäß beendet werden, indem Sie einige "clean-up" - code, wenn es unterbrochen.
- Das Problem war JVM-spezifisch. Ich erhielt das Kopfgeld von Jitter, da seine Antwort enthalten "JVM-Implementierung spezifische" gestellt und die meisten tools für die Diagnose von mein problem. Vielen Dank an alle.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Kann es sehr gut sein, eine JVM-Implementierung spezifische problem. Wir sind mit einer undokumentierten /nicht unterstützte API (
sun.misc.Signal/SignalHandler
) und daher kein Vertrag über das Verhalten der API ist garantiert.IBM JVM-Implementierung könnte do-signal-handling-Verwandte-Dinge, die anders als die SUN JVM-Implementierung und damit dieses problem verursachen. So dass in diesem bestimmten Fall funktioniert, in dem SUN JVM, aber nicht in der IBM JVM.
Aber versuchen, aus den folgenden (kann ich nicht versuchen Sie es selber):
Tun alle Kombinationen aus startet die JVM mit einer/zwei/drei von diesen Parametern und die dort möglichen Wert-Kombinationen.
-Xrs
option angegeben /nicht angegebenibm.signalhandling.sigint
eingestellttrue
/false
ibm.signalhandling.rs
eingestellttrue
/false
(Eigenschaften, die sich über google in mehreren Fehler-dumps, aber ich kann nicht finden, alle spezifischen Unterlagen auf Sie)
Ich weiß nicht, ob die IBM-JVM unterstützt auch diese Besondere fahne, aber Sie könnten versuchen, hinzufügen, dass diese zu dem in der SUN-JVM scheint spezifisch für einige Probleme mit der signal-Handler unter linux/solaris
Oder versuchen Sie es mit einem nativen signal-handler, wenn das ist eine option für Sie. Überprüfen Sie heraus die code-Beispiele:
Obwohl es nicht in Beziehung zu Ihrem spezifischen problem, ein IBM-Artikel über JVM-signal-handling (leicht veraltet, aber immer noch meist die richtige). Mit Proben für native-code-signal-Handler:
Offenbarungen über Java-Signalverarbeitung und Kündigung
Aber ich denke, das können alle ohne Erfolg, da die IBM JVM-Implementierung könnte verlassen sich auf die Handhabung
SIGINT
sich korrekt zu funktionieren und so nie geben Ihnen eine chance zu handhabenSIGINT
selbst.Btw. aus der Beschreibung zum
-Xrs
- flag ich verstehe, dass es tatsächlich daran hindern können, Sie zu tun, was Sie wollen. Es sagtSein, oder es könnte bedeuten, dass nur die Standard-JVM-Aktionen für die Signale werden nicht ausgeführt. Oder es könnte abhängen auf die JVM-Implementierung, was wirklich gemeint ist.
Starten der JVM mit -Xrs-option, die ist gültig auf die IBM JVM nach diese sowieso. Das könnte verhindern, dass der Konflikt.
EDIT: In Reaktion auf die Ihr zugrunde liegende Sehnsucht, schau an:
- Laufzeit.getRuntime().addShutdownHook(Thread)
Sie eine Unterklasse ein thread-Objekt, und es wird als Teil des shutdown (nehmen Sie hin, dass-Xrs für diese gut zu funktionieren). Einige Dinge (wie der Aufruf halt auf Laufzeit), können verhindern, dass aus geschieht, so dass Sie brauchen, um bewusst sein, der Möglichkeit, dass Sie einfach nicht am Ende passiert.
Geschrieben von Heinz Kabutz, die Signale, die Sie aufnehmen können, hängt von der Betriebssystem Sie laufen, und wahrscheinlich die JVM-version. Wenn eine bestimmte Bs/jvm-Kombination lässt Sie nicht registrieren Sie Ihr signal dann sind Sie kein Glück. Vielleicht tweaking mit os/vm-Einstellungen helfen könnte.
Laut Ihres Kommentars, das hinzufügen einer shutdown-hook wie vorgeschlagen von Yishai sollte den trick tun.
Ausnahme tritt auf, da die VM bereits einen signal-handler für SIGINT. Was kann man/sollte man dagegen tun, hängt von dem Kontext, in dem diese Ausnahme wird geworfen.
Ich habe versucht den gleichen code und es funktioniert für mich. Also ich denke es könnte etwas Unterschied in der Einrichtung.
Nach dem hinzufügen
den Griff Meldung kann ich die Klasse so:
Habe ich diese zu arbeiten, indem Sie eine andere JVM-Implementierung (SuSE) anstelle von IBM.
Beim Umgang mit undokumentierten features, es scheint, dass die JVM sind nicht sehr konsistent Verhalten.
Ich habe auch das gleiche problem. Ich starte das java-Programm von einem ksh-Skript.
Wenn ich das Skript mit dem account auf dem die csh-Profil
d.h., in der Datei /etc/passwd
userx:*:7260:20::/home/userx:/usr/bin/csh
Das Skript ausgeführt wird, erfolgreich. Aber wenn ich es mit dem Konto, das andere als sh Profil, es gibt die gleichen Fehler.
So, die Lösung ist, um Ihre unix-Benutzer-Profil geändert csh.
Habe ich auch auf dieses problem mit der IBM JVM (64 bit) unter Linux. Es stellte sich heraus, dass die JVM ist empfindlich auf das signal-Maske des Prozesses, der es nennt.
Beachten Sie, dass das bit für SIGINT (Wert 2) eingestellt ist, in SigIgn. Beim starten der IBM JVM mit dieser Maske, Sie weigert sich zu installieren, einen handler für SIGINT. Ich arbeitete, um das problem durch starten der JVM durch ein Python-wrapper, der setzt die SIGINT-handler die default:
Das erste argument der wrapper ist der
java
Befehl, dann Folgen die Argumente für die JVM.