1
2
3
4
5
6
7
8
9
10
11
12
13
14 package org.eclipse.jetty.webapp;
15
16 import java.io.File;
17 import java.io.FileOutputStream;
18 import java.io.IOException;
19 import java.io.InputStream;
20 import java.net.URL;
21 import java.net.URLClassLoader;
22 import java.security.CodeSource;
23 import java.security.PermissionCollection;
24 import java.util.HashSet;
25 import java.util.StringTokenizer;
26
27 import org.eclipse.jetty.server.handler.ContextHandler;
28 import org.eclipse.jetty.util.IO;
29 import org.eclipse.jetty.util.LazyList;
30 import org.eclipse.jetty.util.StringUtil;
31 import org.eclipse.jetty.util.log.Log;
32 import org.eclipse.jetty.util.resource.Resource;
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54 public class WebAppClassLoader extends URLClassLoader
55 {
56 private String _name;
57 private WebAppContext _context;
58 private ClassLoader _parent;
59 private HashSet<String> _extensions;
60
61
62
63
64 public WebAppClassLoader(WebAppContext context)
65 throws IOException
66 {
67 this(null,context);
68 }
69
70
71
72
73 public WebAppClassLoader(ClassLoader parent, WebAppContext context)
74 throws IOException
75 {
76 super(new URL[]{},parent!=null?parent
77 :(Thread.currentThread().getContextClassLoader()!=null?Thread.currentThread().getContextClassLoader()
78 :(WebAppClassLoader.class.getClassLoader()!=null?WebAppClassLoader.class.getClassLoader()
79 :ClassLoader.getSystemClassLoader())));
80 _parent=getParent();
81 _context=context;
82 if (_parent==null)
83 throw new IllegalArgumentException("no parent classloader!");
84
85 _extensions = new HashSet<String>();
86 _extensions.add(".jar");
87 _extensions.add(".zip");
88
89 String extensions = System.getProperty(WebAppClassLoader.class.getName() + ".extensions");
90 if(extensions!=null)
91 {
92 StringTokenizer tokenizer = new StringTokenizer(extensions, ",;");
93 while(tokenizer.hasMoreTokens())
94 _extensions.add(tokenizer.nextToken().trim());
95 }
96
97 if (context.getExtraClasspath()!=null)
98 addClassPath(context.getExtraClasspath());
99 }
100
101
102
103
104
105 public String getName()
106 {
107 return _name;
108 }
109
110
111
112
113
114 public void setName(String name)
115 {
116 _name=name;
117 }
118
119
120
121 public ContextHandler getContext()
122 {
123 return _context;
124 }
125
126
127
128
129
130
131
132 public void addClassPath(String classPath)
133 throws IOException
134 {
135 if (classPath == null)
136 return;
137
138 StringTokenizer tokenizer= new StringTokenizer(classPath, ",;");
139 while (tokenizer.hasMoreTokens())
140 {
141 Resource resource= _context.newResource(tokenizer.nextToken());
142 if (Log.isDebugEnabled())
143 Log.debug("Path resource=" + resource);
144
145
146 File file= resource.getFile();
147 if (file != null)
148 {
149 URL url= resource.getURL();
150 addURL(url);
151 }
152 else
153 {
154
155 if (!resource.isDirectory() && file == null)
156 {
157 throw new IllegalArgumentException("!file: "+resource);
158 }
159 else
160 {
161 URL url= resource.getURL();
162 addURL(url);
163 }
164 }
165 }
166 }
167
168
169
170
171
172 private boolean isFileSupported(String file)
173 {
174 int dot = file.lastIndexOf('.');
175 return dot!=-1 && _extensions.contains(file.substring(dot));
176 }
177
178
179
180
181
182
183
184
185
186 public void addJars(Resource lib)
187 {
188 if (lib.exists() && lib.isDirectory())
189 {
190 String[] files=lib.list();
191 for (int f=0;files!=null && f<files.length;f++)
192 {
193 try {
194 Resource fn=lib.addPath(files[f]);
195 String fnlc=fn.getName().toLowerCase();
196 if (isFileSupported(fnlc))
197 {
198 String jar=fn.toString();
199 jar=StringUtil.replace(jar, ",", "%2C");
200 jar=StringUtil.replace(jar, ";", "%3B");
201 addClassPath(jar);
202 }
203 }
204 catch (Exception ex)
205 {
206 Log.warn(Log.EXCEPTION,ex);
207 }
208 }
209 }
210 }
211
212 public void destroy()
213 {
214 this._parent=null;
215 }
216
217
218
219 public PermissionCollection getPermissions(CodeSource cs)
220 {
221
222 PermissionCollection permissions=_context.getPermissions();
223 PermissionCollection pc= (permissions == null) ? super.getPermissions(cs) : permissions;
224 return pc;
225 }
226
227
228 public synchronized URL getResource(String name)
229 {
230 URL url= null;
231 boolean tried_parent= false;
232 if (_context.isParentLoaderPriority() || _context.isSystemClass(name))
233 {
234 tried_parent= true;
235
236 if (_parent!=null)
237 url= _parent.getResource(name);
238 }
239
240 if (url == null)
241 {
242 url= this.findResource(name);
243
244 if (url == null && name.startsWith("/"))
245 {
246 if (Log.isDebugEnabled())
247 Log.debug("HACK leading / off " + name);
248 url= this.findResource(name.substring(1));
249 }
250 }
251
252 if (url == null && !tried_parent && !_context.isServerClass(name) )
253 {
254 if (_parent!=null)
255 url= _parent.getResource(name);
256 }
257
258 if (url != null)
259 if (Log.isDebugEnabled())
260 Log.debug("getResource("+name+")=" + url);
261
262 return url;
263 }
264
265
266 @Override
267 public synchronized Class<?> loadClass(String name) throws ClassNotFoundException
268 {
269 return loadClass(name, false);
270 }
271
272
273 @Override
274 protected synchronized Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException
275 {
276 Class<?> c= findLoadedClass(name);
277 ClassNotFoundException ex= null;
278 boolean tried_parent= false;
279
280 boolean system_class=_context.isSystemClass(name);
281 boolean server_class=_context.isServerClass(name);
282
283 if (system_class && server_class)
284 {
285 return null;
286 }
287
288 if (c == null && _parent!=null && (_context.isParentLoaderPriority() || system_class) )
289 {
290 tried_parent= true;
291 try
292 {
293 c= _parent.loadClass(name);
294 if (Log.isDebugEnabled())
295 Log.debug("loaded " + c);
296 }
297 catch (ClassNotFoundException e)
298 {
299 ex= e;
300 }
301 }
302
303 if (c == null)
304 {
305 try
306 {
307 c= this.findClass(name);
308 }
309 catch (ClassNotFoundException e)
310 {
311 ex= e;
312 }
313 }
314
315 if (c == null && _parent!=null && !tried_parent && !server_class )
316 c= _parent.loadClass(name);
317
318 if (c == null)
319 throw ex;
320
321 if (resolve)
322 resolveClass(c);
323
324 if (Log.isDebugEnabled())
325 Log.debug("loaded " + c+ " from "+c.getClassLoader());
326
327 return c;
328 }
329
330
331 public String toString()
332 {
333 if (Log.isDebugEnabled())
334 return "ContextLoader@" + _name + "(" + LazyList.array2List(getURLs()) + ") / " + _parent;
335 return "ContextLoader@" + _name;
336 }
337
338 }