2009-06-03 10 views
30

क्या यह निर्धारित करने का कोई तरीका है कि कौन से वर्ग लोड किए गए हैं, जिसमें से जार रनटाइम पर हैं?कैसे पता लगाएं कि कौन से वर्ग लोड किए गए हैं, जिनमें से जेएआरएस?

मुझे यकीन है कि हम सब पहले जार नरक में हैं। मैंने इस समस्या को कई समस्या निवारण ClassNotFoundException एस और NoClassDefFoundError एस परियोजनाओं पर चलाया है। मैं जार में एक वर्ग के सभी उदाहरणों को ढूंढने और कोड पर उन्मूलन की प्रक्रिया का उपयोग करने से बचाना चाहता हूं जिससे सीएनएफई अपराधी को ढूंढ सके।

क्या कोई प्रोफाइलिंग या प्रबंधन उपकरण आपको इस तरह की जानकारी देगा?

यह समस्या पूरी तरह से परेशान है क्योंकि कक्षा में लोड होने के समय हमारे पास यह जानकारी होनी चाहिए। इसे पाने का तरीका बनना है, या इसे रिकॉर्ड करना है और इसे ढूंढना है, फिर भी मुझे कुछ भी नहीं पता है जो यह करेगा, है ना?

मुझे पता है कि ओएसजीआई और संस्करण वाले बंडल/मॉड्यूल का उद्देश्य यह एक गैर मुद्दा बनाना है ... लेकिन ऐसा लगता है कि यह जल्द ही कभी नहीं जा रहा है। :)

नोट: मैंने पाया कि यह question संस्करण वाले जार से लोड कक्षाओं से संबंधित मेरे प्रश्न का सबसेट है।

अद्यतन: कुछ हद तक संबंधित, यह पोस्ट जार के भीतर कक्षा (या तो वर्तमान निर्देशिका के तहत) या आपके एम 2 डीजीपीओ में एक कक्षा की खोज करने की रणनीति बताती है। JarScan, scan all JAR files in all subfolders for specific class

अद्यतन 2: इसके अलावा कुछ हद तक संबंधित, JBoss Tattletale

+0

जेसन डे यह सही है, यह मूल रूप से एक सवाल का डुप्लिकेट मैं नहीं तो बहुत पहले से पूछा है देख सकते हैं। http://stackoverflow.com/questions/779650/where-on-the-file-system-was-my-java-class-loaded- से – shsteimer

उत्तर

56

java आदेश को -verbose:class स्विच पासिंग प्रत्येक वर्ग लोड प्रिंट होगा और कहाँ से लोड किया गया था।

Joops समय से पहले गायब कक्षाओं को खोजने के लिए भी एक अच्छा टूल है।

+2

मैंने अभी कोशिश की है -verbose: कक्षा विकल्प। कमाल है!!! वास्तव में वास्तव में उपयोगी – OscarRyz

+0

नाइस - जोओप्स अच्छा लग रहा है - क्या आपको पता है कि क्लास.forनाम के माध्यम से संदर्भित कक्षा का पालन करने के लिए पर्याप्त स्मार्ट है? – cwash

+0

मुझे आश्चर्य होगा अगर यह Class.forName संदर्भों का पालन कर सकता है, लेकिन मुझे निश्चित रूप से पता नहीं है। जोप्स में 'कौन सा' कमांड है, इसलिए आप इसे नाम से कक्षाओं के लिए मैन्युअल रूप से जांचने के लिए उपयोग कर सकते हैं। –

14

कोड से आप कॉल कर सकते हैं:

myObject.getClass().getProtectionDomain().getCodeSource() 

(ध्यान दें, getProtectionDomain दुर्भाग्य null (खराब डिजाइन वापस आ सकते हैं), तो "उचित कोड" उस के लिए जाँच करेगा।)

+0

यह एक सीएनएफई या एनसीडीएफई के साथ मदद नहीं करेगा; आपने यह कब किया है? – cwash

+0

संभवतः यदि आपको क्लास नॉटफाउंड अपवाद प्राप्त होता है तो संभवतः आप पहले से ही जानते हैं कि कक्षा किसी भी जार में नहीं है। (मान लीजिए कि आप क्लास लोडर के साथ नहीं खेल रहे हैं।) यदि गायब सुपरक्लास की तरह क्लास लोडिंग के दौरान अन्य त्रुटियां हैं तो समस्याएं हो सकती हैं। –

+0

@ टॉमहॉटिन-टाइललाइन आपको 'क्लास नॉटफाउंड अपवाद' प्राप्त हो सकती है यदि कहा गया वर्ग का एक स्थिर प्रारंभकर्ता अपवाद फेंकता है। फिर आपके पास जार फ़ाइल में कक्षा है, लेकिन क्लासलोडर इसे लोड नहीं कर सकता है। – hidralisk

4

के लिए एक MBean नहीं है ऊपर जेसन डे द्वारा वर्णित जेवीएम ध्वज।

यदि आप जेबॉस का उपयोग कर रहे हैं, तो आप जेएमएक्स का उपयोग करके मांग पर इसे जोड़ सकते हैं, अगर आप मूल कॉन्फ़िगरेशन में मूल जेएमएक्स एमबीएएन सर्वर जोड़ते हैं। निम्नलिखित डी के जोड़ें:

-Dcom.sun.management.jmxremote.port=3333 
-Dcom.sun.management.jmxremote.authenticate=false 
-Dcom.sun.management.jmxremote.ssl=false 
-Djboss.platform.mbeanserver 
-Djavax.management.builder.initial=org.jboss.system.server.jmx.MBeanServerBuilderImpl 
-DJBOSS_CLASSPATH="../lib/jboss-system-jmx.jar" 

और फिर आप java.lang के तहत इस सेटिंग को देख सकते हैं: Classloading MBean और यह मक्खी पर/बंद कटौती कर सकते हैं। यह सहायक है अगर आप केवल कोड के एक निश्चित टुकड़े को निष्पादित करते समय इसे चालू करना चाहते हैं।

एक एमबीन भी है जो आपको पूरी तरह से योग्य क्लासनाम में प्रवेश करने की अनुमति देगा और देखेंगे कि यह कक्षा पदानुक्रम में कहां से लोड किया गया था। एमबीन को लोडर रिपोजिटरी कहा जाता है और आप FQCN में गुजरने वाले displayClassInfo() ऑपरेशन को आमंत्रित करना चाहते हैं।

0

WebSphere में (था) आप एक विशेषता "क्लास लोडर व्यूअर"

कहा जाता है का उपयोग कर सकते सर्वर> सर्वर प्रकार> WebSphere अनुप्रयोग सर्वर> server_name> कक्षा लोडर दर्शक सेवा पर क्लिक करके प्रथम श्रेणी लोडर दर्शक सक्षम, सक्षम सेवा और सर्वर को पुनरारंभ करें।

फिर आप समस्या निवारण> कक्षा लोडर व्यूअर पर जा सकते हैं और अपनी कक्षा या पैकेज नाम खोज सकते हैं।

https://www-01.ibm.com/support/knowledgecenter/SSAW57_8.5.5/com.ibm.websphere.nd.doc/ae/ttrb_classload_viewer.html?lang=en

0

आप आसानी से आप की तरह की प्रक्रिया में किसी भी भरी हुई वर्ग के लिए पैकेज की जानकारी तक पहुँचने के लिए JMX आपरेशन निर्यात कर सकते हैं:

public static final class Jmx { 

    @JmxExport 
    public static Reflections.PackageInfo getPackageInfo(@JmxExport("className") final String className) { 
     return Reflections.getPackageInfo(className); 
    } 
    } 

और यहाँ निर्यात और यह आह्वान करने के लिए एक सरल इकाई परीक्षण है:

@Test 
    public void testClassLocator() throws IOException, InstanceNotFoundException, MBeanException, ReflectionException { 
    Registry.export(Jmx.class); 
    Reflections.PackageInfo info = (Reflections.PackageInfo) Client.callOperation(
      "service:jmx:rmi:///jndi/rmi://:9999/jmxrmi", 
      Jmx.class.getPackage().getName(), 
      Jmx.class.getSimpleName(), "getPackageInfo", Registry.class.getName()); 
    System.out.println(info); 
    Assert.assertNotNull(info); 
    } 
इस

सब से spf4j (http://www.spf4j.org)

कुछ छोटे उपयोगिताओं लाइब्रेरी का उपयोग आधारित है

आप इस कोड at और परीक्षण at

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