2009-06-26 8 views
5

Red Hat LinuxでJavaの問題(IBM JVM 1.4.2 64ビットを使用)を調べています。 誰もがこのエラーメッセージを以前に見たことがあり、この問題の回避策があるかどうか知っていますか?Javaエラー:java.lang.IllegalArgumentException:既にVMで使用されているシグナル:INT

出典:

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); 
    } 
} 

出力:

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 

追加情報:

私は奇妙な何かを見つけました。 それが失敗する理由は、バックグラウンドプロセスとしてシェルスクリプト内でプログラムを実行しているからです。

sigtest.shすなわち:私は、コマンドラインからプログラムを実行するか、または「&」(すなわち、それシェルスクリプト内のフォアグラウンド・プロセス作りを)削除した場合

#!/bin/bash 
java -cp . SignalTest >> sigtest.log 2>&1 & 

、そうでありません問題があります... これがなぜこのようなのか分かりません。

+0

ジン、私の答えにあなたのコメントを与え、JVMはこのイベントにフックを登録させていません。あなたが達成しようとしていることについてもっと詳しく記述できますか?たぶん、JVMの期待とより多く同期する方法があります。 – Yishai

+0

中断された場合、コードをクリーンアップして正常に終了するようにしたい。 –

+0

問題はJVM固有の問題でした。 私はJitterに賞金を授与しました。回答には「JVM実装固有のもの」が含まれていて、私の問題を診断するためのツールがほとんどでした。 ありがとうございます。 –

答えて

3

これは、JVM実装固有の問題である可能性があります。ドキュメント化されていない/サポートされていないAPI(sun.misc.Signal/SignalHandler)を使用しているため、APIの動作に関する契約は保証されていません。

IBM JVM実装では、SUN JVM実装とは異なるシグナル処理関連の問題が発生し、この問題が発生する可能性があります。この特定のユースケースは、SUN JVMでは動作しますが、IBM JVMでは動作しません。

しかし、(私は自分自身をそれを試してみることはできません)次のことを試してみる:

は、これらのパラメータの1/2/3、そこに可能な値の組み合わせでJVMを起動オフすべての組み合わせを実行してください。

  1. -Xrsオプション指定しない/指定
  2. ibm.signalhandling.sigintセット/ false
  3. true
  4. プロパティへibm.signalhandling.rsセットいくつかは、Googleを介して見出さ特性(true/false

にエラーダンプがありますが、特定のドキュメントが見つかりません)

IBM JVMも、この特別なフラグをサポートしている場合、私は知りませんが、あなたは、これはあまりにもSUN JVMでこれは、Linux/Solarisではシグナルハンドラを持ついくつかの問題

​​

か試すための具体的のようです追加してみてください可能性がありそれがオプションの場合は、ネイティブシグナルハンドラを使用してください。

で、それはあなたの特定の問題、JVM上のIBMの記事とは関係ありませんが:提供されたコードサンプルをチェックシグナル処理(わずかに日付があるが、依然としてほとんど正しい)。ネイティブコードシグナルハンドラのためのサンプルで:

Revelations on Java signal handling and termination


しかし、私は、これはすべてのため、正しく機能するためにSIGINT自体の取り扱いとに依存している可能性がありIBM JVMの実装として無駄になることが推測決してあなた与えませんあなた自身SIGINTを処理するチャンス。

Btw。 description to the -Xrs flagから、私は実際にあなたが望むことをするのを妨げる可能性があることを理解します。それは

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.

それとも信号のための唯一のJVMのデフォルトのアクションが実行されていないことを意味するかもしれないと言います。あるいは、実際に何が意味されているかは、JVM実装に依存する可能性があります。

+0

問題は、JVMが特異的でした。 私が望む動作を得るために別のJVMをインストールする必要がありました。 –

0

VMにSIGINT用のシグナルハンドラがすでに用意されているため、例外が発生します。これについては、この例外がスローされるコンテキストによって異なります。

0

私は同じコードを試してみました。だから私はセットアップにいくつかの違いがあるかもしれないと思う。

ハンドルメッセージに

System.out.println("Hello"); 

を追加した後、私はそのようなクラスを実行することができます:

[email protected]:/tmp/so$ java SignalTest & sleep 1s && kill -2 $! 
[1] 20467 
[email protected]:/tmp/so$ Hello 
[email protected]:/tmp/so$ 
[email protected]:/tmp/so$ java SignalTest 
[1]+ Done    java SignalTest 
+0

はい、私は2つの環境を持っています。 1つは32ビットLinuxで、Sun JVMを使用すると問題なく動作します。 1つは64ビットLinuxですが、このLinuxでは動作しません。 –

+0

私の設定は、Sun JVM(HotSpot、1.6.0_11)を使用して64ビット(2.6.24 ...)です。 –

+0

私はこれがプログラミング上の問題ではなく、より多くのJVMの問題であると感じ始めています。 java.lang.IllegalArgumentExceptionが次へ : java.lang.IllegalArgumentExceptionがからの出力を変化さ –

2

IBM JVMはに従って上で有効である-Xrsオプションを指定してJVMを起動してみてくださいとにかくthis。それは紛争を防ぐかもしれない。

EDIT:(仕事に、このためにその-Xrsを取るあなたがスレッドオブジェクトをサブクラス化し、それがシャットダウンの一環として開始します

​​

:あなたの基本的な欲求に応えて、見てよく)。ランタイムで停止を呼び出すなど、いくつかのことが起きるのを止めることができるので、起こりそうにない可能性を認識する必要があります。

+0

1

Heinz Kabutzで書かれているように、実行可能なシグナルは、実行しているオペレーティングシステムやJVMのバージョンによって異なります。特定のos/jvmの組み合わせで信号を登録できない場合は、運が悪いです。おそらくos/vmの設定を調整すると助けになるかもしれません。

あなたのコメントによると、Yishaiが提案したようにshutdown hookを追加することは、このトリックを行うべきです。

0

IBMではなく、別のJVM実装(SuSE)を使用してこれを動作させました。 文書化されていない機能を扱う場合、JVMの動作があまり一貫していないようです。

0

私も同じ問題があります。私はkshスクリプトからjavaプログラムを実行します。 私はcshのプロファイルを持つアカウントを使用して、スクリプト すなわち、/ etc/passwdファイル内

USERX実行する場合:*:7260:20 :: /ホーム/ USERXします。/ usr/bin/cshの

スクリプトは正常に実行されます。しかし、私がshのプロファイル以外のアカウントで実行すると、同じエラーが出ています。

解決策は、あなたのUNIXユーザプロファイルをcshに変更することです。

0

Linux上のIBM JVM(64ビット)でもこの問題が発生しました。 JVMは、それを呼び出すプロセスのシグナルマスクに敏感であることが判明しました。

> grep Sig /proc/self/status 
SigQ: 1/1030663 
SigPnd: 0000000000000000 
SigBlk: 0000000000000000 
SigIgn: 0000000001001006 
SigCgt: 0000000000000000 

SIGINT(値2)のビットがSigIgnに設定されていることに注意してください。このマスクを使用してIBM JVMを起動すると、SIGINT用のハンドラーのインストールを拒否します。ラッパーへの最初の引数がjavaコマンドです

#!/usr/bin/env python 

import os 
import signal 
import sys 

signal.signal(signal.SIGINT, signal.SIG_DFL) 

args = sys.argv[1:] 
os.execv(args[0], args) 

、その後、JVMの引数に従ってください:私はデフォルトにSIGINTハンドラをリセットPythonラッパーを通じてJVMを起動することで問題を回避働きました。

関連する問題