Author: markt
Date: Sat Jun  2 21:29:30 2012
New Revision: 1345588

URL: http://svn.apache.org/viewvc?rev=1345588&view=rev
Log:
Fix https://issues.apache.org/bugzilla/show_bug.cgi?id=53333
Validate JNDI resource types against injection target types and use target 
types when no type is specified for the resource.
Based on a patch by Violeta Georgieva.

Added:
    tomcat/tc7.0.x/trunk/java/org/apache/catalina/util/Introspection.java
      - copied unchanged from r1345367, 
tomcat/trunk/java/org/apache/catalina/util/Introspection.java
Modified:
    tomcat/tc7.0.x/trunk/   (props changed)
    
tomcat/tc7.0.x/trunk/java/org/apache/catalina/core/DefaultInstanceManager.java
    tomcat/tc7.0.x/trunk/java/org/apache/catalina/core/LocalStrings.properties
    tomcat/tc7.0.x/trunk/java/org/apache/catalina/deploy/LocalStrings.properties
    tomcat/tc7.0.x/trunk/java/org/apache/catalina/deploy/NamingResources.java
    tomcat/tc7.0.x/trunk/java/org/apache/catalina/startup/ContextConfig.java
    
tomcat/tc7.0.x/trunk/java/org/apache/catalina/startup/LocalStrings.properties
    tomcat/tc7.0.x/trunk/java/org/apache/catalina/startup/WebAnnotationSet.java
    tomcat/tc7.0.x/trunk/java/org/apache/catalina/util/LocalStrings.properties
    tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml

Propchange: tomcat/tc7.0.x/trunk/
------------------------------------------------------------------------------
  Merged /tomcat/trunk:r1345325,1345367,1345580,1345582

Modified: 
tomcat/tc7.0.x/trunk/java/org/apache/catalina/core/DefaultInstanceManager.java
URL: 
http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/catalina/core/DefaultInstanceManager.java?rev=1345588&r1=1345587&r2=1345588&view=diff
==============================================================================
--- 
tomcat/tc7.0.x/trunk/java/org/apache/catalina/core/DefaultInstanceManager.java 
(original)
+++ 
tomcat/tc7.0.x/trunk/java/org/apache/catalina/core/DefaultInstanceManager.java 
Sat Jun  2 21:29:30 2012
@@ -14,11 +14,8 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
-
 package org.apache.catalina.core;
 
-
 import java.beans.Introspector;
 import java.io.IOException;
 import java.io.InputStream;
@@ -52,6 +49,7 @@ import javax.xml.ws.WebServiceRef;
 import org.apache.catalina.ContainerServlet;
 import org.apache.catalina.Globals;
 import org.apache.catalina.security.SecurityUtil;
+import org.apache.catalina.util.Introspection;
 import org.apache.tomcat.InstanceManager;
 import org.apache.tomcat.util.ExceptionUtils;
 import org.apache.tomcat.util.res.StringManager;
@@ -61,6 +59,16 @@ import org.apache.tomcat.util.res.String
  */
 public class DefaultInstanceManager implements InstanceManager {
 
+    // Used when there are no annotations in a class
+    private static final AnnotationCacheEntry[] ANNOTATIONS_EMPTY
+        = new AnnotationCacheEntry[0];
+
+    /**
+     * The string manager for this package.
+     */
+    protected static final StringManager sm =
+        StringManager.getManager(Constants.Package);
+
     private final Context context;
     private final Map<String, Map<String, String>> injectionMap;
     protected final ClassLoader classLoader;
@@ -73,10 +81,6 @@ public class DefaultInstanceManager impl
     private final Map<Class<?>, AnnotationCacheEntry[]> annotationCache =
         new WeakHashMap<Class<?>, AnnotationCacheEntry[]>();
 
-    // Used when there are no annotations in a class
-    private static final AnnotationCacheEntry[] ANNOTATIONS_EMPTY
-        = new AnnotationCacheEntry[0];
-
     public DefaultInstanceManager(Context context, Map<String, Map<String, 
String>> injectionMap, org.apache.catalina.Context catalinaContext, ClassLoader 
containerClassLoader) {
         classLoader = catalinaContext.getLoader().getClassLoader();
         privileged = catalinaContext.getPrivileged();
@@ -286,19 +290,7 @@ public class DefaultInstanceManager impl
                 if (context != null) {
                     // Initialize fields annotations for resource injection if
                     // JNDI is enabled
-                    Field[] fields = null;
-                    if (Globals.IS_SECURITY_ENABLED) {
-                        final Class<?> clazz2 = clazz;
-                        fields = AccessController.doPrivileged(
-                                new PrivilegedAction<Field[]>(){
-                            @Override
-                            public Field[] run(){
-                                return clazz2.getDeclaredFields();
-                            }
-                        });
-                    } else {
-                        fields = clazz.getDeclaredFields();
-                    }
+                    Field[] fields = Introspection.getDeclaredFields(clazz);
                     for (Field field : fields) {
                         if (injections != null && 
injections.containsKey(field.getName())) {
                             annotations.add(new AnnotationCacheEntry(
@@ -338,30 +330,15 @@ public class DefaultInstanceManager impl
                 }
 
                 // Initialize methods annotations
-                Method[] methods = null;
-                if (Globals.IS_SECURITY_ENABLED) {
-                    final Class<?> clazz2 = clazz;
-                    methods = AccessController.doPrivileged(
-                            new PrivilegedAction<Method[]>(){
-                        @Override
-                        public Method[] run(){
-                            return clazz2.getDeclaredMethods();
-                        }
-                    });
-                } else {
-                    methods = clazz.getDeclaredMethods();
-                }
+                Method[] methods = Introspection.getDeclaredMethods(clazz);
                 Method postConstruct = null;
                 Method preDestroy = null;
                 for (Method method : methods) {
-                    String methodName = method.getName();
                     if (context != null) {
                         // Resource injection only if JNDI is enabled
-                        if (injections != null && methodName.startsWith("set")
-                                && methodName.length() > 3
-                                && method.getParameterTypes().length == 1
-                                && 
method.getReturnType().getName().equals("void")) {
-                            String fieldName = getName(method);
+                        if (injections != null &&
+                                Introspection.isValidSetter(method)) {
+                            String fieldName = Introspection.getName(method);
                             if (injections.containsKey(fieldName)) {
                                 annotations.add(new AnnotationCacheEntry(
                                         method.getName(),
@@ -634,11 +611,9 @@ public class DefaultInstanceManager impl
             Object instance, Method method, String name, Class<?> clazz)
             throws NamingException, IllegalAccessException, 
InvocationTargetException {
 
-        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");
+        if (!Introspection.isValidSetter(method)) {
+            throw new IllegalArgumentException(
+                    sm.getString("defaultInstanceManager.invalidInjection"));
         }
 
         Object lookedupResource;
@@ -650,7 +625,7 @@ public class DefaultInstanceManager impl
             lookedupResource = context.lookup(normalizedName);
         } else {
             lookedupResource = context.lookup(
-                    clazz.getName() + "/" + getName(method));
+                    clazz.getName() + "/" + Introspection.getName(method));
         }
 
         synchronized (method) {
@@ -661,6 +636,7 @@ public class DefaultInstanceManager impl
         }
     }
 
+    @Deprecated
     public static String getName(Method setter) {
         // Note: method signature has already been checked for correctness.
         // The method name always starts with "set".

Modified: 
tomcat/tc7.0.x/trunk/java/org/apache/catalina/core/LocalStrings.properties
URL: 
http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/catalina/core/LocalStrings.properties?rev=1345588&r1=1345587&r2=1345588&view=diff
==============================================================================
--- tomcat/tc7.0.x/trunk/java/org/apache/catalina/core/LocalStrings.properties 
(original)
+++ tomcat/tc7.0.x/trunk/java/org/apache/catalina/core/LocalStrings.properties 
Sat Jun  2 21:29:30 2012
@@ -75,6 +75,7 @@ containerBase.backgroundProcess.loader=E
 containerBase.backgroundProcess.manager=Exception processing manager {0} 
background process
 containerBase.backgroundProcess.realm=Exception processing realm {0} 
background process
 containerBase.backgroundProcess.valve=Exception processing valve {0} 
background process
+defaultInstanceManager.invalidInjection=Invalid method resource injection 
annotation
 fastEngineMapper.alreadyStarted=FastEngineMapper {0} has already been started
 fastEngineMapper.notStarted=FastEngineMapper {0} has not yet been started
 filterChain.filter=Filter execution threw an exception

Modified: 
tomcat/tc7.0.x/trunk/java/org/apache/catalina/deploy/LocalStrings.properties
URL: 
http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/catalina/deploy/LocalStrings.properties?rev=1345588&r1=1345587&r2=1345588&view=diff
==============================================================================
--- 
tomcat/tc7.0.x/trunk/java/org/apache/catalina/deploy/LocalStrings.properties 
(original)
+++ 
tomcat/tc7.0.x/trunk/java/org/apache/catalina/deploy/LocalStrings.properties 
Sat Jun  2 21:29:30 2012
@@ -50,3 +50,4 @@ namingResources.cleanupNoContext=Failed 
 namingResources.cleanupNoResource=Failed to retrieve JNDI resource [{0}] for 
container [{1}] so no cleanup was performed for that resource
 namingResources.mbeanCreateFail=Failed to create MBean for naming resource 
[{0}]
 namingResources.mbeanDestroyFail=Failed to destroy MBean for naming resource 
[{0}]
+namingResources.resourceTypeFail=The JNDI resource named [{0}] is of type 
[{1}] but the type is inconsistent with the type(s) of the injection target(s) 
configured for that resource
\ No newline at end of file

Modified: 
tomcat/tc7.0.x/trunk/java/org/apache/catalina/deploy/NamingResources.java
URL: 
http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/catalina/deploy/NamingResources.java?rev=1345588&r1=1345587&r2=1345588&view=diff
==============================================================================
--- tomcat/tc7.0.x/trunk/java/org/apache/catalina/deploy/NamingResources.java 
(original)
+++ tomcat/tc7.0.x/trunk/java/org/apache/catalina/deploy/NamingResources.java 
Sat Jun  2 21:29:30 2012
@@ -14,18 +14,17 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
-
 package org.apache.catalina.deploy;
 
-
 import java.beans.PropertyChangeListener;
 import java.beans.PropertyChangeSupport;
 import java.io.Serializable;
+import java.lang.reflect.Field;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.util.HashMap;
-import java.util.Hashtable;
+import java.util.HashSet;
+import java.util.Set;
 
 import javax.naming.NamingException;
 
@@ -36,6 +35,7 @@ import org.apache.catalina.LifecycleExce
 import org.apache.catalina.LifecycleState;
 import org.apache.catalina.Server;
 import org.apache.catalina.mbeans.MBeanUtils;
+import org.apache.catalina.util.Introspection;
 import org.apache.catalina.util.LifecycleMBeanBase;
 import org.apache.juli.logging.Log;
 import org.apache.juli.logging.LogFactory;
@@ -84,11 +84,9 @@ public class NamingResources extends Lif
 
 
     /**
-     * List of naming entries, keyed by name. The value is the entry type, as
-     * declared by the user.
+     * Set of naming entries, keyed by name.
      */
-    private Hashtable<String, String> entries =
-        new Hashtable<String, String>();
+    private Set<String> entries = new HashSet<String>();
 
 
     /**
@@ -204,10 +202,10 @@ public class NamingResources extends Lif
      */
     public void addEjb(ContextEjb ejb) {
 
-        if (entries.containsKey(ejb.getName())) {
+        if (entries.contains(ejb.getName())) {
             return;
         } else {
-            entries.put(ejb.getName(), ejb.getType());
+            entries.add(ejb.getName());
         }
 
         synchronized (ejbs) {
@@ -226,7 +224,7 @@ public class NamingResources extends Lif
      */
     public void addEnvironment(ContextEnvironment environment) {
 
-        if (entries.containsKey(environment.getName())) {
+        if (entries.contains(environment.getName())) {
             ContextEnvironment ce = findEnvironment(environment.getName());
             ContextResourceLink rl = findResourceLink(environment.getName());
             if (ce != null) {
@@ -251,7 +249,13 @@ public class NamingResources extends Lif
             }
         }
         
-        entries.put(environment.getName(), environment.getType());
+        if (!checkResourceType(environment)) {
+            throw new IllegalArgumentException(sm.getString(
+                    "namingResources.resourceTypeFail", environment.getName(),
+                    environment.getType()));
+        }
+
+        entries.add(environment.getName());
 
         synchronized (envs) {
             environment.setNamingResources(this);
@@ -292,10 +296,10 @@ public class NamingResources extends Lif
      */
     public void addLocalEjb(ContextLocalEjb ejb) {
 
-        if (entries.containsKey(ejb.getName())) {
+        if (entries.contains(ejb.getName())) {
             return;
         } else {
-            entries.put(ejb.getName(), ejb.getType());
+            entries.add(ejb.getName());
         }
 
         synchronized (localEjbs) {
@@ -314,10 +318,15 @@ public class NamingResources extends Lif
      */
     public void addMessageDestinationRef(MessageDestinationRef mdr) {
 
-        if (entries.containsKey(mdr.getName())) {
+        if (entries.contains(mdr.getName())) {
             return;
         } else {
-            entries.put(mdr.getName(), mdr.getType());
+            if (!checkResourceType(mdr)) {
+                throw new IllegalArgumentException(sm.getString(
+                        "namingResources.resourceTypeFail", mdr.getName(),
+                        mdr.getType()));
+            }
+            entries.add(mdr.getName());
         }
 
         synchronized (mdrs) {
@@ -348,10 +357,15 @@ public class NamingResources extends Lif
      */
     public void addResource(ContextResource resource) {
 
-        if (entries.containsKey(resource.getName())) {
+        if (entries.contains(resource.getName())) {
             return;
         } else {
-            entries.put(resource.getName(), resource.getType());
+            if (!checkResourceType(resource)) {
+                throw new IllegalArgumentException(sm.getString(
+                        "namingResources.resourceTypeFail", resource.getName(),
+                        resource.getType()));
+            }
+            entries.add(resource.getName());
         }
 
         synchronized (resources) {
@@ -379,10 +393,14 @@ public class NamingResources extends Lif
      */
     public void addResourceEnvRef(ContextResourceEnvRef resource) {
 
-        if (entries.containsKey(resource.getName())) {
+        if (entries.contains(resource.getName())) {
             return;
         } else {
-            entries.put(resource.getName(), resource.getType());
+            if (!checkResourceType(resource)) {
+                throw new IllegalArgumentException(sm.getString(
+                        "namingResources.resourceTypeFail", resource.getName(),
+                        resource.getType()));
+            }            entries.add(resource.getName());
         }
 
         synchronized (resourceEnvRefs) {
@@ -401,14 +419,10 @@ public class NamingResources extends Lif
      */
     public void addResourceLink(ContextResourceLink resourceLink) {
 
-        if (entries.containsKey(resourceLink.getName())) {
+        if (entries.contains(resourceLink.getName())) {
             return;
         } else {
-            String value = resourceLink.getType();
-            if (value == null) {
-                value = "";
-            }
-            entries.put(resourceLink.getName(), value);
+            entries.add(resourceLink.getName());
         }
 
         synchronized (resourceLinks) {
@@ -436,14 +450,10 @@ public class NamingResources extends Lif
      */
     public void addService(ContextService service) {
 
-        if (entries.containsKey(service.getName())) {
+        if (entries.contains(service.getName())) {
             return;
         } else {
-            String value = service.getType();
-            if (value == null) {
-                value = "";
-            }
-            entries.put(service.getName(), value);
+            entries.add(service.getName());
         }
         
         synchronized (services) {
@@ -697,7 +707,7 @@ public class NamingResources extends Lif
     @Deprecated
     public boolean exists(String name) {
 
-        return (entries.containsKey(name));
+        return (entries.contains(name));
 
     }
 
@@ -1104,4 +1114,147 @@ public class NamingResources extends Lif
         // Server or just unknown
         return "type=NamingResources";
     }
+
+    /**
+     * Checks that the configuration of the type for the specified resource is
+     * consistent with any injection targets and if the type is not specified,
+     * tries to configure the type based on the injection targets
+     *
+     * @param resource  The resource to check
+     *
+     * @return  <code>true</code> if the type for the resource is now valid (if
+     *          previously <code>null</code> this means it is now set) or
+     *          <code>false</code> if the current resource type is inconsistent
+     *          with the injection targets and/or cannot be determined
+     */
+    private boolean checkResourceType(ResourceBase resource) {
+        if (!(container instanceof Context)) {
+            // Only Context's will have injection targets
+            return true;
+        }
+
+        if (resource.getInjectionTargets() == null ||
+                resource.getInjectionTargets().size() == 0) {
+            // No injection targets so use the defined type for the resource
+            return true;
+        }
+
+        Context context = (Context) container;
+
+        String typeName = resource.getType();
+        Class<?> typeClass = null;
+        if (typeName != null) {
+            typeClass = Introspection.loadClass(context, typeName);
+            if (typeClass == null) {
+                // Can't load the type - will trigger a failure later so don't
+                // fail here
+                return true;
+            }
+        }
+
+        Class<?> injectionClass = getInjectionTargetType(context, resource);
+        if (injectionClass == null) {
+            // Indicates that a compatible type could not be identified that
+            // worked for all injection targets
+            return false;
+        }
+
+        if (typeClass == null) {
+                // Only injectionTarget defined - use it
+                resource.setType(injectionClass.getCanonicalName());
+                return true;
+        } else {
+            return injectionClass.isAssignableFrom(typeClass);
+        }
+    }
+
+    private Class<?> getInjectionTargetType(Context context,
+            ResourceBase resource) {
+
+        Class<?> result = null;
+
+        for (InjectionTarget injectionTarget : resource.getInjectionTargets()) 
{
+            Class<?> clazz = Introspection.loadClass(
+                    context, injectionTarget.getTargetClass());
+            if (clazz == null) {
+                // Can't load class - therefore ignore this target
+                continue;
+            }
+
+            // Look for a match
+            String targetName = injectionTarget.getTargetName();
+            // Look for a setter match first
+            Class<?> targetType = getSetterType(clazz, targetName);
+            if (targetType == null) {
+                // Try a field match if no setter match
+                targetType = getFieldType(clazz,targetName);
+            }
+            if (targetType == null) {
+                // No match - ignore this injection target
+                continue;
+            }
+            targetType = convertPrimitiveType(targetType);
+
+            // Figure out the common type - if there is one
+            if (result == null) {
+                result = targetType;
+            } else if (targetType.isAssignableFrom(result)) {
+                // NO-OP - This will work
+            } else if (result.isAssignableFrom(targetType)) {
+                // Need to use more specific type
+                result = targetType;
+            } else {
+                // Incompatible types
+                return null;
+            }
+        }
+        return result;
+    }
+
+    private Class<?> getSetterType(Class<?> clazz, String name) {
+        Method[] methods = Introspection.getDeclaredMethods(clazz);
+        if (methods != null && methods.length > 0) {
+            for (Method method : methods) {
+                if (Introspection.isValidSetter(method) &&
+                        Introspection.getName(method).equals(name)) {
+                    return method.getParameterTypes()[0];
+                }
+            }
+        }
+        return null;
+    }
+
+    private Class<?> getFieldType(Class<?> clazz, String name) {
+        Field[] fields = Introspection.getDeclaredFields(clazz);
+        if (fields != null && fields.length > 0) {
+            for (Field field : fields) {
+                if (field.getName().equals(name)) {
+                    return field.getType();
+                }
+            }
+        }
+        return null;
+    }
+
+    private Class<?> convertPrimitiveType(Class<?> clazz) {
+        if (clazz.equals(char.class)) {
+            return Character.class;
+        } else if (clazz.equals(int.class)) {
+            return Integer.class;
+        } else if (clazz.equals(boolean.class)) {
+            return Boolean.class;
+        } else if (clazz.equals(double.class)) {
+            return Double.class;
+        } else if (clazz.equals(byte.class)) {
+            return Byte.class;
+        } else if (clazz.equals(short.class)) {
+            return Short.class;
+        } else if (clazz.equals(long.class)) {
+            return Long.class;
+        } else if (clazz.equals(float.class)) {
+            return Float.class;
+        } else {
+            return clazz;
+        }
+    }
 }

Modified: 
tomcat/tc7.0.x/trunk/java/org/apache/catalina/startup/ContextConfig.java
URL: 
http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/catalina/startup/ContextConfig.java?rev=1345588&r1=1345587&r2=1345588&view=diff
==============================================================================
--- tomcat/tc7.0.x/trunk/java/org/apache/catalina/startup/ContextConfig.java 
(original)
+++ tomcat/tc7.0.x/trunk/java/org/apache/catalina/startup/ContextConfig.java 
Sat Jun  2 21:29:30 2012
@@ -77,6 +77,7 @@ import org.apache.catalina.deploy.Securi
 import org.apache.catalina.deploy.ServletDef;
 import org.apache.catalina.deploy.WebXml;
 import org.apache.catalina.util.ContextName;
+import org.apache.catalina.util.Introspection;
 import org.apache.juli.logging.Log;
 import org.apache.juli.logging.LogFactory;
 import org.apache.naming.resources.DirContextURLConnection;
@@ -2089,7 +2090,7 @@ public class ContextConfig implements Li
             }
             if (entry.getSciSet().size() > 0) {
                 // Need to try and load the class
-                clazz = loadClass(className);
+                clazz = Introspection.loadClass(context, className);
                 if (clazz == null) {
                     // Can't load the class so no point continuing
                     return;
@@ -2117,7 +2118,8 @@ public class ContextConfig implements Li
                         if (entry.getKey().getName().equals(
                                 
getClassName(annotationEntry.getAnnotationType()))) {
                             if (clazz == null) {
-                                clazz = loadClass(className);
+                                clazz = Introspection.loadClass(
+                                        context, className);
                                 if (clazz == null) {
                                     // Can't load the class so no point
                                     // continuing
@@ -2231,31 +2233,6 @@ public class ContextConfig implements Li
         return Collections.emptySet();
     }
 
-    private Class<?> loadClass(String className) {
-        Class<?> clazz = null;
-        try {
-            clazz = context.getLoader().getClassLoader().loadClass(className);
-        } catch (NoClassDefFoundError e) {
-            log.debug(sm.getString("contextConfig.invalidSciHandlesTypes",
-                    className), e);
-            return null;
-        } catch (ClassNotFoundException e) {
-            log.debug(sm.getString("contextConfig.invalidSciHandlesTypes",
-                    className), e);
-            return null;
-        } catch (ClassFormatError e) {
-            log.debug(sm.getString("contextConfig.invalidSciHandlesTypes",
-                    className), e);
-            return null;
-        } catch (Throwable t) {
-            ExceptionUtils.handleThrowable(t);
-            log.debug(sm.getString("contextConfig.invalidSciHandlesTypes",
-                    className), t);
-            return null;
-        }
-        return clazz;
-    }
-
     private static final String getClassName(String internalForm) {
         if (!internalForm.startsWith("L")) {
             return internalForm;

Modified: 
tomcat/tc7.0.x/trunk/java/org/apache/catalina/startup/LocalStrings.properties
URL: 
http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/catalina/startup/LocalStrings.properties?rev=1345588&r1=1345587&r2=1345588&view=diff
==============================================================================
--- 
tomcat/tc7.0.x/trunk/java/org/apache/catalina/startup/LocalStrings.properties 
(original)
+++ 
tomcat/tc7.0.x/trunk/java/org/apache/catalina/startup/LocalStrings.properties 
Sat Jun  2 21:29:30 2012
@@ -44,7 +44,6 @@ contextConfig.inputStreamFile=Unable to 
 contextConfig.inputStreamJar=Unable to process Jar entry [{0}] from Jar [{1}] 
for annotations
 contextConfig.inputStreamJndi=Unable to process resource element [{0}] for 
annotations
 contextConfig.invalidSci=The ServletContentInitializer [{0}] could not be 
created
-contextConfig.invalidSciHandlesTypes=Unable to load class [{0}] to check 
against the @HandlesTypes annotation of one or more ServletContentInitializers.
 contextConfig.jarUrl=The connection created for URL [{0}] was not a 
JarUrlConnection
 contextConfig.jar=Unable to process resource [{0}] for annotations
 contextConfig.jndiUrl=Unable to process JNDI URL [{0}] for annotations
@@ -129,6 +128,7 @@ userConfig.error=Error deploying web app
 userConfig.start=UserConfig: Processing START
 userConfig.stop=UserConfig: Processing STOP
 userConfig.deploy.threaded.error=Error waiting for multi-thread deployment of 
user directories to complete
+webAnnotationSet.invalidInjection=Invalid method resource injection annotation.
 webRuleSet.absoluteOrdering=<absolute-ordering> element not valid in 
web-fragment.xml and will be ignored
 webRuleSet.absoluteOrderingCount=<absolute-ordering> element is limited to 1 
occurrence
 webRuleSet.nameCount=<name> element is limited to 1 occurrence

Modified: 
tomcat/tc7.0.x/trunk/java/org/apache/catalina/startup/WebAnnotationSet.java
URL: 
http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/catalina/startup/WebAnnotationSet.java?rev=1345588&r1=1345587&r2=1345588&view=diff
==============================================================================
--- tomcat/tc7.0.x/trunk/java/org/apache/catalina/startup/WebAnnotationSet.java 
(original)
+++ tomcat/tc7.0.x/trunk/java/org/apache/catalina/startup/WebAnnotationSet.java 
Sat Jun  2 21:29:30 2012
@@ -14,15 +14,10 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
-
 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;
@@ -31,15 +26,15 @@ 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;
 import org.apache.catalina.deploy.ContextService;
 import org.apache.catalina.deploy.FilterDef;
 import org.apache.catalina.deploy.MessageDestinationRef;
+import org.apache.catalina.util.Introspection;
+import org.apache.tomcat.util.res.StringManager;
 
 /**
  * <p><strong>AnnotationSet</strong> for processing the annotations of the web 
application
@@ -53,9 +48,15 @@ public class WebAnnotationSet {
 
     private static final String SEPARATOR = "/";
 
+    /**
+     * The string resources for this package.
+     */
+    protected static final StringManager sm =
+        StringManager.getManager(Constants.Package);
+
+
     // --------------------------------------------------------- Public Methods
-    
-    
+
     /**
      * Process the annotations on a context.
      */
@@ -79,7 +80,8 @@ public class WebAnnotationSet {
         Class<?> classClass = null;
         String[] applicationListeners = context.findApplicationListeners();
         for (int i = 0; i < applicationListeners.length; i++) {
-            classClass = loadClass(context, applicationListeners[i]);
+            classClass = Introspection.loadClass(context,
+                    applicationListeners[i]);
             if (classClass == null) {
                 continue;
             }
@@ -98,7 +100,8 @@ public class WebAnnotationSet {
         Class<?> classClass = null;
         FilterDef[] filterDefs = context.findFilterDefs();
         for (int i = 0; i < filterDefs.length; i++) {
-            classClass = loadClass(context, (filterDefs[i]).getFilterClass());
+            classClass = Introspection.loadClass(context,
+                    (filterDefs[i]).getFilterClass());
             if (classClass == null) {
                 continue;
             }
@@ -127,7 +130,8 @@ public class WebAnnotationSet {
                     continue;
                 }
                 
-                classClass = loadClass(context, wrapper.getServletClass());
+                classClass = Introspection.loadClass(context,
+                        wrapper.getServletClass());
                 if (classClass == null) {
                     continue;
                 }
@@ -254,7 +258,7 @@ public class WebAnnotationSet {
     protected static void loadFieldsAnnotation(Context context,
             Class<?> classClass) {
         // Initialize the annotations
-        Field[] fields = getDeclaredFields(classClass);
+        Field[] fields = Introspection.getDeclaredFields(classClass);
         if (fields != null && fields.length > 0) {
             for (Field field : fields) {
                 if (field.isAnnotationPresent(Resource.class)) {
@@ -272,16 +276,19 @@ public class WebAnnotationSet {
     protected static void loadMethodsAnnotation(Context context,
             Class<?> classClass) {
         // Initialize the annotations
-        Method[] methods = getDeclaredMethods(classClass);
+        Method[] methods = Introspection.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);
+                    if (!Introspection.isValidSetter(method)) {
+                        throw new IllegalArgumentException(sm.getString(
+                                "webAnnotationSet.invalidInjection"));
+                    }
 
                     String defaultName = classClass.getName() + SEPARATOR +
-                            DefaultInstanceManager.getName(method);
+                            Introspection.getName(method);
 
                     String defaultType =
                             (method.getParameterTypes()[0]).getCanonicalName();
@@ -405,16 +412,6 @@ public class WebAnnotationSet {
     }
 
 
-    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")) {
@@ -435,54 +432,4 @@ public class WebAnnotationSet {
         }
         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;
-    }
 }

Modified: 
tomcat/tc7.0.x/trunk/java/org/apache/catalina/util/LocalStrings.properties
URL: 
http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/catalina/util/LocalStrings.properties?rev=1345588&r1=1345587&r2=1345588&view=diff
==============================================================================
--- tomcat/tc7.0.x/trunk/java/org/apache/catalina/util/LocalStrings.properties 
(original)
+++ tomcat/tc7.0.x/trunk/java/org/apache/catalina/util/LocalStrings.properties 
Sat Jun  2 21:29:30 2012
@@ -22,6 +22,7 @@ extensionValidator.web-application-manif
 extensionValidator.extension-not-found-error=ExtensionValidator[{0}][{1}]: 
Required extension [{2}] not found.
 extensionValidator.extension-validation-error=ExtensionValidator[{0}]: Failure 
to find [{1}] required extension(s).
 extensionValidator.failload=Failure loading extension [{0}]
+introspection.classLoadFailed=Failed to load class [{0}]
 lifecycleBase.alreadyDestroyed=The destroy() method was called on component 
[{0}] after destroy() had already been called. The second call will be ignored.
 lifecycleBase.alreadyStarted=The start() method was called on component [{0}] 
after start() had already been called. The second call will be ignored.
 lifecycleBase.alreadyStopped=The stop() method was called on component [{0}] 
after stop() had already been called. The second call will be ignored.

Modified: tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml
URL: 
http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml?rev=1345588&r1=1345587&r2=1345588&view=diff
==============================================================================
--- tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml (original)
+++ tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml Sat Jun  2 21:29:30 2012
@@ -175,6 +175,12 @@
         uppercase characters. (kkolinko)
       </fix>
       <fix>
+        <bug>53333</bug>: When processing JNDI resources, take account of the
+        types of any specified injection targets to ensure that the resource
+        definition and the injection target types are consistent. Based on a
+        patch provided by Violeta Georgieva. (markt)
+      </fix>
+      <fix>
         <bug>53342</bug>: To avoid BindException, make startStopThreads into a
         demon thread. (kfujino)
       </fix>



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to