[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.