You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by ma...@apache.org on 2012/03/27 21:20:10 UTC
svn commit: r1305965 -
/tomcat/trunk/java/org/apache/catalina/startup/WebAnnotationSet.java
Author: markt
Date: Tue Mar 27 19:20:10 2012
New Revision: 1305965
URL: http://svn.apache.org/viewvc?rev=1305965&view=rev
Log:
Fix https://issues.apache.org/bugzilla/show_bug.cgi?id=52974
Fix NameNotFoundException when field/method is annotated with @Resource annotation
Patch provided by Violet Agg.
Modified:
tomcat/trunk/java/org/apache/catalina/startup/WebAnnotationSet.java
Modified: tomcat/trunk/java/org/apache/catalina/startup/WebAnnotationSet.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/startup/WebAnnotationSet.java?rev=1305965&r1=1305964&r2=1305965&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/startup/WebAnnotationSet.java (original)
+++ tomcat/trunk/java/org/apache/catalina/startup/WebAnnotationSet.java Tue Mar 27 19:20:10 2012
@@ -19,6 +19,11 @@
package org.apache.catalina.startup;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
import javax.annotation.Resource;
import javax.annotation.Resources;
import javax.annotation.security.DeclareRoles;
@@ -26,7 +31,9 @@ import javax.annotation.security.RunAs;
import org.apache.catalina.Container;
import org.apache.catalina.Context;
+import org.apache.catalina.Globals;
import org.apache.catalina.Wrapper;
+import org.apache.catalina.core.DefaultInstanceManager;
import org.apache.catalina.deploy.ContextEnvironment;
import org.apache.catalina.deploy.ContextResource;
import org.apache.catalina.deploy.ContextResourceEnvRef;
@@ -44,6 +51,7 @@ import org.apache.catalina.deploy.Messag
public class WebAnnotationSet {
+ private static final String SEPARATOR = "/";
// --------------------------------------------------------- Public Methods
@@ -68,9 +76,17 @@ public class WebAnnotationSet {
* Process the annotations for the listeners.
*/
protected static void loadApplicationListenerAnnotations(Context context) {
+ Class<?> classClass = null;
String[] applicationListeners = context.findApplicationListeners();
for (int i = 0; i < applicationListeners.length; i++) {
- loadClassAnnotation(context, applicationListeners[i]);
+ classClass = loadClass(context, applicationListeners[i]);
+ if (classClass == null) {
+ continue;
+ }
+
+ loadClassAnnotation(context, classClass);
+ loadFieldsAnnotation(context, classClass);
+ loadMethodsAnnotation(context, classClass);
}
}
@@ -79,9 +95,17 @@ public class WebAnnotationSet {
* Process the annotations for the filters.
*/
protected static void loadApplicationFilterAnnotations(Context context) {
+ Class<?> classClass = null;
FilterDef[] filterDefs = context.findFilterDefs();
for (int i = 0; i < filterDefs.length; i++) {
- loadClassAnnotation(context, (filterDefs[i]).getFilterClass());
+ classClass = loadClass(context, (filterDefs[i]).getFilterClass());
+ if (classClass == null) {
+ continue;
+ }
+
+ loadClassAnnotation(context, classClass);
+ loadFieldsAnnotation(context, classClass);
+ loadMethodsAnnotation(context, classClass);
}
}
@@ -91,7 +115,6 @@ public class WebAnnotationSet {
*/
protected static void loadApplicationServletAnnotations(Context context) {
- ClassLoader classLoader = context.getLoader().getClassLoader();
Wrapper wrapper = null;
Class<?> classClass = null;
@@ -104,19 +127,15 @@ public class WebAnnotationSet {
continue;
}
- try {
- classClass = classLoader.loadClass(wrapper.getServletClass());
- } catch (ClassNotFoundException e) {
- // We do nothing
- } catch (NoClassDefFoundError e) {
- // We do nothing
- }
-
+ classClass = loadClass(context, wrapper.getServletClass());
if (classClass == null) {
continue;
}
- loadClassAnnotation(context, wrapper.getServletClass());
+ loadClassAnnotation(context, classClass);
+ loadFieldsAnnotation(context, classClass);
+ loadMethodsAnnotation(context, classClass);
+
/* Process RunAs annotation which can be only on servlets.
* Ref JSR 250, equivalent to the run-as element in
* the deployment descriptor
@@ -135,25 +154,9 @@ public class WebAnnotationSet {
/**
* Process the annotations on a context for a given className.
*/
- protected static void loadClassAnnotation(Context context, String fileString) {
-
- ClassLoader classLoader = context.getLoader().getClassLoader();
- Class<?> classClass = null;
-
- try {
- classClass = classLoader.loadClass(fileString);
- } catch (ClassNotFoundException e) {
- // We do nothing
- } catch (NoClassDefFoundError e) {
- // We do nothing
- }
-
- if (classClass == null) {
- return;
- }
-
+ protected static void loadClassAnnotation(Context context,
+ Class<?> classClass) {
// Initialize the annotations
-
if (classClass.isAnnotationPresent(Resource.class)) {
Resource annotation = classClass.getAnnotation(Resource.class);
addResource(context, annotation);
@@ -245,11 +248,49 @@ public class WebAnnotationSet {
context.addSecurityRole(annotation.value()[i]);
}
}
+ }
+ protected static void loadFieldsAnnotation(Context context,
+ Class<?> classClass) {
+ // Initialize the annotations
+ Field[] fields = getDeclaredFields(classClass);
+ if (fields != null && fields.length > 0) {
+ for (Field field : fields) {
+ if (field.isAnnotationPresent(Resource.class)) {
+ Resource annotation = field.getAnnotation(Resource.class);
+ String defaultName =
+ classClass.getName() + SEPARATOR + field.getName();
+ String defaultType = field.getType().getCanonicalName();
+ addResource(context, annotation, defaultName, defaultType);
+ }
+ }
+ }
}
+ protected static void loadMethodsAnnotation(Context context,
+ Class<?> classClass) {
+ // Initialize the annotations
+ Method[] methods = getDeclaredMethods(classClass);
+ if (methods != null && methods.length > 0) {
+ for (Method method : methods) {
+ if (method.isAnnotationPresent(Resource.class)) {
+ Resource annotation = method.getAnnotation(Resource.class);
+
+ checkBeanNamingConventions(method);
+
+ String defaultName = classClass.getName() + SEPARATOR +
+ DefaultInstanceManager.getName(method);
+
+ String defaultType =
+ (method.getParameterTypes()[0]).getCanonicalName();
+ addResource(context, annotation, defaultName, defaultType);
+ }
+ }
+ }
+ }
+
/**
* Process a Resource annotation to set up a Resource.
* Ref JSR 250, equivalent to the resource-ref,
@@ -257,22 +298,29 @@ public class WebAnnotationSet {
* or service-ref element in the deployment descriptor.
*/
protected static void addResource(Context context, Resource annotation) {
+ addResource(context, annotation, null, null);
+ }
- if (annotation.type().getCanonicalName().equals("java.lang.String") ||
- annotation.type().getCanonicalName().equals("java.lang.Character") ||
- annotation.type().getCanonicalName().equals("java.lang.Integer") ||
- annotation.type().getCanonicalName().equals("java.lang.Boolean") ||
- annotation.type().getCanonicalName().equals("java.lang.Double") ||
- annotation.type().getCanonicalName().equals("java.lang.Byte") ||
- annotation.type().getCanonicalName().equals("java.lang.Short") ||
- annotation.type().getCanonicalName().equals("java.lang.Long") ||
- annotation.type().getCanonicalName().equals("java.lang.Float")) {
+ protected static void addResource(Context context, Resource annotation,
+ String defaultName, String defaultType) {
+ String name = getName(annotation, defaultName);
+ String type = getType(annotation, defaultType);
+
+ if (type.equals("java.lang.String") ||
+ type.equals("java.lang.Character") ||
+ type.equals("java.lang.Integer") ||
+ type.equals("java.lang.Boolean") ||
+ type.equals("java.lang.Double") ||
+ type.equals("java.lang.Byte") ||
+ type.equals("java.lang.Short") ||
+ type.equals("java.lang.Long") ||
+ type.equals("java.lang.Float")) {
// env-ref element
ContextEnvironment resource = new ContextEnvironment();
- resource.setName(annotation.name());
- resource.setType(annotation.type().getCanonicalName());
+ resource.setName(name);
+ resource.setType(type);
resource.setDescription(annotation.description());
@@ -280,37 +328,34 @@ public class WebAnnotationSet {
context.getNamingResources().addEnvironment(resource);
- } else if (annotation.type().getCanonicalName().equals("javax.xml.rpc.Service")) {
+ } else if (type.equals("javax.xml.rpc.Service")) {
// service-ref element
ContextService service = new ContextService();
- service.setName(annotation.name());
+ service.setName(name);
service.setWsdlfile(annotation.mappedName());
- service.setType(annotation.type().getCanonicalName());
+ service.setType(type);
service.setDescription(annotation.description());
context.getNamingResources().addService(service);
- } else if (annotation.type().getCanonicalName().equals("javax.sql.DataSource") ||
- annotation.type().getCanonicalName().equals("javax.jms.ConnectionFactory") ||
- annotation.type().getCanonicalName()
- .equals("javax.jms.QueueConnectionFactory") ||
- annotation.type().getCanonicalName()
- .equals("javax.jms.TopicConnectionFactory") ||
- annotation.type().getCanonicalName().equals("javax.mail.Session") ||
- annotation.type().getCanonicalName().equals("java.net.URL") ||
- annotation.type().getCanonicalName()
- .equals("javax.resource.cci.ConnectionFactory") ||
- annotation.type().getCanonicalName().equals("org.omg.CORBA_2_3.ORB") ||
- annotation.type().getCanonicalName().endsWith("ConnectionFactory")) {
+ } else if (type.equals("javax.sql.DataSource") ||
+ type.equals("javax.jms.ConnectionFactory") ||
+ type.equals("javax.jms.QueueConnectionFactory") ||
+ type.equals("javax.jms.TopicConnectionFactory") ||
+ type.equals("javax.mail.Session") ||
+ type.equals("java.net.URL") ||
+ type.equals("javax.resource.cci.ConnectionFactory") ||
+ type.equals("org.omg.CORBA_2_3.ORB") ||
+ type.endsWith("ConnectionFactory")) {
// resource-ref element
ContextResource resource = new ContextResource();
- resource.setName(annotation.name());
- resource.setType(annotation.type().getCanonicalName());
+ resource.setName(name);
+ resource.setType(type);
if (annotation.authenticationType()
== Resource.AuthenticationType.CONTAINER) {
@@ -327,31 +372,29 @@ public class WebAnnotationSet {
context.getNamingResources().addResource(resource);
- } else if (annotation.type().getCanonicalName().equals("javax.jms.Queue") ||
- annotation.type().getCanonicalName().equals("javax.jms.Topic")) {
+ } else if (type.equals("javax.jms.Queue") ||
+ type.equals("javax.jms.Topic")) {
// message-destination-ref
MessageDestinationRef resource = new MessageDestinationRef();
- resource.setName(annotation.name());
- resource.setType(annotation.type().getCanonicalName());
+ resource.setName(name);
+ resource.setType(type);
resource.setUsage(annotation.mappedName());
resource.setDescription(annotation.description());
context.getNamingResources().addMessageDestinationRef(resource);
- } else if (annotation.type().getCanonicalName()
- .equals("javax.resource.cci.InteractionSpec") ||
- annotation.type().getCanonicalName()
- .equals("javax.transaction.UserTransaction") ||
+ } else if (type.equals("javax.resource.cci.InteractionSpec") ||
+ type.equals("javax.transaction.UserTransaction") ||
true) {
// resource-env-ref
ContextResourceEnvRef resource = new ContextResourceEnvRef();
- resource.setName(annotation.name());
- resource.setType(annotation.type().getCanonicalName());
+ resource.setName(name);
+ resource.setType(type);
resource.setProperty("mappedName", annotation.mappedName());
resource.setDescription(annotation.description());
@@ -359,9 +402,87 @@ public class WebAnnotationSet {
context.getNamingResources().addResourceEnvRef(resource);
}
+ }
+
+
+ private static void checkBeanNamingConventions(Method method) {
+ if (!method.getName().startsWith("set")
+ || method.getName().length() < 4
+ || method.getParameterTypes().length != 1
+ || !method.getReturnType().getName().equals("void")) {
+ throw new IllegalArgumentException("Invalid method resource injection annotation.");
+ }
+ }
+
+
+ private static String getType(Resource annotation, String defaultType) {
+ String type = annotation.type().getCanonicalName();
+ if (type == null || type.equals("java.lang.Object")) {
+ if (defaultType != null) {
+ type = defaultType;
+ }
+ }
+ return type;
+ }
+
+
+ private static String getName(Resource annotation, String defaultName) {
+ String name = annotation.name();
+ if (name == null || name.equals("")) {
+ if (defaultName != null) {
+ name = defaultName;
+ }
+ }
+ return name;
+ }
+
+
+ private static Field[] getDeclaredFields(Class<?> classClass) {
+ Field[] fields = null;
+ if (Globals.IS_SECURITY_ENABLED) {
+ final Class<?> clazz = classClass;
+ fields = AccessController.doPrivileged(
+ new PrivilegedAction<Field[]>(){
+ @Override
+ public Field[] run(){
+ return clazz.getDeclaredFields();
+ }
+ });
+ } else {
+ fields = classClass.getDeclaredFields();
+ }
+ return fields;
+ }
+ private static Method[] getDeclaredMethods(Class<?> classClass) {
+ Method[] methods = null;
+ if (Globals.IS_SECURITY_ENABLED) {
+ final Class<?> clazz = classClass;
+ methods = AccessController.doPrivileged(
+ new PrivilegedAction<Method[]>(){
+ @Override
+ public Method[] run(){
+ return clazz.getDeclaredMethods();
+ }
+ });
+ } else {
+ methods = classClass.getDeclaredMethods();
+ }
+ return methods;
}
+ private static Class<?> loadClass(Context context, String fileString) {
+ ClassLoader classLoader = context.getLoader().getClassLoader();
+ Class<?> classClass = null;
+ try {
+ classClass = classLoader.loadClass(fileString);
+ } catch (ClassNotFoundException e) {
+ // We do nothing
+ } catch (NoClassDefFoundError e) {
+ // We do nothing
+ }
+ return classClass;
+ }
}
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org