/[classpath]/classpath/java/rmi/server/RMIClassLoader.java
ViewVC logotype

Diff of /classpath/java/rmi/server/RMIClassLoader.java

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.5 by cbj, Mon Mar 25 05:12:19 2002 UTC revision 1.6 by mark, Thu Oct 31 18:35:23 2002 UTC
# Line 43  import java.net.URLClassLoader; Line 43  import java.net.URLClassLoader;
43  import java.io.IOException;  import java.io.IOException;
44  import java.io.DataInputStream;  import java.io.DataInputStream;
45  import java.net.MalformedURLException;  import java.net.MalformedURLException;
46  import java.util.StringTokenizer;  import java.util.ArrayList;
47  import java.util.Collection;  import java.util.Collection;
48  import java.util.Collections;  import java.util.Collections;
49    import java.util.Hashtable;
50  import java.util.Map;  import java.util.Map;
51    import java.util.StringTokenizer;
52  import java.util.WeakHashMap;  import java.util.WeakHashMap;
 import java.util.ArrayList;  
53    
54  public class RMIClassLoader  public class RMIClassLoader
55  {  {
56    
57    static private class MyClassLoader extends URLClassLoader    static private class MyClassLoader extends URLClassLoader
58    {    {
59    
60        private MyClassLoader(URL[] urls, ClassLoader parent, String annotation)
61        {
62          super(urls, parent);
63          this.annotation = annotation;
64        }
65    
66      private MyClassLoader(URL[] urls, ClassLoader parent)      private MyClassLoader(URL[] urls, ClassLoader parent)
67      {      {
68        super (urls, parent);        super (urls, parent);
69          this.annotation = urlToAnnotation(urls);
70      }      }
71    
72      Class defineClass(String name, byte[] data)      public static String urlToAnnotation(URL[] urls)
73      {      {
74        return defineClass(name, data, 0, data.length);        if (urls.length == 0)
75            return null;
76    
77          StringBuffer annotation = new StringBuffer(64*urls.length);
78          for(int i = 0; i < urls.length; i++)
79            {
80              annotation.append(urls[i].toExternalForm());
81              annotation.append(' ');
82            }
83    
84          return annotation.toString();
85        }
86    
87        public final String getClassAnnotation(){
88          return annotation;
89      }      }
90    
91        private final String annotation;
92    
93    }    }
94    
95    private static Map cacheLoaders; //map annotations to loaders    private static Map cacheLoaders; //map annotations to loaders
96    private static Map cacheClasses; //map loader to classes that the loader loaded+    private static Map cacheAnnotations; //map loaders to annotations
97    
98      //defaultAnnotation is got from system property
99      // "java.rmi.server.defaultAnnotation"
100    private static String defaultAnnotation;    private static String defaultAnnotation;
101      //URL object for defaultAnnotation
102    private static URL defaultCodebase;    private static URL defaultCodebase;
103      //class loader for defaultAnnotation
104    private static MyClassLoader defaultLoader;    private static MyClassLoader defaultLoader;
105        
106    static    static
107    {    {
108      cacheLoaders = Collections.synchronizedMap(new WeakHashMap(5));      // 89 is a nice prime number for Hashtable initial capacity
109      cacheClasses = Collections.synchronizedMap(new WeakHashMap(5));      cacheLoaders = new Hashtable(89);
110        cacheAnnotations = new Hashtable(89);
111        
112      defaultAnnotation = System.getProperty("java.rmi.server.defaultAnnotation");      defaultAnnotation = System.getProperty("java.rmi.server.defaultAnnotation");
113      try      try
114        {        {
# Line 89  public class RMIClassLoader Line 122  public class RMIClassLoader
122      if (defaultCodebase != null)      if (defaultCodebase != null)
123        {        {
124          defaultLoader = new MyClassLoader(new URL[]{ defaultCodebase },          defaultLoader = new MyClassLoader(new URL[]{ defaultCodebase },
125                                            Thread.currentThread().getContextClassLoader());                                            null, defaultAnnotation);
126          cacheLoaders.put(defaultAnnotation, defaultLoader);          cacheLoaders.put(defaultAnnotation, defaultLoader);
         cacheClasses.put(defaultLoader, Collections.synchronizedMap(new WeakHashMap()));  
127        }        }
128    }    }
129        
# Line 104  public class RMIClassLoader Line 136  public class RMIClassLoader
136      return (loadClass("", name));      return (loadClass("", name));
137    }    }
138    
139    public static Class loadClass(URL codebase, String name)    public static Class loadClass(String codebases, String name)
140      throws MalformedURLException, ClassNotFoundException      throws MalformedURLException, ClassNotFoundException
141    {    {
142      URL u = new URL(codebase, name + ".class");      Class c = null;
143        ClassLoader loader = Thread.currentThread().getContextClassLoader();
144        //try context class loader first
145      try      try
146        {        {
147          URLConnection conn = u.openConnection();              c = loader.loadClass(name);      
         DataInputStream strm = new DataInputStream(conn.getInputStream());  
         byte data[] = new byte[conn.getContentLength()];  
         strm.readFully(data);  
         return (defaultLoader.defineClass(name, data));  
       }  
     catch (IOException _)  
       {  
         throw new ClassNotFoundException(name);  
148        }        }
149    }      catch(ClassNotFoundException e) {}
150      
151    public static Class loadClass(String codebases, String name)      if (c != null)
152      throws MalformedURLException, ClassNotFoundException        return c;
153    {  
154      ClassLoader loader = (ClassLoader)cacheLoaders.get(codebases);      if (codebases.length() == 0) //==""
155      if (loader == null)        loader = defaultLoader;
156        else
157        {        {
158          if (codebases != "")          loader = (ClassLoader)cacheLoaders.get(codebases);
159            if (loader == null)
160            {            {
161              //codebases are separated by " "              //create an entry in cacheLoaders mapping a loader to codebases.
162                
163                // codebases are separated by " "
164              StringTokenizer tok = new StringTokenizer(codebases, " ");              StringTokenizer tok = new StringTokenizer(codebases, " ");
165              ArrayList urls = new ArrayList();              ArrayList urls = new ArrayList();
166              while (tok.hasMoreTokens())              while (tok.hasMoreTokens())
167                urls.add(new URL(tok.nextToken()));                urls.add(new URL(tok.nextToken()));
168                  
169              loader = new MyClassLoader((URL[])urls.toArray(new URL[urls.size()]),              loader = new MyClassLoader((URL[])urls.toArray(new URL[urls.size()]),
170                                         Thread.currentThread().getContextClassLoader());                                          null, codebases);
171              cacheLoaders.put(codebases, loader);              cacheLoaders.put(codebases, loader);
             cacheClasses.put(loader, Collections.synchronizedMap(new WeakHashMap()));  
           }  
         else  
           {  
             //if codebases is empty, construct a classloader  
             // based on current context classloader,  
             // and we won't cache classloader for empty codebases  
             loader = new MyClassLoader(new URL[]{ defaultCodebase },  
                                        Thread.currentThread().getContextClassLoader());  
172            }            }
173        }        }
174    
175      Class c = null;      return loader.loadClass(name);
     Map classes = (Map)cacheClasses.get(loader);  
     if (classes != null)  
       {  
         c = (Class)classes.get(name);  
         if (c == null)  
           {  
             c = loader.loadClass(name);  
             classes.put(name, c);  
           }  
       }else  
         c = loader.loadClass(name);  
       
     return c;  
176    }    }
177        
178    public static String getClassAnnotation(Class cl)    public static String getClassAnnotation(Class cl)
179    {    {
180      ClassLoader loader = cl.getClassLoader();      ClassLoader loader = cl.getClassLoader();
181      if (loader == null)      if (loader == null || loader == ClassLoader.getSystemClassLoader())
182        {        {
183          if (defaultCodebase != null)          return null; //??
184            return defaultCodebase.toExternalForm();        }
185          else          
186            return null;      if (loader instanceof MyClassLoader)
187          {
188            return ((MyClassLoader)loader).getClassAnnotation();
189        }        }
190            
191        String s = (String)cacheAnnotations.get(loader);
192        if (s != null)
193          return s;
194                
195      if (loader instanceof URLClassLoader)      if (loader instanceof URLClassLoader)
196        {        {
197          URL[] urls = ((URLClassLoader)loader).getURLs();          URL[] urls = ((URLClassLoader)loader).getURLs();
198          if(urls.length == 0)          if(urls.length == 0)
199            return null;            return null;
200          StringBuffer annotation = new StringBuffer(urls[0].toExternalForm());  
201          for(int i = 1; i < urls.length; i++)          StringBuffer annotation = new StringBuffer(64*urls.length);
202            for(int i = 0; i < urls.length; i++)
203            {            {
             annotation.append(' ');  
204              annotation.append(urls[i].toExternalForm());              annotation.append(urls[i].toExternalForm());
205                annotation.append(' ');
206            }            }
207          return annotation.toString();          s = annotation.toString();
208            cacheAnnotations.put(loader, s);
209        }        }
210      return null;      return null;
211    }    }

Legend:
Removed from v.1.5  
changed lines
  Added in v.1.6

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26