2009-04-28 17 views
6

मैं किसी भी तरह से Thread.interrupt() पर लॉग इन करना चाहता हूं, लॉग इन करने के लिए थ्रेड ने कॉल जारी किया (और इसके वर्तमान स्टैक) के साथ-साथ थ्रेड को बाधित करने के बारे में जानकारी की पहचान करना।जावा * लॉग इन * हर * थ्रेड इंटरप्ट लॉग इन करने का कोई तरीका है?

क्या ऐसा करने का कोई तरीका है? जानकारी के लिए खोज, मैंने देखा कि किसी ने सुरक्षा प्रबंधक को लागू करने की संभावना का संदर्भ दिया है। क्या यह कुछ ऐसा है जो रनटाइम पर किया जा सकता है (उदा।, ऐप्पल या वेब स्टार्ट क्लाइंट में), या क्या आपको ऐसा करने के लिए स्थापित JVM टूल करने की आवश्यकता है?

या ऐसा करने का कोई बेहतर तरीका है?

+0

मैं विभिन्न जटिलताओं और विभिन्न प्रदर्शन हिट के साथ ऐसा करने के कुछ तरीकों के बारे में सोच सकता हूं। क्या यह एक बग खोजने के लिए एक बार की बात है या क्या आप उत्पादन में कुछ चाहते हैं? – Fredrik

+0

यह मुख्य रूप से कुछ है जो मैं एक बार की चीज़ के रूप में चाहता हूं, लेकिन कुछ जो मुझे पता है मैं समय-समय पर उपयोग करना चाहता हूं। यदि यह पर्याप्त दोस्ताना था, तो मैं इसे उत्पादन कोड में छोड़ दूंगा लेकिन आवश्यक होने पर उपयोग किए जाने के लिए रिमोट डीबगिंग (लॉग के माध्यम से) के अतिरिक्त मोड के रूप में अक्षम किया जाएगा। – Eddie

उत्तर

9

एक त्वरित हैक के रूप में, यह एक बहुत आसान करने के लिए की तुलना में मैंने सोचा कि यह होता था। चूंकि यह एक त्वरित हैक है, मैं चीजों को नहीं किया सुनिश्चित की तरह है कि स्टैक ट्रेस काफी गहरी है सरणी, आदि अपसंदर्भन से पहले मैं अपने हस्ताक्षर किए एप्लेट के निर्माता में निम्नलिखित डाला:

log.info("Old security manager = " + System.getSecurityManager()); 
System.setSecurityManager(new SecurityManager() { 
     @Override 
     public void checkAccess(final Thread t) { 
     StackTraceElement[] list = Thread.currentThread().getStackTrace(); 
     StackTraceElement element = list[3]; 
     if (element.getMethodName().equals("interrupt")) { 
      log.info("CheckAccess to interrupt(Thread = " + t.getName() + ") - " 
        + element.getMethodName()); 
      dumpThreadStack(Thread.currentThread()); 
     } 
     super.checkAccess(t); 
     } 
    }); 

और dumpThreadStack विधि इस प्रकार है:

public static void dumpThreadStack(final Thread thread) { 
    StringBuilder builder = new StringBuilder('\n'); 
    try { 
    for (StackTraceElement element : thread.getStackTrace()) { 
     builder.append(element.toString()).append('\n'); 
    } 
    } catch (SecurityException e) { /* ignore */ } 
    log.info(builder.toString()); 
} 

मैं कभी नहीं, ज़ाहिर है, इस उत्पादन कोड में छोड़ सकता है, लेकिन यह मुझे बिल्कुल बताने के लिए जो धागा एक interrupt() कि मैं उम्मीद नहीं थी पैदा कर रहा था पर्याप्त। यही है, इस कोड के साथ, मुझे प्रत्येक कॉल के लिए Thread.interrupt() पर एक स्टैक डंप मिलता है।

+1

ध्यान दें कि जावा के कुछ संस्करणों में सुरक्षा प्रबंधक को चेकप्रमिशन विधियों को ओवरराइड करना चाहिए (सबसे अनुमोदित और सरल विकल्प के लिए, उन्हें बस वापस लौटाएं) या फिर आप 'java.security.AccessControlException: एक्सेस अस्वीकृत' जैसी सुरक्षा त्रुटियों को दबा सकते हैं। – vazor

4

कुछ भी जंगली कोशिश करने से पहले, क्या आपने Java debuggingAPI का उपयोग करने पर विचार किया है? मुझे लगता है कि Thread.interrupt() पर MethodEntryEvents को कैप्चर करना यह करेगा।

ईइक, यह पुराना इंटरफ़ेस है, आपको नए JVM ToolInterface पर भी जांच करनी चाहिए।

+0

मैं जावा डिबगिंग एपीआई के बारे में बेहद जागरूक हूं, लेकिन मुझे यकीन नहीं है कि इसे उस एप्लिकेशन के अंदर से कैसे उपयोग किया जाए जिसका मैं इसका उपयोग करूंगा। – Eddie

+0

मैंने आपको अब कुछ लिंक दिए हैं; संक्षिप्त जवाब यह है कि आप JVM आमंत्रण में ध्वज जोड़ते हैं, और फिर बाहरी रूप से JVM से कनेक्ट कर सकते हैं। –

+0

दुर्भाग्य से, आपके सुझाव मेरी मदद नहीं करेंगे। नए जेवीएम टूल इंटरफेस के लिए जेएनआई की आवश्यकता है और पुराने जावा डीबगिंग एपीआई एप्लेट्स के लिए उपलब्ध नहीं है। हालांकि, यह जानकारी भविष्य में किसी और चीज़ के लिए उपयोगी साबित हो सकती है। पॉइंटर्स के लिए धन्यवाद। – Eddie

2

मैं AspectJ और विधि कॉल को लपेटने के लिए इसकी क्षमताओं को देखता हूं। execution pointcutinterrupt() विधि के आसपास यहां सहायता करनी चाहिए।

ध्यान दें कि चूंकि आप जावा सिस्टम विधि कॉल (आपके आवेदन कोड के विपरीत) को अवरुद्ध करना चाहते हैं, तो ऊपर उपयुक्त नहीं हो सकता है। This thread सुझाव देता है कि यह संभव है, लेकिन ध्यान दें कि उसने बुना rt.jar बनाया है। ThreadInfo वस्तु के साथ

ManagementFactory.getThreadMXBean().getThreadInfo(aThreadID) 

आप लॉग इन कर सकते:

+0

देखें आप जेवीएम पुस्तकालयों में विधियों को भी लपेट सकते हैं? – Eddie

+0

यह एक अच्छा मुद्दा है, और एक जैसा कि मैंने इसे टाइप किया था, उसी पर विचार कर रहा था। विभिन्न बाइट-बुनाई तंत्र हैं, निश्चित रूप से (संकलन-समय/रन-टाइम/कक्षा-भार का समय) ताकि इनमें से कोई काम कर सके। –

0

आप JMX साथ भी आजमा सकते हैं

  • धागे की स्टैक ट्रेस
  • नाम, स्थिति, आदि जैसे सामान्य userful जानकारी
  • आदि
,210

संपादित

उपयोग getAllThreadIds() क्रम में लाइव धागा id की सूची प्राप्त करने के लिए:

long[] ids = ManagementFactory.getThreadMXBean().getAllThreadIds(); 
+0

आपका मतलब क्या है कि इंटरप्ट-कॉल को पकड़ लेंगे? – Fredrik

+0

एक और विधि का उपयोग कर (जेवीएम वाद्ययंत्र, डीबगिंग हुक, एओपी, आदि)? – dfa

1

अन्य लोगों ने कहा के रूप में ... अगर यह एक बार की बात JVMTI शायद है जाने के लिए सबसे कट्टर तरीका। हालांकि, बस एएसएम लाइब्रेरी और इंस्ट्रूमेंटेशन एपीआई का उपयोग करने के लिए एक एजेंट बनाने के लिए मजेदार हो सकता है जो आपके द्वारा Thread.interrupt() कॉल से पहले बनाई गई स्थिर विधि को कॉल करता है (या शायद Thread.interrupt को बदल सकता है () ऐसा करने के लिए विधि, मुझे लगता है कि आप ऐसा कर सकते हैं)।

दोनों सीखने में कुछ समय लगता है लेकिन यह काम करने में काफी मजेदार है और एक बार जब आप इसे पकड़ लेंगे तो आप उन्हें भविष्य में सभी प्रकार की मजेदार चीजों के लिए उपयोग कर सकते हैं :-) मेरे पास वास्तव में कोई नहीं है अच्छे स्निपेट अभी यहां पेस्ट करने के लिए हैं, लेकिन यदि आप एएसएम के लिए चारों ओर गुजरते हैं और शायद एएसएम के कुछ रचनात्मक उपयोग के लिए जेआईपी देखें तो मुझे लगता है कि आपको प्रेरणा मिल जाएगी।

JIP: Java Interactive Profiler

+0

मुझे लगता है कि आप http://asm.ow2.org/ का जिक्र कर रहे हैं? बहुत रचनात्मक लगता है! मेरे पास जांच करने का समय नहीं था, लेकिन ऐसा लगता है कि भविष्य में मुझे अच्छा लगेगा। धन्यवाद। – Eddie

+0

सही, यूआरएल सहित नहीं के लिए खेद है। – Fredrik

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