1
17 package org.apache.catalina.core;
18
19 import java.io.IOException;
20 import java.io.InputStream;
21 import java.lang.annotation.Annotation;
22 import java.lang.reflect.Field;
23 import java.lang.reflect.InvocationTargetException;
24 import java.lang.reflect.Method;
25 import java.security.AccessController;
26 import java.security.PrivilegedAction;
27 import java.security.PrivilegedActionException;
28 import java.security.PrivilegedExceptionAction;
29 import java.util.ArrayList;
30 import java.util.Collections;
31 import java.util.HashMap;
32 import java.util.HashSet;
33 import java.util.List;
34 import java.util.Map;
35 import java.util.Properties;
36 import java.util.Set;
37
38 import javax.annotation.PostConstruct;
39 import javax.annotation.PreDestroy;
40 import javax.annotation.Resource;
41 import javax.ejb.EJB;
42 import javax.naming.Context;
43 import javax.naming.NamingException;
44 import javax.persistence.PersistenceContext;
45 import javax.persistence.PersistenceUnit;
46 import javax.xml.ws.WebServiceRef;
47
48 import org.apache.catalina.ContainerServlet;
49 import org.apache.catalina.Globals;
50 import org.apache.catalina.security.SecurityUtil;
51 import org.apache.catalina.util.Introspection;
52 import org.apache.juli.logging.Log;
53 import org.apache.tomcat.InstanceManager;
54 import org.apache.tomcat.util.ExceptionUtils;
55 import org.apache.tomcat.util.collections.ManagedConcurrentWeakHashMap;
56 import org.apache.tomcat.util.res.StringManager;
57
58 public class DefaultInstanceManager implements InstanceManager {
59
60
61 private static final AnnotationCacheEntry[] ANNOTATIONS_EMPTY
62 = new AnnotationCacheEntry[0];
63
64
67 protected static final StringManager sm =
68 StringManager.getManager(Constants.Package);
69
70 private static final boolean EJB_PRESENT;
71 private static final boolean JPA_PRESENT;
72 private static final boolean WS_PRESENT;
73
74 static {
75 Class<?> clazz = null;
76 try {
77 clazz = Class.forName("javax.ejb.EJB");
78 } catch (ClassNotFoundException cnfe) {
79
80 }
81 EJB_PRESENT = (clazz != null);
82
83 clazz = null;
84 try {
85 clazz = Class.forName("javax.persistence.PersistenceContext");
86 } catch (ClassNotFoundException cnfe) {
87
88 }
89 JPA_PRESENT = (clazz != null);
90
91 clazz = null;
92 try {
93 clazz = Class.forName("javax.xml.ws.WebServiceRef");
94 } catch (ClassNotFoundException cnfe) {
95
96 }
97 WS_PRESENT = (clazz != null);
98 }
99
100
101 private final Context context;
102 private final Map<String, Map<String, String>> injectionMap;
103 protected final ClassLoader classLoader;
104 protected final ClassLoader containerClassLoader;
105 protected final boolean privileged;
106 protected final boolean ignoreAnnotations;
107 private final Set<String> restrictedClasses;
108 private final ManagedConcurrentWeakHashMap<Class<?>, AnnotationCacheEntry[]> annotationCache =
109 new ManagedConcurrentWeakHashMap<>();
110 private final Map<String, String> postConstructMethods;
111 private final Map<String, String> preDestroyMethods;
112
113 public DefaultInstanceManager(Context context,
114 Map<String, Map<String, String>> injectionMap,
115 org.apache.catalina.Context catalinaContext,
116 ClassLoader containerClassLoader) {
117 classLoader = catalinaContext.getLoader().getClassLoader();
118 privileged = catalinaContext.getPrivileged();
119 this.containerClassLoader = containerClassLoader;
120 ignoreAnnotations = catalinaContext.getIgnoreAnnotations();
121 Log log = catalinaContext.getLogger();
122 Set<String> classNames = new HashSet<>();
123 loadProperties(classNames,
124 "org/apache/catalina/core/RestrictedServlets.properties",
125 "defaultInstanceManager.restrictedServletsResource", log);
126 loadProperties(classNames,
127 "org/apache/catalina/core/RestrictedListeners.properties",
128 "defaultInstanceManager.restrictedListenersResource", log);
129 loadProperties(classNames,
130 "org/apache/catalina/core/RestrictedFilters.properties",
131 "defaultInstanceManager.restrictedFiltersResource", log);
132 restrictedClasses = Collections.unmodifiableSet(classNames);
133 this.context = context;
134 this.injectionMap = injectionMap;
135 this.postConstructMethods = catalinaContext.findPostConstructMethods();
136 this.preDestroyMethods = catalinaContext.findPreDestroyMethods();
137 }
138
139 @Override
140 public Object newInstance(Class<?> clazz) throws IllegalAccessException,
141 InvocationTargetException, NamingException, InstantiationException,
142 IllegalArgumentException, NoSuchMethodException, SecurityException {
143 return newInstance(clazz.getConstructor().newInstance(), clazz);
144 }
145
146 @Override
147 public Object newInstance(String className) throws IllegalAccessException,
148 InvocationTargetException, NamingException, InstantiationException,
149 ClassNotFoundException, IllegalArgumentException, NoSuchMethodException, SecurityException {
150 Class<?> clazz = loadClassMaybePrivileged(className, classLoader);
151 return newInstance(clazz.getConstructor().newInstance(), clazz);
152 }
153
154 @Override
155 public Object newInstance(final String className, final ClassLoader classLoader)
156 throws IllegalAccessException, NamingException, InvocationTargetException,
157 InstantiationException, ClassNotFoundException, IllegalArgumentException,
158 NoSuchMethodException, SecurityException {
159 Class<?> clazz = classLoader.loadClass(className);
160 return newInstance(clazz.getConstructor().newInstance(), clazz);
161 }
162
163 @Override
164 public void newInstance(Object o)
165 throws IllegalAccessException, InvocationTargetException, NamingException {
166 newInstance(o, o.getClass());
167 }
168
169 private Object newInstance(Object instance, Class<?> clazz)
170 throws IllegalAccessException, InvocationTargetException, NamingException {
171 if (!ignoreAnnotations) {
172 Map<String, String> injections = assembleInjectionsFromClassHierarchy(clazz);
173 populateAnnotationsCache(clazz, injections);
174 processAnnotations(instance, injections);
175 postConstruct(instance, clazz);
176 }
177 return instance;
178 }
179
180 private Map<String, String> assembleInjectionsFromClassHierarchy(Class<?> clazz) {
181 Map<String, String> injections = new HashMap<>();
182 Map<String, String> currentInjections = null;
183 while (clazz != null) {
184 currentInjections = this.injectionMap.get(clazz.getName());
185 if (currentInjections != null) {
186 injections.putAll(currentInjections);
187 }
188 clazz = clazz.getSuperclass();
189 }
190 return injections;
191 }
192
193 @Override
194 public void destroyInstance(Object instance) throws IllegalAccessException,
195 InvocationTargetException {
196 if (!ignoreAnnotations) {
197 preDestroy(instance, instance.getClass());
198 }
199 }
200
201
211 protected void postConstruct(Object instance, final Class<?> clazz)
212 throws IllegalAccessException, InvocationTargetException {
213 if (context == null) {
214
215 return;
216 }
217
218 Class<?> superClass = clazz.getSuperclass();
219 if (superClass != Object.class) {
220 postConstruct(instance, superClass);
221 }
222
223
224
225 AnnotationCacheEntry[] annotations = annotationCache.get(clazz);
226 for (AnnotationCacheEntry entry : annotations) {
227 if (entry.getType() == AnnotationCacheEntryType.POST_CONSTRUCT) {
228 Method postConstruct = getMethod(clazz, entry);
229 synchronized (postConstruct) {
230 boolean accessibility = postConstruct.isAccessible();
231 postConstruct.setAccessible(true);
232 postConstruct.invoke(instance);
233 postConstruct.setAccessible(accessibility);
234 }
235 }
236 }
237 }
238
239
240
250 protected void preDestroy(Object instance, final Class<?> clazz)
251 throws IllegalAccessException, InvocationTargetException {
252 Class<?> superClass = clazz.getSuperclass();
253 if (superClass != Object.class) {
254 preDestroy(instance, superClass);
255 }
256
257
258
259 AnnotationCacheEntry[] annotations = annotationCache.get(clazz);
260 if (annotations == null) {
261
262 return;
263 }
264 for (AnnotationCacheEntry entry : annotations) {
265 if (entry.getType() == AnnotationCacheEntryType.PRE_DESTROY) {
266 Method preDestroy = getMethod(clazz, entry);
267 synchronized (preDestroy) {
268 boolean accessibility = preDestroy.isAccessible();
269 preDestroy.setAccessible(true);
270 preDestroy.invoke(instance);
271 preDestroy.setAccessible(accessibility);
272 }
273 }
274 }
275 }
276
277
278 @Override
279 public void backgroundProcess() {
280 annotationCache.maintain();
281 }
282
283
284
296 protected void populateAnnotationsCache(Class<?> clazz,
297 Map<String, String> injections) throws IllegalAccessException,
298 InvocationTargetException, NamingException {
299
300 List<AnnotationCacheEntry> annotations = null;
301 Set<String> injectionsMatchedToSetter = new HashSet<>();
302
303 while (clazz != null) {
304 AnnotationCacheEntry[] annotationsArray = annotationCache.get(clazz);
305 if (annotationsArray == null) {
306 if (annotations == null) {
307 annotations = new ArrayList<>();
308 } else {
309 annotations.clear();
310 }
311
312
313 Method[] methods = Introspection.getDeclaredMethods(clazz);
314 Method postConstruct = null;
315 String postConstructFromXml = postConstructMethods.get(clazz.getName());
316 Method preDestroy = null;
317 String preDestroyFromXml = preDestroyMethods.get(clazz.getName());
318 for (Method method : methods) {
319 if (context != null) {
320
321 if (injections != null && Introspection.isValidSetter(method)) {
322 String fieldName = Introspection.getPropertyName(method);
323 injectionsMatchedToSetter.add(fieldName);
324 if (injections.containsKey(fieldName)) {
325 annotations.add(new AnnotationCacheEntry(
326 method.getName(),
327 method.getParameterTypes(),
328 injections.get(fieldName),
329 AnnotationCacheEntryType.SETTER));
330 continue;
331 }
332 }
333 Resource resourceAnnotation;
334 Annotation ejbAnnotation;
335 Annotation webServiceRefAnnotation;
336 Annotation persistenceContextAnnotation;
337 Annotation persistenceUnitAnnotation;
338 if ((resourceAnnotation = method.getAnnotation(Resource.class)) != null) {
339 annotations.add(new AnnotationCacheEntry(
340 method.getName(),
341 method.getParameterTypes(),
342 resourceAnnotation.name(),
343 AnnotationCacheEntryType.SETTER));
344 } else if (EJB_PRESENT &&
345 (ejbAnnotation = method.getAnnotation(EJB.class)) != null) {
346 annotations.add(new AnnotationCacheEntry(
347 method.getName(),
348 method.getParameterTypes(),
349 ((EJB) ejbAnnotation).name(),
350 AnnotationCacheEntryType.SETTER));
351 } else if (WS_PRESENT && (webServiceRefAnnotation =
352 method.getAnnotation(WebServiceRef.class)) != null) {
353 annotations.add(new AnnotationCacheEntry(
354 method.getName(),
355 method.getParameterTypes(),
356 ((WebServiceRef) webServiceRefAnnotation).name(),
357 AnnotationCacheEntryType.SETTER));
358 } else if (JPA_PRESENT && (persistenceContextAnnotation =
359 method.getAnnotation(PersistenceContext.class)) != null) {
360 annotations.add(new AnnotationCacheEntry(
361 method.getName(),
362 method.getParameterTypes(),
363 ((PersistenceContext) persistenceContextAnnotation).name(),
364 AnnotationCacheEntryType.SETTER));
365 } else if (JPA_PRESENT && (persistenceUnitAnnotation =
366 method.getAnnotation(PersistenceUnit.class)) != null) {
367 annotations.add(new AnnotationCacheEntry(
368 method.getName(),
369 method.getParameterTypes(),
370 ((PersistenceUnit) persistenceUnitAnnotation).name(),
371 AnnotationCacheEntryType.SETTER));
372 }
373 }
374
375 postConstruct = findPostConstruct(postConstruct, postConstructFromXml, method);
376
377 preDestroy = findPreDestroy(preDestroy, preDestroyFromXml, method);
378 }
379
380 if (postConstruct != null) {
381 annotations.add(new AnnotationCacheEntry(
382 postConstruct.getName(),
383 postConstruct.getParameterTypes(), null,
384 AnnotationCacheEntryType.POST_CONSTRUCT));
385 } else if (postConstructFromXml != null) {
386 throw new IllegalArgumentException(sm.getString("defaultInstanceManager.postConstructNotFound",
387 postConstructFromXml, clazz.getName()));
388 }
389 if (preDestroy != null) {
390 annotations.add(new AnnotationCacheEntry(
391 preDestroy.getName(),
392 preDestroy.getParameterTypes(), null,
393 AnnotationCacheEntryType.PRE_DESTROY));
394 } else if (preDestroyFromXml != null) {
395 throw new IllegalArgumentException(sm.getString("defaultInstanceManager.preDestroyNotFound",
396 preDestroyFromXml, clazz.getName()));
397 }
398
399 if (context != null) {
400
401
402 Field[] fields = Introspection.getDeclaredFields(clazz);
403 for (Field field : fields) {
404 Resource resourceAnnotation;
405 Annotation ejbAnnotation;
406 Annotation webServiceRefAnnotation;
407 Annotation persistenceContextAnnotation;
408 Annotation persistenceUnitAnnotation;
409 String fieldName = field.getName();
410 if (injections != null && injections.containsKey(fieldName) && !injectionsMatchedToSetter.contains(fieldName)) {
411 annotations.add(new AnnotationCacheEntry(
412 fieldName, null,
413 injections.get(fieldName),
414 AnnotationCacheEntryType.FIELD));
415 } else if ((resourceAnnotation =
416 field.getAnnotation(Resource.class)) != null) {
417 annotations.add(new AnnotationCacheEntry(fieldName, null,
418 resourceAnnotation.name(), AnnotationCacheEntryType.FIELD));
419 } else if (EJB_PRESENT &&
420 (ejbAnnotation = field.getAnnotation(EJB.class)) != null) {
421 annotations.add(new AnnotationCacheEntry(fieldName, null,
422 ((EJB) ejbAnnotation).name(), AnnotationCacheEntryType.FIELD));
423 } else if (WS_PRESENT && (webServiceRefAnnotation =
424 field.getAnnotation(WebServiceRef.class)) != null) {
425 annotations.add(new AnnotationCacheEntry(fieldName, null,
426 ((WebServiceRef) webServiceRefAnnotation).name(),
427 AnnotationCacheEntryType.FIELD));
428 } else if (JPA_PRESENT && (persistenceContextAnnotation =
429 field.getAnnotation(PersistenceContext.class)) != null) {
430 annotations.add(new AnnotationCacheEntry(fieldName, null,
431 ((PersistenceContext) persistenceContextAnnotation).name(),
432 AnnotationCacheEntryType.FIELD));
433 } else if (JPA_PRESENT && (persistenceUnitAnnotation =
434 field.getAnnotation(PersistenceUnit.class)) != null) {
435 annotations.add(new AnnotationCacheEntry(fieldName, null,
436 ((PersistenceUnit) persistenceUnitAnnotation).name(),
437 AnnotationCacheEntryType.FIELD));
438 }
439 }
440 }
441
442 if (annotations.isEmpty()) {
443
444 annotationsArray = ANNOTATIONS_EMPTY;
445 } else {
446 annotationsArray = annotations.toArray(
447 new AnnotationCacheEntry[annotations.size()]);
448 }
449 synchronized (annotationCache) {
450 annotationCache.put(clazz, annotationsArray);
451 }
452 }
453 clazz = clazz.getSuperclass();
454 }
455 }
456
457
458
468 protected void processAnnotations(Object instance, Map<String, String> injections)
469 throws IllegalAccessException, InvocationTargetException, NamingException {
470
471 if (context == null) {
472
473 return;
474 }
475
476 Class<?> clazz = instance.getClass();
477
478 while (clazz != null) {
479 AnnotationCacheEntry[] annotations = annotationCache.get(clazz);
480 for (AnnotationCacheEntry entry : annotations) {
481 if (entry.getType() == AnnotationCacheEntryType.SETTER) {
482 lookupMethodResource(context, instance,
483 getMethod(clazz, entry),
484 entry.getName(), clazz);
485 } else if (entry.getType() == AnnotationCacheEntryType.FIELD) {
486 lookupFieldResource(context, instance,
487 getField(clazz, entry),
488 entry.getName(), clazz);
489 }
490 }
491 clazz = clazz.getSuperclass();
492 }
493 }
494
495
496
501 protected int getAnnotationCacheSize() {
502 return annotationCache.size();
503 }
504
505
506 protected Class<?> loadClassMaybePrivileged(final String className,
507 final ClassLoader classLoader) throws ClassNotFoundException {
508 Class<?> clazz;
509 if (SecurityUtil.isPackageProtectionEnabled()) {
510 try {
511 clazz = AccessController.doPrivileged(
512 new PrivilegedLoadClass(className, classLoader));
513 } catch (PrivilegedActionException e) {
514 Throwable t = e.getCause();
515 if (t instanceof ClassNotFoundException) {
516 throw (ClassNotFoundException) t;
517 }
518 throw new RuntimeException(t);
519 }
520 } else {
521 clazz = loadClass(className, classLoader);
522 }
523 checkAccess(clazz);
524 return clazz;
525 }
526
527 protected Class<?> loadClass(String className, ClassLoader classLoader)
528 throws ClassNotFoundException {
529 if (className.startsWith("org.apache.catalina")) {
530 return containerClassLoader.loadClass(className);
531 }
532 try {
533 Class<?> clazz = containerClassLoader.loadClass(className);
534 if (ContainerServlet.class.isAssignableFrom(clazz)) {
535 return clazz;
536 }
537 } catch (Throwable t) {
538 ExceptionUtils.handleThrowable(t);
539 }
540 return classLoader.loadClass(className);
541 }
542
543 private void checkAccess(Class<?> clazz) {
544 if (privileged) {
545 return;
546 }
547 if (ContainerServlet.class.isAssignableFrom(clazz)) {
548 throw new SecurityException(sm.getString(
549 "defaultInstanceManager.restrictedContainerServlet", clazz));
550 }
551 while (clazz != null) {
552 if (restrictedClasses.contains(clazz.getName())) {
553 throw new SecurityException(sm.getString(
554 "defaultInstanceManager.restrictedClass", clazz));
555 }
556 clazz = clazz.getSuperclass();
557 }
558 }
559
560
571 protected static void lookupFieldResource(Context context,
572 Object instance, Field field, String name, Class<?> clazz)
573 throws NamingException, IllegalAccessException {
574
575 Object lookedupResource;
576 boolean accessibility;
577
578 String normalizedName = normalize(name);
579
580 if ((normalizedName != null) && (normalizedName.length() > 0)) {
581 lookedupResource = context.lookup(normalizedName);
582 } else {
583 lookedupResource =
584 context.lookup(clazz.getName() + "/" + field.getName());
585 }
586
587 synchronized (field) {
588 accessibility = field.isAccessible();
589 field.setAccessible(true);
590 field.set(instance, lookedupResource);
591 field.setAccessible(accessibility);
592 }
593 }
594
595
608 protected static void lookupMethodResource(Context context,
609 Object instance, Method method, String name, Class<?> clazz)
610 throws NamingException, IllegalAccessException, InvocationTargetException {
611
612 if (!Introspection.isValidSetter(method)) {
613 throw new IllegalArgumentException(
614 sm.getString("defaultInstanceManager.invalidInjection"));
615 }
616
617 Object lookedupResource;
618 boolean accessibility;
619
620 String normalizedName = normalize(name);
621
622 if ((normalizedName != null) && (normalizedName.length() > 0)) {
623 lookedupResource = context.lookup(normalizedName);
624 } else {
625 lookedupResource = context.lookup(
626 clazz.getName() + "/" + Introspection.getPropertyName(method));
627 }
628
629 synchronized (method) {
630 accessibility = method.isAccessible();
631 method.setAccessible(true);
632 method.invoke(instance, lookedupResource);
633 method.setAccessible(accessibility);
634 }
635 }
636
637 private static void loadProperties(Set<String> classNames, String resourceName,
638 String messageKey, Log log) {
639 Properties properties = new Properties();
640 ClassLoader cl = DefaultInstanceManager.class.getClassLoader();
641 try (InputStream is = cl.getResourceAsStream(resourceName)) {
642 if (is == null) {
643 log.error(sm.getString(messageKey, resourceName));
644 } else {
645 properties.load(is);
646 }
647 } catch (IOException ioe) {
648 log.error(sm.getString(messageKey, resourceName), ioe);
649 }
650 if (properties.isEmpty()) {
651 return;
652 }
653 for (Map.Entry<Object, Object> e : properties.entrySet()) {
654 if ("restricted".equals(e.getValue())) {
655 classNames.add(e.getKey().toString());
656 } else {
657 log.warn(sm.getString(
658 "defaultInstanceManager.restrictedWrongValue",
659 resourceName, e.getKey(), e.getValue()));
660 }
661 }
662 }
663
664 private static String normalize(String jndiName){
665 if(jndiName != null && jndiName.startsWith("java:comp/env/")){
666 return jndiName.substring(14);
667 }
668 return jndiName;
669 }
670
671 private static Method getMethod(final Class<?> clazz,
672 final AnnotationCacheEntry entry) {
673 Method result = null;
674 if (Globals.IS_SECURITY_ENABLED) {
675 result = AccessController.doPrivileged(new PrivilegedGetMethod(clazz, entry));
676 } else {
677 try {
678 result = clazz.getDeclaredMethod(
679 entry.getAccessibleObjectName(), entry.getParamTypes());
680 } catch (NoSuchMethodException e) {
681
682 }
683 }
684 return result;
685 }
686
687 private static Field getField(final Class<?> clazz,
688 final AnnotationCacheEntry entry) {
689 Field result = null;
690 if (Globals.IS_SECURITY_ENABLED) {
691 result = AccessController.doPrivileged(new PrivilegedGetField(clazz, entry));
692 } else {
693 try {
694 result = clazz.getDeclaredField(entry.getAccessibleObjectName());
695 } catch (NoSuchFieldException e) {
696
697 }
698 }
699 return result;
700 }
701
702
703 private static Method findPostConstruct(Method currentPostConstruct,
704 String postConstructFromXml, Method method) {
705 return findLifecycleCallback(currentPostConstruct,
706 postConstructFromXml, method, PostConstruct.class);
707 }
708
709 private static Method findPreDestroy(Method currentPreDestroy,
710 String preDestroyFromXml, Method method) {
711 return findLifecycleCallback(currentPreDestroy,
712 preDestroyFromXml, method, PreDestroy.class);
713 }
714
715 private static Method findLifecycleCallback(Method currentMethod,
716 String methodNameFromXml, Method method,
717 Class<? extends Annotation> annotation) {
718 Method result = currentMethod;
719 if (methodNameFromXml != null) {
720 if (method.getName().equals(methodNameFromXml)) {
721 if (!Introspection.isValidLifecycleCallback(method)) {
722 throw new IllegalArgumentException(
723 "Invalid " + annotation.getName() + " annotation");
724 }
725 result = method;
726 }
727 } else {
728 if (method.isAnnotationPresent(annotation)) {
729 if (currentMethod != null || !Introspection.isValidLifecycleCallback(method)) {
730 throw new IllegalArgumentException(
731 "Invalid " + annotation.getName() + " annotation");
732 }
733 result = method;
734 }
735 }
736 return result;
737 }
738
739 private static final class AnnotationCacheEntry {
740 private final String accessibleObjectName;
741 private final Class<?>[] paramTypes;
742 private final String name;
743 private final AnnotationCacheEntryType type;
744
745 public AnnotationCacheEntry(String accessibleObjectName,
746 Class<?>[] paramTypes, String name,
747 AnnotationCacheEntryType type) {
748 this.accessibleObjectName = accessibleObjectName;
749 this.paramTypes = paramTypes;
750 this.name = name;
751 this.type = type;
752 }
753
754 public String getAccessibleObjectName() {
755 return accessibleObjectName;
756 }
757
758 public Class<?>[] getParamTypes() {
759 return paramTypes;
760 }
761
762 public String getName() {
763 return name;
764 }
765 public AnnotationCacheEntryType getType() {
766 return type;
767 }
768 }
769
770
771 private enum AnnotationCacheEntryType {
772 FIELD, SETTER, POST_CONSTRUCT, PRE_DESTROY
773 }
774
775
776 private static class PrivilegedGetField implements PrivilegedAction<Field> {
777
778 private final Class<?> clazz;
779 private final AnnotationCacheEntry entry;
780
781 public PrivilegedGetField(Class<?> clazz, AnnotationCacheEntry entry) {
782 this.clazz = clazz;
783 this.entry = entry;
784 }
785
786 @Override
787 public Field run() {
788 Field result = null;
789 try {
790 result = clazz.getDeclaredField(entry.getAccessibleObjectName());
791 } catch (NoSuchFieldException e) {
792
793 }
794 return result;
795 }
796 }
797
798
799 private static class PrivilegedGetMethod implements PrivilegedAction<Method> {
800
801 private final Class<?> clazz;
802 private final AnnotationCacheEntry entry;
803
804 public PrivilegedGetMethod(Class<?> clazz, AnnotationCacheEntry entry) {
805 this.clazz = clazz;
806 this.entry = entry;
807 }
808
809 @Override
810 public Method run() {
811 Method result = null;
812 try {
813 result = clazz.getDeclaredMethod(
814 entry.getAccessibleObjectName(), entry.getParamTypes());
815 } catch (NoSuchMethodException e) {
816
817 }
818 return result;
819 }
820 }
821
822
823 private class PrivilegedLoadClass implements PrivilegedExceptionAction<Class<?>> {
824
825 private final String className;
826 private final ClassLoader classLoader;
827
828 public PrivilegedLoadClass(String className, ClassLoader classLoader) {
829 this.className = className;
830 this.classLoader = classLoader;
831 }
832
833 @Override
834 public Class<?> run() throws Exception {
835 return loadClass(className, classLoader);
836 }
837 }
838 }
839