Author: markt Date: Mon Oct 27 06:24:06 2008 New Revision: 708168 URL: http://svn.apache.org/viewvc?rev=708168&view=rev Log: Fix https://issues.apache.org/bugzilla/show_bug.cgi?id=45285 Correctly handle annotations in parent classes Based on a patch by Florent BENOIT
Modified: tomcat/tc6.0.x/trunk/STATUS.txt tomcat/tc6.0.x/trunk/java/org/apache/catalina/util/DefaultAnnotationProcessor.java tomcat/tc6.0.x/trunk/webapps/docs/changelog.xml Modified: tomcat/tc6.0.x/trunk/STATUS.txt URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/STATUS.txt?rev=708168&r1=708167&r2=708168&view=diff ============================================================================== --- tomcat/tc6.0.x/trunk/STATUS.txt (original) +++ tomcat/tc6.0.x/trunk/STATUS.txt Mon Oct 27 06:24:06 2008 @@ -196,13 +196,6 @@ really old to me, so where would this come from ?) -1: -* Fix https://issues.apache.org/bugzilla/show_bug.cgi?id=45285 - Correctly handle annotations in parent classes - http://people.apache.org/~markt/patches/2008-10-20-bug45285-v2.patch - Based on a patch by Florent BENOIT - +1: markt, remm, fhanik - -1: - * Fix classcast exception upon shutdown(edgecase) http://svn.apache.org/viewvc?rev=706433&view=rev +1: fhanik Modified: tomcat/tc6.0.x/trunk/java/org/apache/catalina/util/DefaultAnnotationProcessor.java URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/catalina/util/DefaultAnnotationProcessor.java?rev=708168&r1=708167&r2=708168&view=diff ============================================================================== --- tomcat/tc6.0.x/trunk/java/org/apache/catalina/util/DefaultAnnotationProcessor.java (original) +++ tomcat/tc6.0.x/trunk/java/org/apache/catalina/util/DefaultAnnotationProcessor.java Mon Oct 27 06:24:06 2008 @@ -56,30 +56,35 @@ public void postConstruct(Object instance) throws IllegalAccessException, InvocationTargetException { - Method[] methods = instance.getClass().getDeclaredMethods(); - Method postConstruct = null; - for (int i = 0; i < methods.length; i++) { - if (methods[i].isAnnotationPresent(PostConstruct.class)) { - if ((postConstruct != null) - || (methods[i].getParameterTypes().length != 0) - || (Modifier.isStatic(methods[i].getModifiers())) - || (methods[i].getExceptionTypes().length > 0) - || (!methods[i].getReturnType().getName().equals("void"))) { - throw new IllegalArgumentException("Invalid PostConstruct annotation"); + Class<?> clazz = instance.getClass(); + + while (clazz != null) { + Method[] methods = clazz.getDeclaredMethods(); + Method postConstruct = null; + for (int i = 0; i < methods.length; i++) { + if (methods[i].isAnnotationPresent(PostConstruct.class)) { + if ((postConstruct != null) + || (methods[i].getParameterTypes().length != 0) + || (Modifier.isStatic(methods[i].getModifiers())) + || (methods[i].getExceptionTypes().length > 0) + || (!methods[i].getReturnType().getName().equals("void"))) { + throw new IllegalArgumentException("Invalid PostConstruct annotation"); + } + postConstruct = methods[i]; } - postConstruct = methods[i]; } - } - - // At the end the postconstruct annotated - // method is invoked - if (postConstruct != null) { - boolean accessibility = postConstruct.isAccessible(); - postConstruct.setAccessible(true); - postConstruct.invoke(instance); - postConstruct.setAccessible(accessibility); - } + + // At the end the postconstruct annotated + // method is invoked + if (postConstruct != null) { + boolean accessibility = postConstruct.isAccessible(); + postConstruct.setAccessible(true); + postConstruct.invoke(instance); + postConstruct.setAccessible(accessibility); + } + clazz = clazz.getSuperclass(); + } } @@ -89,30 +94,35 @@ public void preDestroy(Object instance) throws IllegalAccessException, InvocationTargetException { - Method[] methods = instance.getClass().getDeclaredMethods(); - Method preDestroy = null; - for (int i = 0; i < methods.length; i++) { - if (methods[i].isAnnotationPresent(PreDestroy.class)) { - if ((preDestroy != null) - || (methods[i].getParameterTypes().length != 0) - || (Modifier.isStatic(methods[i].getModifiers())) - || (methods[i].getExceptionTypes().length > 0) - || (!methods[i].getReturnType().getName().equals("void"))) { - throw new IllegalArgumentException("Invalid PreDestroy annotation"); + Class<?> clazz = instance.getClass(); + + while (clazz != null) { + Method[] methods = clazz.getDeclaredMethods(); + Method preDestroy = null; + for (int i = 0; i < methods.length; i++) { + if (methods[i].isAnnotationPresent(PreDestroy.class)) { + if ((preDestroy != null) + || (methods[i].getParameterTypes().length != 0) + || (Modifier.isStatic(methods[i].getModifiers())) + || (methods[i].getExceptionTypes().length > 0) + || (!methods[i].getReturnType().getName().equals("void"))) { + throw new IllegalArgumentException("Invalid PreDestroy annotation"); + } + preDestroy = methods[i]; } - preDestroy = methods[i]; } - } + + // At the end the postconstruct annotated + // method is invoked + if (preDestroy != null) { + boolean accessibility = preDestroy.isAccessible(); + preDestroy.setAccessible(true); + preDestroy.invoke(instance); + preDestroy.setAccessible(accessibility); + } - // At the end the postconstruct annotated - // method is invoked - if (preDestroy != null) { - boolean accessibility = preDestroy.isAccessible(); - preDestroy.setAccessible(true); - preDestroy.invoke(instance); - preDestroy.setAccessible(accessibility); + clazz = clazz.getSuperclass(); } - } @@ -131,58 +141,69 @@ while (clazz != null) { // Initialize fields annotations - Field[] fields = instance.getClass().getDeclaredFields(); + Field[] fields = clazz.getDeclaredFields(); for (int i = 0; i < fields.length; i++) { if (fields[i].isAnnotationPresent(Resource.class)) { - Resource annotation = (Resource) fields[i].getAnnotation(Resource.class); - lookupFieldResource(context, instance, fields[i], annotation.name()); + Resource annotation = + fields[i].getAnnotation(Resource.class); + lookupFieldResource(context, instance, fields[i], + annotation.name(), clazz); } if (fields[i].isAnnotationPresent(EJB.class)) { - EJB annotation = (EJB) fields[i].getAnnotation(EJB.class); - lookupFieldResource(context, instance, fields[i], annotation.name()); + EJB annotation = fields[i].getAnnotation(EJB.class); + lookupFieldResource(context, instance, fields[i], + annotation.name(), clazz); } if (fields[i].isAnnotationPresent(WebServiceRef.class)) { - WebServiceRef annotation = - (WebServiceRef) fields[i].getAnnotation(WebServiceRef.class); - lookupFieldResource(context, instance, fields[i], annotation.name()); + WebServiceRef annotation = + fields[i].getAnnotation(WebServiceRef.class); + lookupFieldResource(context, instance, fields[i], + annotation.name(), clazz); } if (fields[i].isAnnotationPresent(PersistenceContext.class)) { PersistenceContext annotation = - (PersistenceContext) fields[i].getAnnotation(PersistenceContext.class); - lookupFieldResource(context, instance, fields[i], annotation.name()); + fields[i].getAnnotation(PersistenceContext.class); + lookupFieldResource(context, instance, fields[i], + annotation.name(), clazz); } if (fields[i].isAnnotationPresent(PersistenceUnit.class)) { PersistenceUnit annotation = - (PersistenceUnit) fields[i].getAnnotation(PersistenceUnit.class); - lookupFieldResource(context, instance, fields[i], annotation.name()); + fields[i].getAnnotation(PersistenceUnit.class); + lookupFieldResource(context, instance, fields[i], + annotation.name(), clazz); } } // Initialize methods annotations - Method[] methods = instance.getClass().getDeclaredMethods(); + Method[] methods = clazz.getDeclaredMethods(); for (int i = 0; i < methods.length; i++) { if (methods[i].isAnnotationPresent(Resource.class)) { - Resource annotation = (Resource) methods[i].getAnnotation(Resource.class); - lookupMethodResource(context, instance, methods[i], annotation.name()); + Resource annotation = methods[i].getAnnotation(Resource.class); + lookupMethodResource(context, instance, methods[i], + annotation.name(), clazz); } if (methods[i].isAnnotationPresent(EJB.class)) { - EJB annotation = (EJB) methods[i].getAnnotation(EJB.class); - lookupMethodResource(context, instance, methods[i], annotation.name()); + EJB annotation = methods[i].getAnnotation(EJB.class); + lookupMethodResource(context, instance, methods[i], + annotation.name(), clazz); } if (methods[i].isAnnotationPresent(WebServiceRef.class)) { WebServiceRef annotation = - (WebServiceRef) methods[i].getAnnotation(WebServiceRef.class); - lookupMethodResource(context, instance, methods[i], annotation.name()); + methods[i].getAnnotation(WebServiceRef.class); + lookupMethodResource(context, instance, methods[i], + annotation.name(), clazz); } if (methods[i].isAnnotationPresent(PersistenceContext.class)) { PersistenceContext annotation = - (PersistenceContext) methods[i].getAnnotation(PersistenceContext.class); - lookupMethodResource(context, instance, methods[i], annotation.name()); + methods[i].getAnnotation(PersistenceContext.class); + lookupMethodResource(context, instance, methods[i], + annotation.name(), clazz); } if (methods[i].isAnnotationPresent(PersistenceUnit.class)) { PersistenceUnit annotation = - (PersistenceUnit) methods[i].getAnnotation(PersistenceUnit.class); - lookupMethodResource(context, instance, methods[i], annotation.name()); + methods[i].getAnnotation(PersistenceUnit.class); + lookupMethodResource(context, instance, methods[i], + annotation.name(), clazz); } } @@ -195,7 +216,7 @@ * Inject resources in specified field. */ protected static void lookupFieldResource(javax.naming.Context context, - Object instance, Field field, String name) + Object instance, Field field, String name, Class<?> clazz) throws NamingException, IllegalAccessException { Object lookedupResource = null; @@ -205,7 +226,8 @@ (name.length() > 0)) { lookedupResource = context.lookup(name); } else { - lookedupResource = context.lookup(instance.getClass().getName() + "/" + field.getName()); + lookedupResource = context.lookup( + clazz.getName() + "/" + field.getName()); } accessibility = field.isAccessible(); @@ -219,7 +241,7 @@ * Inject resources in specified method. */ protected static void lookupMethodResource(javax.naming.Context context, - Object instance, Method method, String name) + Object instance, Method method, String name, Class<?> clazz) throws NamingException, IllegalAccessException, InvocationTargetException { if (!method.getName().startsWith("set") @@ -235,8 +257,8 @@ (name.length() > 0)) { lookedupResource = context.lookup(name); } else { - lookedupResource = - context.lookup(instance.getClass().getName() + "/" + method.getName().substring(3)); + lookedupResource = context.lookup( + clazz.getName() + "/" + method.getName().substring(3)); } accessibility = method.isAccessible(); Modified: tomcat/tc6.0.x/trunk/webapps/docs/changelog.xml URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/webapps/docs/changelog.xml?rev=708168&r1=708167&r2=708168&view=diff ============================================================================== --- tomcat/tc6.0.x/trunk/webapps/docs/changelog.xml (original) +++ tomcat/tc6.0.x/trunk/webapps/docs/changelog.xml Mon Oct 27 06:24:06 2008 @@ -98,6 +98,10 @@ on a patch by Per Landberg. (markt) </fix> <fix> + <bug>45825</bug>: Correctly handle annotations in parent classes. Based + on a patch by Florent Benoit. (markt) + </fix> + <fix> <bug>45906</bug>: Further ETag handling improvements. Patch provided by Chris Hubick. (markt) </fix> --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]