2009-06-26 8 views
5

मैं जावा समस्या की जांच कर रहा हूं (आईबीएम जेवीएम 1.4.2 64-बिट का उपयोग कर) Red Hat Linux पर। मुझे आश्चर्य है कि किसी ने इस त्रुटि संदेश को पहले देखा है और जानता है कि इस समस्या का कोई समाधान है या नहीं?जावा त्रुटि: java.lang.IllegalArgumentException: सिग्नल पहले से ही वीएम द्वारा उपयोग किया जाता है: 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 की अपेक्षा के साथ समन्वयित है। – Yishai

+0

मैं चाहता हूं कि प्रोग्राम बाधित होने पर कुछ "साफ-सफाई" कोड चलाकर गहराई से बाहर निकलें। –

+0

मुद्दा जेवीएम विशिष्ट था। मैंने जिटर को बक्षीस से सम्मानित किया, क्योंकि उनके जवाब में "जेवीएम कार्यान्वयन विशिष्ट" शामिल था और मेरी समस्या का निदान करने के लिए सबसे अधिक टूल प्रदान किए गए थे। सभी को धन्यवाद। –

उत्तर

3

यह एक जेवीएम कार्यान्वयन विशिष्ट समस्या बहुत अच्छी तरह से हो सकता है। हम एक अनियंत्रित/असमर्थित API (sun.misc.Signal/SignalHandler) का उपयोग कर रहे हैं और इसलिए एपीआई के व्यवहार पर कोई अनुबंध गारंटी नहीं है।

आईबीएम जेवीएम कार्यान्वयन सिंक-हैंडलिंग से संबंधित चीजों को सूर्य जेवीएम कार्यान्वयन से अलग-अलग कर सकता है और इस प्रकार इस समस्या का कारण बनता है। ताकि यह विशिष्ट उपयोग केस सूर्य JVM में काम करता है लेकिन आईबीएम जेवीएम में नहीं।

लेकिन निम्नलिखित (मैं इसे बाहर अपने आप कोशिश नहीं कर सकते हैं) की कोशिश:

एक/दो/उन मापदंडों के तीन और वहाँ संभव मूल्य संयोजनों के साथ JVM शुरू कर बंद सभी संयोजनों करो।

  1. -Xrs विकल्प निर्दिष्ट नहीं/निर्दिष्ट
  2. संपत्ति ibm.signalhandling.sigint सेट true/false
  3. संपत्ति को ibm.signalhandling.rs सेट (true/false

के गुण जहां कई में गूगल के माध्यम से पाया त्रुटि डंप लेकिन मुझे उन पर कोई विशिष्ट दस्तावेज नहीं मिल रहा है)

आईबीएम JVM भी इस विशेष ध्वज का समर्थन करता है, तो मैं नहीं जानता कि, लेकिन आप यह भी है जो सूर्य JVM में

-XX:-AllowUserSignalHandlers 

या कोशिश linux/सोलारिस के तहत संकेत संचालकों के साथ कुछ समस्याओं के लिए विशिष्ट हो रहा है जोड़ने की कोशिश कर सकते यदि यह आपके लिए एक विकल्प है तो मूल सिग्नल हैंडलर का उपयोग करना। प्रदान की कोड नमूने की जाँच करें:

में

  • हालांकि यह अपने विशिष्ट समस्या, JVM पर एक आईबीएम लेख से संबंधित नहीं है सिग्नल हैंडलिंग (थोड़ा दिनांकित लेकिन अभी भी अधिकतर सही)। मूल कोड संकेत संचालकों के लिए नमूने के साथ:

    Revelations on Java signal handling and termination


    लेकिन मुझे लगता है कि यह सब आईबीएम JVM कार्यान्वयन से निपटने SIGINT ही ठीक से कार्य करने और इस प्रकार पर निर्भर कर सकता है के रूप में कोई लाभ नहीं हुआ हो सकता है आप एक कभी नहीं दे रही है SIGINT स्वयं को संभालने का मौका।

    बीटीडब्ल्यू। 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

    अपवाद होता है क्योंकि वीएम में पहले से ही सिग्नल हैंडलर सिगिनट के लिए रखा गया है। इसके बारे में आप क्या कर सकते हैं/उस संदर्भ पर निर्भर करता है जिसमें इस अपवाद को फेंक दिया गया है।

    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

    हां, मेरे पास दो वातावरण हैं। एक 32 बिट लिनक्स है, यह सूर्य जेवीएम का उपयोग करके ठीक काम करता है। एक 64 बिट लिनक्स है, यह इस पर काम नहीं करता है। –

    +0

    मेरा सेटअप सन-जेवीएम (हॉटस्पॉट, 1.6.0_11) का उपयोग कर 64-बिट (2.6.24 ...) है। –

    +0

    मुझे लगता है कि यह प्रोग्रामिंग समस्या कम है और एक जेवीएम मुद्दा है। –

    2

    एक -Xrs विकल्प जो आईबीएम JVM के अनुसार पर मान्य है साथ JVM शुरू करने का प्रयास वैसे भी this। यह संघर्ष को रोक सकता है।

    संपादित करें: आपके मौलिक इच्छा के जवाब में, देखने में:

    Runtime.getRuntime().addShutdownHook(Thread)

    आप एक धागा वस्तु उपवर्ग, और यह बंद (कि -Xrs इस के लिए काम करने के लिए बाहर ले जाना के हिस्से के रूप शुरू कर देंगे कुंआ)। कुछ चीजें (जैसे रनटाइम पर रुकने की तरह) इसे रोकने से रोक सकती है, इसलिए आपको इस संभावना से अवगत होना चाहिए कि यह अभी खत्म नहीं होगा।

    +0

    यही से उत्पादन परिवर्तन: java.lang.IllegalArgumentException <सिग्नल पहले से ही वी एम द्वारा इस्तेमाल किया: INT>: java.lang.IllegalArgumentException निम्नलिखित करने के लिए <सिग्नल वीएम द्वारा प्रतिबंधित: INT> –

    1

    जैसा कि Heinz Kabutz द्वारा लिखा गया है, आप जिस सिग्नल को पकड़ने में सक्षम हैं, उस ऑपरेटिंग सिस्टम पर निर्भर करता है जो आप चल रहे हैं और संभवतः जेवीएम संस्करण। यदि कोई निश्चित ओएस/जेवीएम संयोजन आपको अपना सिग्नल पंजीकृत नहीं करने देता है तो आप भाग्य से बाहर हैं। शायद ओएस/वीएम सेटिंग्स के साथ tweaking मदद कर सकता है।

    आपकी टिप्पणी के अनुसार, shutdown hook जोड़कर यिशै द्वारा प्रस्तावित चाल चलाना चाहिए।

    0

    मुझे आईबीएम के बजाय एक अलग जेवीएम कार्यान्वयन (एसयूएसई) का उपयोग कर काम करने के लिए मिला। अनियंत्रित सुविधाओं से निपटने पर, ऐसा प्रतीत होता है कि JVMs व्यवहार में बहुत संगत नहीं हैं।

    0

    मुझे भी एक ही समस्या है। मैं एक जावा स्क्रिप्ट से जावा प्रोग्राम चलाता हूं। अगर मैं खाते के साथ स्क्रिप्ट जो, csh प्रोफ़ाइल यानी है/आदि में/पासवर्ड फ़ाइल

    userx चलाएँ: *: 7260: 20 ::/घर/userx:/usr/bin/csh

    स्क्रिप्ट सफलतापूर्वक चलाएगी। लेकिन अगर मैं इसे खाता के साथ चलाता हूं जो sh प्रोफाइल के अलावा है, तो यह वही त्रुटि दे रहा है।

    तो, समाधान है कि आपकी यूनिक्स उपयोगकर्ता प्रोफ़ाइल csh में बदल जाए।

    0

    मुझे लिनक्स पर आईबीएम जेवीएम (64 बिट) के साथ भी इस समस्या का सामना करना पड़ा है। यह पता चला कि JVM प्रक्रिया के सिग्नल मास्क से संवेदनशील है जो इसे कॉल करता है।

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

    ध्यान दें कि SIGINT (मान 2) के लिए बिट SigIgn में सेट है। इस मुखौटा के साथ आईबीएम जेवीएम शुरू करते समय, यह SIGINT के लिए एक हैंडलर स्थापित करने से इंकार कर देता है। मैं इस समस्या के चारों ओर एक अजगर आवरण कि डिफ़ॉल्ट करने के लिए SIGINT हैंडलर रीसेट करता है के माध्यम से JVM के लॉन्च के साथ काम किया:

    #!/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) 
    

    आवरण को पहला तर्क java आदेश है, तो JVM के लिए बहस का पालन करें।

    संबंधित मुद्दे