2012-12-24 14 views
11

मैं सरल जावा प्रोफाइलर बनाने और इसके लिए क्लासलोडर का उपयोग करने की कोशिश कर रहा हूं।आरएमआई आमंत्रण के साथ क्लासलोडर

import java.rmi.RemoteException; 
import java.rmi.registry.LocateRegistry; 
import java.rmi.registry.Registry; 

public class CustomClassLoader extends ClassLoader { 
    private Notifier notifier; 

    public CustomClassLoader() { 
     super(); 
    } 

    public CustomClassLoader(ClassLoader parent) { 
     super(parent); 
    } 

    private void initNotifier() { 
     if (notifier != null) return; 
     try { 
      System.out.println("2"); 
      Registry registry = LocateRegistry.getRegistry(Const.registryPort); 
      System.out.println("3"); 
      notifier = (Notifier) registry.lookup(Const.stubName); 
      System.out.println("4"); 
     } catch (Exception e) { 
      e.printStackTrace(); 
      System.exit(1); 
     } 
    } 

    @Override 
    protected synchronized Class<?> loadClass(String name, boolean resolve) 
            throws ClassNotFoundException { 
     System.out.println("0"); 
     Class clazz = super.loadClass(name, resolve); 
     System.out.println("1"); 
     initNotifier(); 
     System.out.println("5"); 
     try { 
      notifier.classLoaded(name); 
      System.out.println("6"); 
     } catch (RemoteException e) { 
      e.printStackTrace(); 
      System.exit(1); 
     } 
     return clazz; 
    } 
} 

जब मैं इस वर्ग लोडर मैं इस उत्पादन प्राप्त उपयोग करने का प्रयास किया है (मैं 1.6_37 और 1.7_10 JKD उपयोग करने के लिए कोशिश की है):

यह classloader की मेरी कार्यान्वयन है

C:\Users\Scepion1d>java -cp C:\Users\Scepion1d\Dropbox\Workspace\IntellijIDEA\pr 
ofiler\out\artifacts\loader\loader.jar;C:\Users\Scepion1d\Dropbox\Workspace\Inte 
llijIDEA\app\out\production\app -Djava.system.class.loader=CustomClassLoader Main 
0 
1 
2 
0 
1 
2 
3 
0 
1 
2 
3 
java.lang.IllegalArgumentException: Non-positive latency: 0 
     at sun.misc.GC$LatencyRequest.<init>(GC.java:190) 
     at sun.misc.GC$LatencyRequest.<init>(GC.java:156) 
     at sun.misc.GC.requestLatency(GC.java:254) 
     at sun.rmi.transport.DGCClient$EndpointEntry.lookup(DGCClient.java:212) 
     at sun.rmi.transport.DGCClient.registerRefs(DGCClient.java:120) 
     at sun.rmi.transport.ConnectionInputStream.registerRefs(ConnectionInputS 
tream.java:80) 
     at sun.rmi.transport.StreamRemoteCall.releaseInputStream(StreamRemoteCal 
l.java:138) 
     at sun.rmi.transport.StreamRemoteCall.done(StreamRemoteCall.java:292) 
     at sun.rmi.server.UnicastRef.done(UnicastRef.java:431) 
     at sun.rmi.registry.RegistryImpl_Stub.lookup(Unknown Source) 
     at CustomClassLoader.initNotifier(CustomClassLoader.java:22) 
     at CustomClassLoader.loadClass(CustomClassLoader.java:35) 
     at java.lang.ClassLoader.loadClass(ClassLoader.java:247) 
     at sun.security.jca.ProviderConfig$3.run(ProviderConfig.java:234) 
     at java.security.AccessController.doPrivileged(Native Method) 
     at sun.security.jca.ProviderConfig.doLoadProvider(ProviderConfig.java:22 
5) 
     at sun.security.jca.ProviderConfig.getProvider(ProviderConfig.java:205) 
     at sun.security.jca.ProviderList.getProvider(ProviderList.java:215) 
     at sun.security.jca.ProviderList.getService(ProviderList.java:313) 
     at sun.security.jca.GetInstance.getInstance(GetInstance.java:140) 
     at java.security.Security.getImpl(Security.java:659) 
     at java.security.MessageDigest.getInstance(MessageDigest.java:129) 
     at java.rmi.dgc.VMID.computeAddressHash(VMID.java:140) 
     at java.rmi.dgc.VMID.<clinit>(VMID.java:27) 
     at sun.rmi.transport.DGCClient.<clinit>(DGCClient.java:66) 
     at sun.rmi.transport.ConnectionInputStream.registerRefs(ConnectionInputS 
tream.java:80) 
     at sun.rmi.transport.StreamRemoteCall.releaseInputStream(StreamRemoteCal 
l.java:138) 
     at sun.rmi.transport.StreamRemoteCall.done(StreamRemoteCall.java:292) 
     at sun.rmi.server.UnicastRef.done(UnicastRef.java:431) 
     at sun.rmi.registry.RegistryImpl_Stub.lookup(Unknown Source) 
     at CustomClassLoader.initNotifier(CustomClassLoader.java:22) 
     at CustomClassLoader.loadClass(CustomClassLoader.java:35) 
     at java.lang.ClassLoader.loadClass(ClassLoader.java:247) 
     at sun.security.jca.ProviderConfig$3.run(ProviderConfig.java:234) 
     at java.security.AccessController.doPrivileged(Native Method) 
     at sun.security.jca.ProviderConfig.doLoadProvider(ProviderConfig.java:22 
5) 
     at sun.security.jca.ProviderConfig.getProvider(ProviderConfig.java:205) 
     at sun.security.jca.ProviderList.getProvider(ProviderList.java:215) 
     at sun.security.jca.ProviderList$3.get(ProviderList.java:130) 
     at sun.security.jca.ProviderList$3.get(ProviderList.java:125) 
     at java.util.AbstractList$Itr.next(AbstractList.java:345) 
     at java.security.SecureRandom.getPrngAlgorithm(SecureRandom.java:522) 
     at java.security.SecureRandom.getDefaultPRNG(SecureRandom.java:165) 
     at java.security.SecureRandom.<init>(SecureRandom.java:133) 
     at java.rmi.server.UID.<init>(UID.java:92) 
     at java.rmi.server.ObjID.<clinit>(ObjID.java:71) 
     at java.rmi.registry.LocateRegistry.getRegistry(LocateRegistry.java:158) 

     at java.rmi.registry.LocateRegistry.getRegistry(LocateRegistry.java:106) 

     at java.rmi.registry.LocateRegistry.getRegistry(LocateRegistry.java:73) 
     at CustomClassLoader.initNotifier(CustomClassLoader.java:20) 
     at CustomClassLoader.loadClass(CustomClassLoader.java:35) 
     at java.lang.ClassLoader.loadClass(ClassLoader.java:247) 

मैंने सोचा है कि समस्या आरएमआई सर्वर में है, लेकिन मैंने एक और आरएमआई क्लाइंट लिखा और यह अच्छा काम करता है। क्या किसी को पता है कि समस्या कहां है और इसे कैसे हल करें (उन्हें)?

+1

आपको एक और (नया या दूसरा संस्करण) जावा आज़माएं और यदि यह मदद नहीं करता है, तो एक बग सबमिट करें (http://bugs.sun.com/) – tcb

+1

यह वास्तव में एक आकस्मिक रिकर्सन है। स्टैक ट्रेस पर एक अच्छा नज़र डालें। आप अपने वर्ग लोडर का उपयोग कर रहे हैं। – EJP

+0

इसे और ट्रैक करने के लिए, आप "0" के लिए अपने println में 'name' भी जोड़ सकते हैं। – JoshDM

उत्तर

2

टीएल; डीआर: कक्षा लोडर का उपयोग न करें जो रूट क्लास लोडर के रूप में ऐसे भारी दुष्प्रभावों का उपयोग न करें।

समस्या यह है कि क्लास sun.rmi.transport.DGCClient पर कॉन्स्ट फील्ड gcInterval प्रारंभ होने से पहले प्रारंभ नहीं किया गया है (और इसलिए मान 0 दिखाता है)। इसका कारण यह है कि आपका वर्ग लोडर आरएमआई के माध्यम से कॉल करता है जो डीजीसीसीएलआईन्ट का एक नया उदाहरण बनाता है। डीजीसीसीलिएंट के निर्माता के निष्पादन के दौरान एक और वर्ग लोड हो गया है (स्टैक ट्रेस देखें)। क्लास लोडर को यह तीसरा कॉल आरएमआई कॉल को फिर से ट्रिगर करता है जो डीजीसीसीएलआईन्ट का नया उदाहरण नहीं बनाता है लेकिन पहले बनाए गए एक का उपयोग करता है और कुछ कॉल करता है। इसका मतलब है कि एक आधा प्रारंभिक वस्तु पर एक कॉल किया जाता है जो इस गैर-प्रारंभिक स्थिर क्षेत्र के उपयोग की ओर जाता है।

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

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