[274340] EJB validation is using a stale JEM cache for bean class
diff --git a/plugins/org.eclipse.jst.j2ee.core/j2ee-validation/org/eclipse/jst/j2ee/model/internal/validation/AComponentVRule.java b/plugins/org.eclipse.jst.j2ee.core/j2ee-validation/org/eclipse/jst/j2ee/model/internal/validation/AComponentVRule.java index ba2aece..03f4d41 100644 --- a/plugins/org.eclipse.jst.j2ee.core/j2ee-validation/org/eclipse/jst/j2ee/model/internal/validation/AComponentVRule.java +++ b/plugins/org.eclipse.jst.j2ee.core/j2ee-validation/org/eclipse/jst/j2ee/model/internal/validation/AComponentVRule.java
@@ -14,9 +14,11 @@ import java.util.List; import java.util.Set; +import org.eclipse.jem.internal.java.adapters.JavaReflectionAdaptor; import org.eclipse.jem.java.JavaClass; import org.eclipse.jem.java.JavaHelpers; import org.eclipse.jem.java.Method; +import org.eclipse.jem.java.TypeKind; import org.eclipse.jst.j2ee.ejb.EnterpriseBean; import org.eclipse.wst.validation.internal.core.ValidationException; import org.eclipse.wst.validation.internal.provisional.core.IMessage; @@ -86,8 +88,24 @@ // IWAD4228 = This method must return the same type as {0}. Read section 10.6.11 of the EJB 2.0 specification. // IWAD4328 = This method must return the same type as {0} on {1}. Read section 12.2.8 of the EJB 2.0 specification. // IWAD4355 = This method must return {0}. Read section 12.2.10 of the EJB 2.0 specification. - IMessage message = MessageUtility.getUtility().getMessage(vc, IMessagePrefixEjb20Constants.CHKJ2470, IEJBValidationContext.ERROR, bean, clazz, method, new String[]{match.getReturnType().getJavaName()}, this); - vc.addMessage(message); + + boolean addMessage = true; + + //if the return type on the interface is resolvable and the match on the bean is not. flush the bean and recheck if it resolves + JavaClass returnType = ValidationRuleUtility.getJavaClass(method.getReturnType()); + JavaClass beanReturnType = ValidationRuleUtility.getJavaClass(match.getReturnType()); + if (returnType != null && beanReturnType != null && returnType.getKind() != TypeKind.UNDEFINED_LITERAL && beanReturnType.getKind() == TypeKind.UNDEFINED_LITERAL) { + // bugzilla 274340 - EJB validation is using a stale JEM cache for bean class + JavaReflectionAdaptor adapter = (JavaReflectionAdaptor) JavaReflectionAdaptor.retrieveAdaptorFrom(bean.getEjbClass()); + adapter.flushReflectedValuesIfNecessary(true); + if (ValidationRuleUtility.getMethodExtended(bean.getEjbClass(), method.getName(), method.listParametersWithoutReturn(), method.getReturnType()) != null) { + addMessage = false; + } + } + if (addMessage) { + IMessage message = MessageUtility.getUtility().getMessage(vc, IMessagePrefixEjb20Constants.CHKJ2470, IEJBValidationContext.ERROR, bean, clazz, method, new String[]{match.getReturnType().getJavaName()}, this); + vc.addMessage(message); + } } Set exceptions = ValidationRuleUtility.getNotSubsetExceptions(bean, match, method);
diff --git a/plugins/org.eclipse.jst.j2ee.core/j2ee-validation/org/eclipse/jst/j2ee/model/internal/validation/ValidationRuleUtility.java b/plugins/org.eclipse.jst.j2ee.core/j2ee-validation/org/eclipse/jst/j2ee/model/internal/validation/ValidationRuleUtility.java index a12e410..59c07d1 100644 --- a/plugins/org.eclipse.jst.j2ee.core/j2ee-validation/org/eclipse/jst/j2ee/model/internal/validation/ValidationRuleUtility.java +++ b/plugins/org.eclipse.jst.j2ee.core/j2ee-validation/org/eclipse/jst/j2ee/model/internal/validation/ValidationRuleUtility.java
@@ -323,6 +323,46 @@ /** * Get the method of this name and these parameters. It will look up the supertype hierarchy. + * + * + * If retType is null it means that the return type of the method doesn't need to be checked. + * Otherwise, check that the return type matches too. + */ + public static Method getMethodExtended(JavaClass clazz, String methodName, JavaParameter[] parameterTypes, JavaHelpers retType) { + if (clazz.isInterface()) { + // Check the current class first. If the method has been overriden, + // don't want to return the parent's method instead of the child's. + return getMethodInterfaceExtended(clazz, methodName, parameterTypes); + } + // Check the current class first. If the method has been overriden, + // don't want to return the parent's method instead of the child's. + Method method = null; + List methods = null; + do { + methods = clazz.getMethods(); + method = getMethod(methodName, parameterTypes, methods); + if (method != null) { + if(retType != null) { + JavaHelpers methRetType = method.getReturnType(); + if(isAssignableFrom(methRetType, retType)) { + return method; + } + } + else { + return method; + } + } + + // else, search the parent + clazz = clazz.getSupertype(); + } + while ((method == null) && (clazz != null)); + + return null; + } + + /** + * Get the method of this name and these parameters. It will look up the supertype hierarchy. * * This method is a duplicate of getMethodInterfaceExtended(String, String[], JavaClass). * For performance reasons, the code was duplicated instead of converting the @@ -906,6 +946,30 @@ return compareType.getWrapper().isAssignableFrom(type.getWrapper()); } } + + /** + * Returns the JavaClass for the JavaHelper type + */ + public static JavaClass getJavaClass(JavaHelpers type) { + if (type == null) { + return null; + } + + if (!type.isPrimitive()) { + if(type.isArray()) { + JavaClass classType = type.getWrapper(); + if (classType == null) { + return null; + } + JavaHelpers finalType = ((ArrayType)classType).getFinalComponentType(); + return getJavaClass(finalType); + } + else { + return type.getWrapper(); + } + } + return null; + } /** * Return true if the given method is associated with a query element in ejb-jar.xml.