Correct the processing of resources with <injection-target>s defined in web.xml. First look for a match using JavaBean property names and then, only if a match is not found, look for a match using fields.
git-svn-id: https://svn.apache.org/repos/asf/tomcat/tc8.0.x/trunk@1830804 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/java/org/apache/catalina/core/DefaultInstanceManager.java b/java/org/apache/catalina/core/DefaultInstanceManager.java
index 110bded..62b364c 100644
--- a/java/org/apache/catalina/core/DefaultInstanceManager.java
+++ b/java/org/apache/catalina/core/DefaultInstanceManager.java
@@ -297,6 +297,7 @@
InvocationTargetException, NamingException {
List<AnnotationCacheEntry> annotations = null;
+ Set<String> injectionsMatchedToSetter = new HashSet<>();
while (clazz != null) {
AnnotationCacheEntry[] annotationsArray = annotationCache.get(clazz);
@@ -307,48 +308,6 @@
annotations.clear();
}
- if (context != null) {
- // Initialize fields annotations for resource injection if
- // JNDI is enabled
- Field[] fields = Introspection.getDeclaredFields(clazz);
- for (Field field : fields) {
- Resource resourceAnnotation;
- Annotation ejbAnnotation;
- Annotation webServiceRefAnnotation;
- Annotation persistenceContextAnnotation;
- Annotation persistenceUnitAnnotation;
- if (injections != null && injections.containsKey(field.getName())) {
- annotations.add(new AnnotationCacheEntry(
- field.getName(), null,
- injections.get(field.getName()),
- AnnotationCacheEntryType.FIELD));
- } else if ((resourceAnnotation =
- field.getAnnotation(Resource.class)) != null) {
- annotations.add(new AnnotationCacheEntry(field.getName(), null,
- resourceAnnotation.name(), AnnotationCacheEntryType.FIELD));
- } else if (EJB_PRESENT &&
- (ejbAnnotation = field.getAnnotation(EJB.class)) != null) {
- annotations.add(new AnnotationCacheEntry(field.getName(), null,
- ((EJB) ejbAnnotation).name(), AnnotationCacheEntryType.FIELD));
- } else if (WS_PRESENT && (webServiceRefAnnotation =
- field.getAnnotation(WebServiceRef.class)) != null) {
- annotations.add(new AnnotationCacheEntry(field.getName(), null,
- ((WebServiceRef) webServiceRefAnnotation).name(),
- AnnotationCacheEntryType.FIELD));
- } else if (JPA_PRESENT && (persistenceContextAnnotation =
- field.getAnnotation(PersistenceContext.class)) != null) {
- annotations.add(new AnnotationCacheEntry(field.getName(), null,
- ((PersistenceContext) persistenceContextAnnotation).name(),
- AnnotationCacheEntryType.FIELD));
- } else if (JPA_PRESENT && (persistenceUnitAnnotation =
- field.getAnnotation(PersistenceUnit.class)) != null) {
- annotations.add(new AnnotationCacheEntry(field.getName(), null,
- ((PersistenceUnit) persistenceUnitAnnotation).name(),
- AnnotationCacheEntryType.FIELD));
- }
- }
- }
-
// Initialize methods annotations
Method[] methods = Introspection.getDeclaredMethods(clazz);
Method postConstruct = null;
@@ -358,9 +317,9 @@
for (Method method : methods) {
if (context != null) {
// Resource injection only if JNDI is enabled
- if (injections != null &&
- Introspection.isValidSetter(method)) {
+ if (injections != null && Introspection.isValidSetter(method)) {
String fieldName = Introspection.getPropertyName(method);
+ injectionsMatchedToSetter.add(fieldName);
if (injections.containsKey(fieldName)) {
annotations.add(new AnnotationCacheEntry(
method.getName(),
@@ -375,8 +334,7 @@
Annotation webServiceRefAnnotation;
Annotation persistenceContextAnnotation;
Annotation persistenceUnitAnnotation;
- if ((resourceAnnotation =
- method.getAnnotation(Resource.class)) != null) {
+ if ((resourceAnnotation = method.getAnnotation(Resource.class)) != null) {
annotations.add(new AnnotationCacheEntry(
method.getName(),
method.getParameterTypes(),
@@ -438,6 +396,50 @@
+ preDestroyFromXml + " for class " + clazz.getName()
+ " is declared in deployment descriptor but cannot be found.");
}
+
+ if (context != null) {
+ // Initialize fields annotations for resource injection if
+ // JNDI is enabled
+ Field[] fields = Introspection.getDeclaredFields(clazz);
+ for (Field field : fields) {
+ Resource resourceAnnotation;
+ Annotation ejbAnnotation;
+ Annotation webServiceRefAnnotation;
+ Annotation persistenceContextAnnotation;
+ Annotation persistenceUnitAnnotation;
+ String fieldName = field.getName();
+ if (injections != null && injections.containsKey(fieldName) && !injectionsMatchedToSetter.contains(fieldName)) {
+ annotations.add(new AnnotationCacheEntry(
+ fieldName, null,
+ injections.get(fieldName),
+ AnnotationCacheEntryType.FIELD));
+ } else if ((resourceAnnotation =
+ field.getAnnotation(Resource.class)) != null) {
+ annotations.add(new AnnotationCacheEntry(fieldName, null,
+ resourceAnnotation.name(), AnnotationCacheEntryType.FIELD));
+ } else if (EJB_PRESENT &&
+ (ejbAnnotation = field.getAnnotation(EJB.class)) != null) {
+ annotations.add(new AnnotationCacheEntry(fieldName, null,
+ ((EJB) ejbAnnotation).name(), AnnotationCacheEntryType.FIELD));
+ } else if (WS_PRESENT && (webServiceRefAnnotation =
+ field.getAnnotation(WebServiceRef.class)) != null) {
+ annotations.add(new AnnotationCacheEntry(fieldName, null,
+ ((WebServiceRef) webServiceRefAnnotation).name(),
+ AnnotationCacheEntryType.FIELD));
+ } else if (JPA_PRESENT && (persistenceContextAnnotation =
+ field.getAnnotation(PersistenceContext.class)) != null) {
+ annotations.add(new AnnotationCacheEntry(fieldName, null,
+ ((PersistenceContext) persistenceContextAnnotation).name(),
+ AnnotationCacheEntryType.FIELD));
+ } else if (JPA_PRESENT && (persistenceUnitAnnotation =
+ field.getAnnotation(PersistenceUnit.class)) != null) {
+ annotations.add(new AnnotationCacheEntry(fieldName, null,
+ ((PersistenceUnit) persistenceUnitAnnotation).name(),
+ AnnotationCacheEntryType.FIELD));
+ }
+ }
+ }
+
if (annotations.isEmpty()) {
// Use common object to save memory
annotationsArray = ANNOTATIONS_EMPTY;
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index 5bf6dd4..7c650b1 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -54,6 +54,12 @@
annotation. Both now attempt to set the <code>mappedName</code> property
of the resource. (markt)
</fix>
+ <fix>
+ Correct the processing of resources with
+ <code><injection-target></code>s defined in web.xml. First look
+ for a match using JavaBean property names and then, only if a match is
+ not found, look for a match using fields. (markt)
+ </fix>
</changelog>
</subsection>
</section>