1
24 package net.sf.jasperreports.engine.util;
25
26 import java.io.ByteArrayOutputStream;
27 import java.io.File;
28 import java.io.FileInputStream;
29 import java.io.IOException;
30 import java.security.ProtectionDomain;
31 import java.util.HashMap;
32 import java.util.Map;
33
34 import net.sf.jasperreports.engine.JRRuntimeException;
35
36
39 public class JRClassLoader extends ClassLoader
40 {
41
42 private static final Map<String, String> PRIMITIVE_COMPONENT_ENCODING;
43 static
44 {
45 PRIMITIVE_COMPONENT_ENCODING = new HashMap<>();
46
47 PRIMITIVE_COMPONENT_ENCODING.put(Boolean.TYPE.getName(), "Z");
48 PRIMITIVE_COMPONENT_ENCODING.put(Byte.TYPE.getName(), "B");
49 PRIMITIVE_COMPONENT_ENCODING.put(Character.TYPE.getName(), "C");
50 PRIMITIVE_COMPONENT_ENCODING.put(Double.TYPE.getName(), "D");
51 PRIMITIVE_COMPONENT_ENCODING.put(Float.TYPE.getName(), "F");
52 PRIMITIVE_COMPONENT_ENCODING.put(Integer.TYPE.getName(), "I");
53 PRIMITIVE_COMPONENT_ENCODING.put(Long.TYPE.getName(), "J");
54 PRIMITIVE_COMPONENT_ENCODING.put(Short.TYPE.getName(), "S");
55 }
56
57 private static ProtectionDomainFactory protectionDomainFactory;
58
59 public static synchronized ProtectionDomainFactory getProtectionDomainFactory()
60 {
61 if (protectionDomainFactory == null)
62 {
63 protectionDomainFactory = new SingleProtectionDomainFactory(JRClassLoader.class.getProtectionDomain());
64 }
65
66 return protectionDomainFactory;
67 }
68
69
78 public static void setProtectionDomain(ProtectionDomain protectionDomain)
79 {
80 SingleProtectionDomainFactory factory = new SingleProtectionDomainFactory(protectionDomain);
81 setProtectionDomainFactory(factory);
82 }
83
84
96 public static void setProtectionDomainFactory(ProtectionDomainFactory protectionDomainFactory)
97 {
98 JRClassLoader.protectionDomainFactory = protectionDomainFactory;
99 }
100
101 private ProtectionDomain protectionDomain;
102
103 private ClassLoaderFilter classLoaderFilter;
104
105
108 protected JRClassLoader()
109 {
110 super();
111 }
112
113 protected JRClassLoader(ClassLoaderFilter classLoaderFilter)
114 {
115 super();
116
117 this.classLoaderFilter = classLoaderFilter;
118 }
119
120
123 protected JRClassLoader(ClassLoader parent)
124 {
125 super(parent);
126 }
127
128 protected JRClassLoader(ClassLoader parent, ClassLoaderFilter classLoaderFilter)
129 {
130 super(parent);
131
132 this.classLoaderFilter = classLoaderFilter;
133 }
134
135
136
139 public static Class<?> loadClassForName(String className) throws ClassNotFoundException
140 {
141 Class<?> clazz = null;
142
143 String classRealName = className;
144 ClassNotFoundException initialEx = null;
145
146 try
147 {
148 clazz = loadClassForRealName(classRealName);
149 }
150 catch (ClassNotFoundException e)
151 {
152 initialEx = e;
153 }
154
155 int lastDotIndex = 0;
156 while (clazz == null && (lastDotIndex = classRealName.lastIndexOf('.')) > 0)
157 {
158 classRealName =
159 classRealName.substring(0, lastDotIndex) + "$" + classRealName.substring(lastDotIndex + 1);
160 try
161 {
162 clazz = loadClassForRealName(classRealName);
163 }
164 catch (ClassNotFoundException e)
165 {
166 }
167 }
168
169 if (clazz == null)
170 {
171 throw initialEx;
172 }
173
174 return clazz;
175 }
176
177
178
181 public static Class<?> loadClassForRealName(String className) throws ClassNotFoundException
182 {
183 Class<?> clazz = null;
184
185 ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
186 if (classLoader != null)
187 {
188 try
189 {
190 clazz = Class.forName(className, true, classLoader);
191 }
192 catch (ClassNotFoundException e)
193 {
194
195
196 }
197 }
198
199 if (clazz == null)
200 {
201 classLoader = JRClassLoader.class.getClassLoader();
202 if (classLoader == null)
203 {
204 clazz = Class.forName(className);
205 }
206 else
207 {
208 clazz = Class.forName(className, true, classLoader);
209 }
210 }
211
212 return clazz;
213 }
214
215
216
219 public static Class<?> loadClassFromFile(String className, File file) throws IOException
220 {
221 Class<?> clazz = null;
222
223 ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
224 if (classLoader != null)
225 {
226 try
227 {
228 clazz =
229 (new JRClassLoader(classLoader))
230 .loadClass(className, file);
231 }
232 catch(NoClassDefFoundError e)
233 {
234
235
236 }
237 }
238
239 if (clazz == null)
240 {
241 classLoader = JRClassLoader.class.getClassLoader();
242 if (classLoader == null)
243 {
244 clazz =
245 (new JRClassLoader())
246 .loadClass(className, file);
247 }
248 else
249 {
250 clazz =
251 (new JRClassLoader(classLoader))
252 .loadClass(className, file);
253 }
254 }
255
256 return clazz;
257 }
258
259
260
263 public static Class<?> loadClassFromBytes(String className, byte[] bytecodes)
264 {
265 return loadClassFromBytes(null, className, bytecodes);
266 }
267
268 public static Class<?> loadClassFromBytes(ClassLoaderFilter classLoaderFilter,
269 String className, byte[] bytecodes)
270 {
271 Class<?> clazz = null;
272
273 ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
274 if (classLoader != null)
275 {
276 try
277 {
278 clazz =
279 (new JRClassLoader(classLoader, classLoaderFilter))
280 .loadClass(className, bytecodes);
281 }
282 catch(NoClassDefFoundError e)
283 {
284
285
286 }
287 }
288
289 if (clazz == null)
290 {
291 classLoader = JRClassLoader.class.getClassLoader();
292 if (classLoader == null)
293 {
294 clazz =
295 (new JRClassLoader(classLoaderFilter))
296 .loadClass(className, bytecodes);
297 }
298 else
299 {
300 clazz =
301 (new JRClassLoader(classLoader, classLoaderFilter))
302 .loadClass(className, bytecodes);
303 }
304 }
305
306 return clazz;
307 }
308
309
310
313 protected Class<?> loadClass(String className, File file) throws IOException
314 {
315 FileInputStream fis = null;
316 ByteArrayOutputStream baos = null;
317
318 byte[] bytecodes = new byte[10000];
319 int ln = 0;
320
321 try
322 {
323 fis = new FileInputStream(file);
324 baos = new ByteArrayOutputStream();
325
326 while ( (ln = fis.read(bytecodes)) > 0 )
327 {
328 baos.write(bytecodes, 0, ln);
329 }
330
331 baos.flush();
332 }
333 finally
334 {
335 if (baos != null)
336 {
337 try
338 {
339 baos.close();
340 }
341 catch(IOException e)
342 {
343 }
344 }
345
346 if (fis != null)
347 {
348 try
349 {
350 fis.close();
351 }
352 catch(IOException e)
353 {
354 }
355 }
356 }
357
358 return loadClass(className, baos.toByteArray());
359 }
360
361 protected synchronized ProtectionDomain getProtectionDomain()
362 {
363 if (protectionDomain == null)
364 {
365 protectionDomain = getProtectionDomainFactory().getProtectionDomain(this);
366 }
367 return protectionDomain;
368 }
369
370
373 protected Class<?> loadClass(String className, byte[] bytecodes)
374 {
375 Class<?> clazz = null;
376
377 clazz =
378 defineClass(
379 className,
380 bytecodes,
381 0,
382 bytecodes.length,
383 getProtectionDomain()
384 );
385
386 return clazz;
387 }
388
389 @Override
390 protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException, JRRuntimeException
391 {
392 if (classLoaderFilter != null)
393 {
394 classLoaderFilter.checkClassVisibility(name);
395 }
396
397 return super.loadClass(name, resolve);
398 }
399
400
403 public static String getClassRealName(String className)
404 {
405 if (className == null)
406 {
407 return null;
408 }
409
410 int ltPos = className.indexOf('<');
411 if (ltPos > 0)
412 {
413 int gtPos = className.lastIndexOf('>');
414 if (gtPos > ltPos)
415 {
416 className = className.substring(0, ltPos) + className.substring(gtPos);
417 }
418 }
419
420 int arrayDimension = 0;
421 int classNameEnd = className.length();
422 int index = 0;
423 int pos = 0;
424 while (index < classNameEnd && (pos = className.indexOf('[', index)) >= 0)
425 {
426 if (index == 0)
427 {
428 classNameEnd = pos;
429 }
430 index = pos;
431 arrayDimension++;
432 }
433
434 if (arrayDimension > 0)
435 {
436 StringBuilder sb = new StringBuilder();
437
438 for(int i = 0; i < arrayDimension; i++)
439 {
440 sb.append('[');
441 }
442
443 String componentClass = className.substring(0, classNameEnd);
444 String primitiveEncoding = PRIMITIVE_COMPONENT_ENCODING.get(componentClass);
445 if (primitiveEncoding == null)
446 {
447
448 sb.append('L');
449 sb.append(componentClass);
450 sb.append(';');
451 }
452 else
453 {
454 sb.append(primitiveEncoding);
455 }
456
457 return sb.toString();
458 }
459
460 return className;
461 }
462
463
464 }
465