2 Copyright (c) 1996, 1997, 1998, 1999, 2002 Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library. Thus, the terms and
23 conditions of the GNU General Public License cover the whole
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module. An independent module is a module which is not derived from
33 or based on this library. If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so. If you do not wish to do so, delete this
36 exception statement from your version. */
38 package java
.rmi
.server
;
41 import java
.net
.URLConnection
;
42 import java
.net
.URLClassLoader
;
43 import java
.io
.IOException
;
44 import java
.io
.DataInputStream
;
45 import java
.net
.MalformedURLException
;
46 import java
.util
.StringTokenizer
;
47 import java
.util
.Collection
;
48 import java
.util
.Collections
;
50 import java
.util
.WeakHashMap
;
51 import java
.util
.ArrayList
;
53 public class RMIClassLoader
56 static private class MyClassLoader
extends URLClassLoader
58 private MyClassLoader(URL
[] urls
, ClassLoader parent
)
63 Class
defineClass(String name
, byte[] data
)
65 return defineClass(name
, data
, 0, data
.length
);
69 private static Map cacheLoaders
; //map annotations to loaders
70 private static Map cacheClasses
; //map loader to classes that the loader loaded+
71 private static String defaultAnnotation
;
72 private static URL defaultCodebase
;
73 private static MyClassLoader defaultLoader
;
77 cacheLoaders
= Collections
.synchronizedMap(new WeakHashMap(5));
78 cacheClasses
= Collections
.synchronizedMap(new WeakHashMap(5));
79 defaultAnnotation
= System
.getProperty("java.rmi.server.defaultAnnotation");
82 if (defaultAnnotation
!= null)
83 defaultCodebase
= new URL(defaultAnnotation
);
87 defaultCodebase
= null;
89 if (defaultCodebase
!= null)
91 defaultLoader
= new MyClassLoader(new URL
[]{ defaultCodebase
},
92 Thread
.currentThread().getContextClassLoader());
93 cacheLoaders
.put(defaultAnnotation
, defaultLoader
);
94 cacheClasses
.put(defaultLoader
, Collections
.synchronizedMap(new WeakHashMap()));
101 public static Class
loadClass(String name
)
102 throws MalformedURLException
, ClassNotFoundException
104 return (loadClass("", name
));
107 public static Class
loadClass(URL codebase
, String name
)
108 throws MalformedURLException
, ClassNotFoundException
110 URL u
= new URL(codebase
, name
+ ".class");
113 URLConnection conn
= u
.openConnection();
114 DataInputStream strm
= new DataInputStream(conn
.getInputStream());
115 byte data
[] = new byte[conn
.getContentLength()];
116 strm
.readFully(data
);
117 return (defaultLoader
.defineClass(name
, data
));
119 catch (IOException _
)
121 throw new ClassNotFoundException(name
);
125 public static Class
loadClass(String codebases
, String name
)
126 throws MalformedURLException
, ClassNotFoundException
128 ClassLoader loader
= (ClassLoader
)cacheLoaders
.get(codebases
);
133 //codebases are separated by " "
134 StringTokenizer tok
= new StringTokenizer(codebases
, " ");
135 ArrayList urls
= new ArrayList();
136 while (tok
.hasMoreTokens())
137 urls
.add(new URL(tok
.nextToken()));
139 loader
= new MyClassLoader((URL
[])urls
.toArray(new URL
[urls
.size()]),
140 Thread
.currentThread().getContextClassLoader());
141 cacheLoaders
.put(codebases
, loader
);
142 cacheClasses
.put(loader
, Collections
.synchronizedMap(new WeakHashMap()));
146 //if codebases is empty, construct a classloader
147 // based on current context classloader,
148 // and we won't cache classloader for empty codebases
149 loader
= new MyClassLoader(new URL
[]{ defaultCodebase
},
150 Thread
.currentThread().getContextClassLoader());
155 Map classes
= (Map
)cacheClasses
.get(loader
);
158 c
= (Class
)classes
.get(name
);
161 c
= loader
.loadClass(name
);
162 classes
.put(name
, c
);
165 c
= loader
.loadClass(name
);
170 public static String
getClassAnnotation(Class cl
)
172 ClassLoader loader
= cl
.getClassLoader();
175 if (defaultCodebase
!= null)
176 return defaultCodebase
.toExternalForm();
180 if (loader
instanceof URLClassLoader
)
182 URL
[] urls
= ((URLClassLoader
)loader
).getURLs();
185 StringBuffer annotation
= new StringBuffer(urls
[0].toExternalForm());
186 for(int i
= 1; i
< urls
.length
; i
++)
188 annotation
.append(' ');
189 annotation
.append(urls
[i
].toExternalForm());
191 return annotation
.toString();
199 public static Object
getSecurityContext(ClassLoader loader
)
201 throw new Error("Not implemented");