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