You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tomee.apache.org by db...@apache.org on 2008/03/13 11:08:10 UTC

svn commit: r636697 - in /openejb/branches/openejb-3.0/container/openejb-core/src/main: java/org/apache/openejb/config/ java/org/apache/openejb/config/rules/ resources/org/apache/openejb/config/rules/

Author: dblevins
Date: Thu Mar 13 03:08:06 2008
New Revision: 636697

URL: http://svn.apache.org/viewvc?rev=636697&view=rev
Log:
Commit 636688 merged from trunk

Modified:
    openejb/branches/openejb-3.0/container/openejb-core/src/main/java/org/apache/openejb/config/AnnotationDeployer.java
    openejb/branches/openejb-3.0/container/openejb-core/src/main/java/org/apache/openejb/config/ReportValidationResults.java
    openejb/branches/openejb-3.0/container/openejb-core/src/main/java/org/apache/openejb/config/rules/CheckClasses.java
    openejb/branches/openejb-3.0/container/openejb-core/src/main/java/org/apache/openejb/config/rules/ValidationBase.java
    openejb/branches/openejb-3.0/container/openejb-core/src/main/resources/org/apache/openejb/config/rules/Messages.properties

Modified: openejb/branches/openejb-3.0/container/openejb-core/src/main/java/org/apache/openejb/config/AnnotationDeployer.java
URL: http://svn.apache.org/viewvc/openejb/branches/openejb-3.0/container/openejb-core/src/main/java/org/apache/openejb/config/AnnotationDeployer.java?rev=636697&r1=636696&r2=636697&view=diff
==============================================================================
--- openejb/branches/openejb-3.0/container/openejb-core/src/main/java/org/apache/openejb/config/AnnotationDeployer.java (original)
+++ openejb/branches/openejb-3.0/container/openejb-core/src/main/java/org/apache/openejb/config/AnnotationDeployer.java Thu Mar 13 03:08:06 2008
@@ -16,6 +16,9 @@
  */
 package org.apache.openejb.config;
 
+import static java.util.Arrays.asList;
+import static java.lang.reflect.Modifier.isAbstract;
+
 import org.apache.openejb.DeploymentInfo;
 import org.apache.openejb.OpenEJBException;
 import org.apache.openejb.core.webservices.JaxWsUtils;
@@ -128,10 +131,10 @@
 import java.lang.reflect.Field;
 import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
+import java.lang.annotation.Annotation;
 import java.net.MalformedURLException;
 import java.net.URL;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
@@ -190,7 +193,7 @@
     }
 
     public static class DiscoverAnnotatedBeans implements DynamicDeployer {
-        public static final Set<String> knownResourceEnvTypes = new TreeSet<String>(Arrays.asList(
+        public static final Set<String> knownResourceEnvTypes = new TreeSet<String>(asList(
                 "javax.ejb.SessionContext",
                 "javax.ejb.EntityContext",
                 "javax.ejb.MessageDrivenContext",
@@ -201,7 +204,7 @@
                 "javax.ejb.TimerService"
         ));
 
-        public static final Set<String> knownEnvironmentEntries = new TreeSet<String>(Arrays.asList(
+        public static final Set<String> knownEnvironmentEntries = new TreeSet<String>(asList(
                 "boolean", "java.lang.Boolean",
                 "char",    "java.lang.Character",
                 "byte",    "java.lang.Byte",
@@ -274,7 +277,7 @@
             classes.addAll(finder.findAnnotatedClasses(WebServiceProvider.class));
             for (Class<?> webServiceClass : classes) {
                 int modifiers = webServiceClass.getModifiers();
-                if (!Modifier.isPublic(modifiers) || Modifier.isFinal(modifiers) || Modifier.isAbstract(modifiers)) {
+                if (!Modifier.isPublic(modifiers) || Modifier.isFinal(modifiers) || isAbstract(modifiers)) {
                     continue;
                 }
 
@@ -329,7 +332,10 @@
             List<Class> classes = finder.findAnnotatedClasses(Stateless.class);
             for (Class<?> beanClass : classes) {
                 Stateless stateless = beanClass.getAnnotation(Stateless.class);
-                String ejbName = stateless.name().length() == 0 ? beanClass.getSimpleName() : stateless.name();
+                String ejbName = getEjbName(stateless, beanClass);
+
+                if (!isValidAnnotationUsage(Stateless.class, beanClass, ejbName, ejbModule)) continue;
+
                 EnterpriseBean enterpriseBean = ejbJar.getEnterpriseBean(ejbName);
                 if (enterpriseBean == null) {
                     enterpriseBean = new StatelessBean(ejbName, beanClass.getName());
@@ -347,7 +353,10 @@
             classes = finder.findAnnotatedClasses(Stateful.class);
             for (Class<?> beanClass : classes) {
                 Stateful stateful = beanClass.getAnnotation(Stateful.class);
-                String ejbName = stateful.name().length() == 0 ? beanClass.getSimpleName() : stateful.name();
+                String ejbName = getEjbName(stateful, beanClass);
+
+                if (!isValidAnnotationUsage(Stateful.class, beanClass, ejbName, ejbModule)) continue;
+
                 EnterpriseBean enterpriseBean = ejbJar.getEnterpriseBean(ejbName);
                 if (enterpriseBean == null) {
                     enterpriseBean = new StatefulBean(ejbName, beanClass.getName());
@@ -365,7 +374,10 @@
             classes = finder.findAnnotatedClasses(MessageDriven.class);
             for (Class<?> beanClass : classes) {
                 MessageDriven mdb = beanClass.getAnnotation(MessageDriven.class);
-                String ejbName = mdb.name().length() == 0 ? beanClass.getSimpleName() : mdb.name();
+                String ejbName = getEjbName(mdb, beanClass);
+
+                if (!isValidAnnotationUsage(MessageDriven.class, beanClass, ejbName, ejbModule)) continue;
+
                 MessageDrivenBean messageBean = (MessageDrivenBean) ejbJar.getEnterpriseBean(ejbName);
                 if (messageBean == null) {
                     messageBean = new MessageDrivenBean(ejbName);
@@ -390,10 +402,64 @@
 
             return ejbModule;
         }
+
+        private String getEjbName(MessageDriven mdb, Class<?> beanClass) {
+            String ejbName = mdb.name().length() == 0 ? beanClass.getSimpleName() : mdb.name();
+            return ejbName;
+        }
+
+        private String getEjbName(Stateful stateful, Class<?> beanClass) {
+            String ejbName = stateful.name().length() == 0 ? beanClass.getSimpleName() : stateful.name();
+            return ejbName;
+        }
+
+        private String getEjbName(Stateless stateless, Class<?> beanClass) {
+            String ejbName = stateless.name().length() == 0 ? beanClass.getSimpleName() : stateless.name();
+            return ejbName;
+        }
+
+        private boolean isValidAnnotationUsage(Class annotationClass, Class<?> beanClass, String ejbName, EjbModule ejbModule) {
+            List<Class<? extends Annotation>> annotations = new ArrayList(asList(Stateless.class, Stateful.class, MessageDriven.class));
+            annotations.remove(annotationClass);
+
+            Map<String,Class<? extends Annotation>> names = new HashMap<String,Class<? extends Annotation>>();
+
+            boolean b = true;
+            for (Class<? extends Annotation> secondAnnotation : annotations) {
+                Annotation annotation = beanClass.getAnnotation(secondAnnotation);
+
+                if (annotation == null) continue;
+
+                String secondEjbName = null;
+                if (annotation instanceof Stateful) {
+                    secondEjbName = getEjbName((Stateful) annotation, beanClass);
+                } else if (annotation instanceof Stateless) {
+                    secondEjbName = getEjbName((Stateless) annotation, beanClass);
+                } else if (annotation instanceof MessageDriven) {
+                    secondEjbName = getEjbName((MessageDriven) annotation, beanClass);
+                }
+
+                if (ejbName.equals(secondEjbName)) {
+                    ejbModule.getValidation().fail(ejbName, "multiplyAnnotatedAsBean", annotationClass.getSimpleName(), secondAnnotation.getSimpleName(), ejbName, beanClass.getName());
+                }
+            }
+
+            if (beanClass.isInterface()){
+                ejbModule.getValidation().fail(ejbName, "interfaceAnnotatedAsBean", annotationClass.getSimpleName(), beanClass.getName());
+                return false;
+            }
+
+            if (isAbstract(beanClass.getModifiers())){
+                ejbModule.getValidation().fail(ejbName, "abstractAnnotatedAsBean", annotationClass.getSimpleName(), beanClass.getName());
+                return false;
+            }
+
+            return b;
+        }
     }
 
     public static class ProcessAnnotatedBeans implements DynamicDeployer {
-        public static final Set<String> knownResourceEnvTypes = new TreeSet<String>(Arrays.asList(
+        public static final Set<String> knownResourceEnvTypes = new TreeSet<String>(asList(
                 "javax.ejb.SessionContext",
                 "javax.ejb.EntityContext",
                 "javax.ejb.MessageDrivenContext",
@@ -404,7 +470,7 @@
                 "javax.ejb.TimerService"
         ));
 
-        public static final Set<String> knownEnvironmentEntries = new TreeSet<String>(Arrays.asList(
+        public static final Set<String> knownEnvironmentEntries = new TreeSet<String>(asList(
                 "boolean", "java.lang.Boolean",
                 "char",    "java.lang.Character",
                 "byte",    "java.lang.Byte",
@@ -667,7 +733,7 @@
                 RolesAllowed rolesAllowed = clazz.getAnnotation(RolesAllowed.class);
                 if (rolesAllowed != null) {
                     MethodPermission methodPermission = new MethodPermission();
-                    methodPermission.getRoleName().addAll(Arrays.asList(rolesAllowed.value()));
+                    methodPermission.getRoleName().addAll(asList(rolesAllowed.value()));
                     methodPermission.getMethod().add(new org.apache.openejb.jee.Method(ejbName, "*"));
                     assemblyDescriptor.getMethodPermission().add(methodPermission);
                 }
@@ -675,7 +741,7 @@
                 for (Method method : classFinder.findAnnotatedMethods(RolesAllowed.class)) {
                     rolesAllowed = method.getAnnotation(RolesAllowed.class);
                     MethodPermission methodPermission = new MethodPermission();
-                    methodPermission.getRoleName().addAll(Arrays.asList(rolesAllowed.value()));
+                    methodPermission.getRoleName().addAll(asList(rolesAllowed.value()));
                     methodPermission.getMethod().add(new org.apache.openejb.jee.Method(ejbName, method));
                     assemblyDescriptor.getMethodPermission().add(methodPermission);
                 }
@@ -862,13 +928,15 @@
                                 } else if (interfaces.get(0).getAnnotation(Local.class) != null) {
                                     validation.fail(ejbName, "ann.remoteLocal.conflict", join(", ", interfaces));
                                 } else {
-                                    validateRemoteInterface(interfaces.get(0), validation, ejbName);
-                                    remotes.add(interfaces.get(0));
+                                    if (validateRemoteInterface(interfaces.get(0), validation, ejbName)){
+                                        remotes.add(interfaces.get(0));
+                                    }
                                     interfaces.remove(0);
                                 }
                             } else for (Class interfce : remote.value()) {
-                                validateRemoteInterface(interfce, validation, ejbName);
-                                remotes.add(interfce);
+                                if (validateRemoteInterface(interfce, validation, ejbName)){
+                                    remotes.add(interfce);
+                                }
                                 interfaces.remove(interfce);
                             }
                         }
@@ -884,13 +952,15 @@
                                 } else if (interfaces.get(0).getAnnotation(Remote.class) != null) {
                                     validation.fail(ejbName, "ann.localRemote.conflict", join(", ", interfaces));
                                 } else {
-                                    validateLocalInterface(interfaces.get(0), validation, ejbName);
-                                    locals.add(interfaces.get(0));
+                                    if (validateLocalInterface(interfaces.get(0), validation, ejbName)){
+                                        locals.add(interfaces.get(0));
+                                    }
                                     interfaces.remove(0);
                                 }
                             } else for (Class interfce : local.value()) {
-                                validateLocalInterface(interfce, validation, ejbName);
-                                locals.add(interfce);
+                                if (validateLocalInterface(interfce, validation, ejbName)){
+                                    locals.add(interfce);
+                                }
                                 interfaces.remove(interfce);
                             }
                         }
@@ -1156,7 +1226,7 @@
             List<EJB> ejbList = new ArrayList<EJB>();
             for (Class<?> clazz : classFinder.findAnnotatedClasses(EJBs.class)) {
                 EJBs ejbs = clazz.getAnnotation(EJBs.class);
-                ejbList.addAll(Arrays.asList(ejbs.value()));
+                ejbList.addAll(asList(ejbs.value()));
             }
             for (Class<?> clazz : classFinder.findAnnotatedClasses(EJB.class)) {
                 EJB e = clazz.getAnnotation(EJB.class);
@@ -1191,7 +1261,7 @@
             List<Resource> resourceList = new ArrayList<Resource>();
             for (Class<?> clazz : classFinder.findAnnotatedClasses(Resources.class)) {
                 Resources resources = clazz.getAnnotation(Resources.class);
-                resourceList.addAll(Arrays.asList(resources.value()));
+                resourceList.addAll(asList(resources.value()));
             }
             for (Class<?> clazz : classFinder.findAnnotatedClasses(Resource.class)) {
                 Resource resource = clazz.getAnnotation(Resource.class);
@@ -1225,7 +1295,7 @@
             List<WebServiceRef> webservicerefList = new ArrayList<WebServiceRef>();
             for (Class<?> clazz : classFinder.findAnnotatedClasses(WebServiceRefs.class)) {
                 WebServiceRefs webServiceRefs = clazz.getAnnotation(WebServiceRefs.class);
-                webservicerefList.addAll(Arrays.asList(webServiceRefs.value()));
+                webservicerefList.addAll(asList(webServiceRefs.value()));
             }
             for (Class<?> clazz : classFinder.findAnnotatedClasses(WebServiceRef.class)) {
                 WebServiceRef webServiceRef = clazz.getAnnotation(WebServiceRef.class);
@@ -1262,7 +1332,7 @@
             List<PersistenceUnit> persistenceUnitList = new ArrayList<PersistenceUnit>();
             for (Class<?> clazz : classFinder.findAnnotatedClasses(PersistenceUnits.class)) {
                 PersistenceUnits persistenceUnits = clazz.getAnnotation(PersistenceUnits.class);
-                persistenceUnitList.addAll(Arrays.asList(persistenceUnits.value()));
+                persistenceUnitList.addAll(asList(persistenceUnits.value()));
             }
             for (Class<?> clazz : classFinder.findAnnotatedClasses(PersistenceUnit.class)) {
                 PersistenceUnit persistenceUnit = clazz.getAnnotation(PersistenceUnit.class);
@@ -1290,7 +1360,7 @@
             List<PersistenceContext> persistenceContextList = new ArrayList<PersistenceContext>();
             for (Class<?> clazz : classFinder.findAnnotatedClasses(PersistenceContexts.class)) {
                 PersistenceContexts persistenceContexts = clazz.getAnnotation(PersistenceContexts.class);
-                persistenceContextList.addAll(Arrays.asList(persistenceContexts.value()));
+                persistenceContextList.addAll(asList(persistenceContexts.value()));
                 pcFactory.addAnnotations(clazz);
             }
             for (Class<?> clazz : classFinder.findAnnotatedClasses(PersistenceContext.class)) {
@@ -1837,24 +1907,32 @@
         }
 
 
-        private void validateRemoteInterface(Class interfce, ValidationContext validation, String ejbName) {
-            validateInterface(interfce, validation, ejbName, "Remote");
+        private boolean validateRemoteInterface(Class interfce, ValidationContext validation, String ejbName) {
+            return isValidInterface(interfce, validation, ejbName, "Remote");
         }
 
-        private void validateLocalInterface(Class interfce, ValidationContext validation, String ejbName) {
-            validateInterface(interfce, validation, ejbName, "Local");
+        private boolean validateLocalInterface(Class interfce, ValidationContext validation, String ejbName) {
+            return isValidInterface(interfce, validation, ejbName, "Local");
         }
 
-        private void validateInterface(Class interfce, ValidationContext validation, String ejbName, String annotationName) {
-            if (EJBHome.class.isAssignableFrom(interfce)){
+        private boolean isValidInterface(Class interfce, ValidationContext validation, String ejbName, String annotationName) {
+            if (!interfce.isInterface()){
+                validation.fail(ejbName, "ann.notAnInterface", annotationName, interfce.getName());
+                return false;
+            } else if (EJBHome.class.isAssignableFrom(interfce)){
                 validation.fail(ejbName, "ann.remoteOrLocal.ejbHome", annotationName, interfce.getName());
+                return false;
             } else if (EJBObject.class.isAssignableFrom(interfce)){
                 validation.fail(ejbName, "ann.remoteOrLocal.ejbObject", annotationName, interfce.getName());
+                return false;
             } else if (EJBLocalHome.class.isAssignableFrom(interfce)) {
                 validation.fail(ejbName, "ann.remoteOrLocal.ejbLocalHome", annotationName, interfce.getName());
+                return false;
             } else if (EJBLocalObject.class.isAssignableFrom(interfce)){
                 validation.fail(ejbName, "ann.remoteOrLocal.ejbLocalObject", annotationName, interfce.getName());
+                return false;
             }
+            return true;
         }
     }
 

Modified: openejb/branches/openejb-3.0/container/openejb-core/src/main/java/org/apache/openejb/config/ReportValidationResults.java
URL: http://svn.apache.org/viewvc/openejb/branches/openejb-3.0/container/openejb-core/src/main/java/org/apache/openejb/config/ReportValidationResults.java?rev=636697&r1=636696&r2=636697&view=diff
==============================================================================
--- openejb/branches/openejb-3.0/container/openejb-core/src/main/java/org/apache/openejb/config/ReportValidationResults.java (original)
+++ openejb/branches/openejb-3.0/container/openejb-core/src/main/java/org/apache/openejb/config/ReportValidationResults.java Thu Mar 13 03:08:06 2008
@@ -21,10 +21,8 @@
 import org.apache.openejb.loader.SystemInstance;
 import org.apache.openejb.util.Logger;
 import org.apache.openejb.util.LogCategory;
-import org.apache.openejb.util.Join;
 
 import java.util.List;
-import java.util.ArrayList;
 import java.util.Arrays;
 
 /**
@@ -57,8 +55,11 @@
             }
         }
 
+        boolean hasErrors = appModule.hasErrors();
+        boolean hasFailures = appModule.hasFailures();
+        boolean hasWarnings = appModule.hasWarnings();
 
-        if (!appModule.hasErrors() && !appModule.hasFailures()) return appModule;
+        if (!hasErrors && !hasFailures && !hasWarnings) return appModule;
 
         ValidationFailedException validationFailedException = null;
 
@@ -73,14 +74,16 @@
             for (ValidationError error : context.getErrors()) {
                 uberContext.addError(error);
             }
-            for (ValidationFailure error : context.getFailures()) {
-                uberContext.addFailure(error);
+            for (ValidationFailure failure : context.getFailures()) {
+                uberContext.addFailure(failure);
             }
-            for (ValidationWarning error : context.getWarnings()) {
-                uberContext.addWarning(error);
+            for (ValidationWarning warning : context.getWarnings()) {
+                uberContext.addWarning(warning);
             }
         }
 
+        if (!hasErrors && !hasFailures) return appModule;
+
         if (level != Level.VERBOSE){
             List<Level> levels = Arrays.asList(Level.values());
             levels = levels.subList(level.ordinal() + 1, levels.size());
@@ -96,21 +99,20 @@
     }
 
     private void logResults(ValidationContext context, Level level) {
-        if (context.hasErrors() || context.hasFailures()) {
 
-            ValidationError[] errors = context.getErrors();
-            ValidationFailure[] failures = context.getFailures();
+        for (ValidationError e : context.getErrors()) {
+            logger.error(e.getPrefix() + " ... " + e.getComponentName() + ":\t" + e.getMessage(level.ordinal() + 1));
+        }
 
-            for (int j = 0; j < errors.length; j++) {
-                ValidationError e = errors[j];
-                String ejbName = e.getComponentName();
-                logger.error(e.getPrefix() + " ... " + ejbName + ":\t" + e.getMessage(level.ordinal() + 1));
-            }
+        for (ValidationFailure e : context.getFailures()) {
+            logger.error(e.getPrefix() + " ... " + e.getComponentName() + ":\t" + e.getMessage(level.ordinal() + 1));
+        }
 
-            for (int j = 0; j < failures.length; j++) {
-                ValidationFailure e = failures[j];
-                logger.error(e.getPrefix() + " ... " + e.getComponentName() + ":\t" + e.getMessage(level.ordinal() + 1));
-            }
+        for (ValidationWarning e : context.getWarnings()) {
+            logger.warning(e.getPrefix() + " ... " + e.getComponentName() + ":\t" + e.getMessage(level.ordinal() + 1));
+        }
+
+        if (context.hasErrors() || context.hasFailures()) {
 
             logger.error("Invalid "+context.getModuleType()+"(path="+context.getJarPath()+")");
 //            logger.error("Validation: "+errors.length + " errors, "+failures.length+ " failures, in "+context.getModuleType()+"(path="+context.getJarPath()+")");

Modified: openejb/branches/openejb-3.0/container/openejb-core/src/main/java/org/apache/openejb/config/rules/CheckClasses.java
URL: http://svn.apache.org/viewvc/openejb/branches/openejb-3.0/container/openejb-core/src/main/java/org/apache/openejb/config/rules/CheckClasses.java?rev=636697&r1=636696&r2=636697&view=diff
==============================================================================
--- openejb/branches/openejb-3.0/container/openejb-core/src/main/java/org/apache/openejb/config/rules/CheckClasses.java (original)
+++ openejb/branches/openejb-3.0/container/openejb-core/src/main/java/org/apache/openejb/config/rules/CheckClasses.java Thu Mar 13 03:08:06 2008
@@ -22,15 +22,47 @@
 import org.apache.openejb.jee.EntityBean;
 import org.apache.openejb.jee.SessionBean;
 import org.apache.openejb.jee.Interceptor;
-import org.apache.openejb.config.ValidationFailure;
 import org.apache.openejb.config.EjbModule;
 import org.apache.openejb.util.SafeToolkit;
+import org.apache.xbean.finder.ClassFinder;
 
 import javax.ejb.EJBLocalHome;
 import javax.ejb.EJBLocalObject;
+import javax.ejb.EJBHome;
+import javax.ejb.EJBObject;
+import javax.jws.WebService;
+import static java.lang.reflect.Modifier.isAbstract;
+import java.lang.reflect.Method;
+import java.lang.annotation.Annotation;
+import java.util.ArrayList;
+import java.util.List;
 
 public class CheckClasses extends ValidationBase {
 
+    private static final List<Class<? extends Annotation>> beanOnlyAnnotations = new ArrayList<Class<? extends Annotation>>();
+
+    static {
+        beanOnlyAnnotations.add(javax.annotation.PostConstruct.class);
+        beanOnlyAnnotations.add(javax.annotation.PreDestroy.class);
+        beanOnlyAnnotations.add(javax.annotation.Resource.class);
+        beanOnlyAnnotations.add(javax.annotation.Resources.class);
+        beanOnlyAnnotations.add(javax.annotation.security.DeclareRoles.class);
+        beanOnlyAnnotations.add(javax.annotation.security.DenyAll.class);
+        beanOnlyAnnotations.add(javax.annotation.security.PermitAll.class);
+        beanOnlyAnnotations.add(javax.annotation.security.RolesAllowed.class);
+        beanOnlyAnnotations.add(javax.annotation.security.RunAs.class);
+
+        beanOnlyAnnotations.add(javax.ejb.EJB.class);
+        beanOnlyAnnotations.add(javax.ejb.EJBs.class);
+        beanOnlyAnnotations.add(javax.ejb.Init.class);
+        beanOnlyAnnotations.add(javax.ejb.PostActivate.class);
+        beanOnlyAnnotations.add(javax.ejb.PrePassivate.class);
+        beanOnlyAnnotations.add(javax.ejb.Remove.class);
+        beanOnlyAnnotations.add(javax.ejb.Timeout.class);
+        beanOnlyAnnotations.add(javax.ejb.TransactionAttribute.class);
+        beanOnlyAnnotations.add(javax.ejb.TransactionManagement.class);
+    }
+
     public void validate(EjbModule ejbModule) {
         for (EnterpriseBean bean : ejbModule.getEjbJar().getEnterpriseBeans()) {
             try {
@@ -41,6 +73,7 @@
 
                 check_isEjbClass(b);
                 check_hasDependentClasses(b, b.getEjbClass(), "<ejb-class>");
+                check_hasInterface(b);
                 if (b.getHome() != null) {
                     check_hasHomeClass(b);
                     check_hasRemoteClass(b);
@@ -57,6 +90,16 @@
                     check_hasDependentClasses(b, b.getLocalHome(), "<local-home>");
                     check_hasDependentClasses(b, b.getLocal(), "<local>");
                 }
+
+                if (b instanceof SessionBean) {
+                    SessionBean sessionBean = (SessionBean) b;
+                    for (String interfce : sessionBean.getBusinessLocal()) {
+                        check_businessInterface(sessionBean, interfce, "<business-local>");
+                    }
+                    for (String interfce : sessionBean.getBusinessRemote()) {
+                        check_businessInterface(sessionBean, interfce, "<business-remote>");
+                    }
+                }
             } catch (RuntimeException e) {
                 throw new RuntimeException(bean.getEjbName(), e);
             }
@@ -67,6 +110,62 @@
         }
     }
 
+    private void check_businessInterface(SessionBean b, String interfaceName, String tagName) {
+        String ejbName = b.getEjbName();
+        Class interfce = lookForClass(interfaceName, tagName, b.getEjbName());
+
+        if (!interfce.isInterface()){
+            fail(b, "notAnInterface", interfce.getName(), tagName);
+        }
+
+        ClassFinder finder = new ClassFinder(interfce);
+
+        for (Class<? extends Annotation> annotation : beanOnlyAnnotations) {
+            if (interfce.getAnnotation(annotation) != null){
+                warn(b, "interface.beanOnlyAnnotation", annotation.getSimpleName(), interfce.getName(), b.getEjbClass());
+            }
+            for (Method method : finder.findAnnotatedMethods(annotation)) {
+                warn(b, "interfaceMethod.beanOnlyAnnotation", annotation.getSimpleName(), interfce.getName(), method.getName(), b.getEjbClass());
+            }
+        }
+
+        if (EJBHome.class.isAssignableFrom(interfce)){
+            fail(ejbName, "xml.remoteOrLocal.ejbHome", tagName, interfce.getName());
+        } else if (EJBObject.class.isAssignableFrom(interfce)){
+            fail(ejbName, "xml.remoteOrLocal.ejbObject", tagName, interfce.getName());
+        } else if (EJBLocalHome.class.isAssignableFrom(interfce)) {
+            fail(ejbName, "xml.remoteOrLocal.ejbLocalHome", tagName, interfce.getName());
+        } else if (EJBLocalObject.class.isAssignableFrom(interfce)){
+            fail(ejbName, "xml.remoteOrLocal.ejbLocalObject", tagName, interfce.getName());
+        }
+
+    }
+
+    private void check_hasInterface(RemoteBean b) {
+        if (b.getRemote() != null) return;
+        if (b.getLocal() != null) return;
+
+        Class beanClass = null;
+        try {
+            beanClass = loadClass(b.getEjbClass());
+        } catch (OpenEJBException e) {
+        }
+
+        if (b instanceof EntityBean){
+            fail(b, "noInterfaceDeclared.entity", beanClass.getSimpleName());
+            return;
+        }
+
+        if (b.getBusinessLocal().size() > 0) return;
+        if (b.getBusinessRemote().size() > 0) return;
+
+        if (((SessionBean) b).getServiceEndpoint() != null) return;
+
+        if (beanClass.getAnnotation(WebService.class) != null) return;
+
+        fail(b, "noInterfaceDeclared.session");
+    }
+
     private void check_hasDependentClasses(RemoteBean b, String className, String type) {
         try {
             ClassLoader cl = module.getClassLoader();
@@ -107,8 +206,19 @@
 
     public void check_hasEjbClass(EnterpriseBean b) {
 
-        lookForClass(b.getEjbClass(), "<ejb-class>", b.getEjbName());
+        String ejbName = b.getEjbName();
+
+        Class beanClass = lookForClass(b.getEjbClass(), "<ejb-class>", ejbName);
 
+        if (beanClass.isInterface()){
+            fail(ejbName, "interfaceDeclaredAsBean", beanClass.getName());
+        }
+
+        if (isCmp(b)) return;
+
+        if (isAbstract(beanClass.getModifiers())){
+            fail(ejbName, "abstractDeclaredAsBean", beanClass.getName());
+        }
     }
 
     public void check_hasInterceptorClass(Interceptor i) {
@@ -165,9 +275,9 @@
 
     }
 
-    private void lookForClass(String clazz, String type, String ejbName) {
+    private Class lookForClass(String clazz, String type, String ejbName) {
         try {
-            loadClass(clazz);
+            return loadClass(clazz);
         } catch (OpenEJBException e) {
             /*
             # 0 - Class name
@@ -189,6 +299,7 @@
             throw e;
         }
 
+        return null;
     }
 
     private void compareTypes(RemoteBean b, String clazz1, Class class2) {

Modified: openejb/branches/openejb-3.0/container/openejb-core/src/main/java/org/apache/openejb/config/rules/ValidationBase.java
URL: http://svn.apache.org/viewvc/openejb/branches/openejb-3.0/container/openejb-core/src/main/java/org/apache/openejb/config/rules/ValidationBase.java?rev=636697&r1=636696&r2=636697&view=diff
==============================================================================
--- openejb/branches/openejb-3.0/container/openejb-core/src/main/java/org/apache/openejb/config/rules/ValidationBase.java (original)
+++ openejb/branches/openejb-3.0/container/openejb-core/src/main/java/org/apache/openejb/config/rules/ValidationBase.java Thu Mar 13 03:08:06 2008
@@ -24,6 +24,8 @@
 import org.apache.openejb.config.ValidationContext;
 import org.apache.openejb.config.DeploymentModule;
 import org.apache.openejb.jee.EnterpriseBean;
+import org.apache.openejb.jee.EntityBean;
+import org.apache.openejb.jee.PersistenceType;
 import org.apache.openejb.OpenEJBException;
 import org.apache.openejb.util.SafeToolkit;
 import org.apache.openejb.util.Join;
@@ -122,5 +124,15 @@
         } catch (ClassNotFoundException cnfe) {
             throw new OpenEJBException(SafeToolkit.messages.format("cl0007", clazz, module.getJarLocation()), cnfe);
         }
+    }
+
+    public boolean isCmp(EnterpriseBean b) {
+
+        if (b instanceof EntityBean) {
+            EntityBean entityBean = (EntityBean) b;
+            PersistenceType persistenceType = entityBean.getPersistenceType();
+            return persistenceType == PersistenceType.CONTAINER;
+        }
+        return false;
     }
 }

Modified: openejb/branches/openejb-3.0/container/openejb-core/src/main/resources/org/apache/openejb/config/rules/Messages.properties
URL: http://svn.apache.org/viewvc/openejb/branches/openejb-3.0/container/openejb-core/src/main/resources/org/apache/openejb/config/rules/Messages.properties?rev=636697&r1=636696&r2=636697&view=diff
==============================================================================
--- openejb/branches/openejb-3.0/container/openejb-core/src/main/resources/org/apache/openejb/config/rules/Messages.properties (original)
+++ openejb/branches/openejb-3.0/container/openejb-core/src/main/resources/org/apache/openejb/config/rules/Messages.properties Thu Mar 13 03:08:06 2008
@@ -220,12 +220,6 @@
 2.injectionTarget.nameContainsSet = Corrected invalid injection-target-name: {0}
 3.injectionTarget.nameContainsSet = The injection-target-name "{0}" for setter methods should not begin with "set".  The last portion of the name "{1}" has been automatically corrected to "{2}".  Update the descriptor with the correct injection-target-name of "{3}" to avoid receiving this warning.  Resource to be injected is "{4}".
 
-# CheckServiceRefs.java
-# warn(bean, "serviceRef.unsupported", ref.getName());
-1.serviceRef.unsupported = Web service refs are not yet supported
-2.serviceRef.unsupported = Web service refs are not yet supported: service-ref {0}
-3.serviceRef.unsupported = The web service ref "{0}" will be ignored as this feature is not yet implemented.  The entry "java:comp/env/{0}" will not be available in JNDI and any associated injects will not be performed.
-
 # AnnotationDeployer.java
 # fail(ejbName, "ann.remote.noAttributes", join(", ", interfaces));
 1.ann.remote.noAttributes = Ambiguous @Remote() usage on bean class
@@ -277,6 +271,26 @@
 2.ann.remoteOrLocal.ejbLocalObject = @{0} used in bean class lists a javax.ejb.EJBLocalObject interface. Use @LocalHome with home interface of "{1}".
 3.ann.remoteOrLocal.ejbLocalObject = When applied to a bean class, the @{0} annotation must only list business interfaces and cannot list legacy EJBLocalObject interfaces.  The EJBLocalHome of interface for "{1}" can be annotated on the bean class with @LocalHome
 
+# fail(ejbName, "xml.remoteOrLocal.ejbHome", tagName, interfce.getName());
+1.xml.remoteOrLocal.ejbHome = javax.ejb.EJBHome interface declared as {0}.
+2.xml.remoteOrLocal.ejbHome = javax.ejb.EJBHome interface declared as {0}. Use <home>{1}</home>
+3.xml.remoteOrLocal.ejbHome = Interfaces extending javax.ejb.EJBHome pre-date the concept of EJB 3.0 simplified business interfaces and must not use the {0} tag when declared in the ejb-jar.xml.  Declare this interface as <home>{1}</home>.
+
+# fail(ejbName, "xml.remoteOrLocal.ejbLocalHome", tagName, interfce.getName());
+1.xml.remoteOrLocal.ejbLocalHome = javax.ejb.EJBHome interface declared as {0}.
+2.xml.remoteOrLocal.ejbLocalHome = javax.ejb.EJBHome interface declared as {0}. Use <local-home>{1}</local-home>
+3.xml.remoteOrLocal.ejbLocalHome = Interfaces extending javax.ejb.EJBLocalHome pre-date the concept of EJB 3.0 simplified business interfaces and must not use the {0} tag when declared in the ejb-jar.xml.  Declare this interface as <local-home>{1}</local-home>.
+
+# fail(ejbName, "xml.remoteOrLocal.ejbObject", tagName, interfce.getName());
+1.xml.remoteOrLocal.ejbObject = javax.ejb.EJBHome interface declared as {0}.
+2.xml.remoteOrLocal.ejbObject = javax.ejb.EJBHome interface declared as {0}. Use <remote>{1}</remote>
+3.xml.remoteOrLocal.ejbObject = Interfaces extending javax.ejb.EJBObject pre-date the concept of EJB 3.0 simplified business interfaces and must not use the {0} tag when declared in the ejb-jar.xml.  Declare this interface as <remote>{1}</remote>.
+
+# fail(ejbName, "xml.remoteOrLocal.ejbLocalObject", tagName, interfce.getName());
+1.xml.remoteOrLocal.ejbLocalObject = javax.ejb.EJBHome interface declared as {0}.
+2.xml.remoteOrLocal.ejbLocalObject = javax.ejb.EJBHome interface declared as {0}. Use <local>{1}</local>
+3.xml.remoteOrLocal.ejbLocalObject = Interfaces extending javax.ejb.EJBObject pre-date the concept of EJB 3.0 simplified business interfaces and must not use the {0} tag when declared in the ejb-jar.xml.  Declare this interface as <local>{1}</local>.
+
 # fail(bean, "persistenceContextExtented.nonStateful", refName, beanType);
 1.persistenceContextExtented.nonStateful = Non-Stateful use of PersistenceContextType.EXTENDED
 2.persistenceContextExtented.nonStateful = Non-Stateful use of PersistenceContextType.EXTENDED in ref {0}
@@ -431,3 +445,63 @@
     </persistence-unit>\
   </persistence>\
 
+
+# fail(ejbName, "interfaceAnnotatedAsBean", annotationClass.getSimpleName(), beanClass.getName());
+1.interfaceAnnotatedAsBean = @{0} cannot be applied to an interface.
+2.interfaceAnnotatedAsBean = @{0} cannot be applied to an interface: {1}
+3.interfaceAnnotatedAsBean = Only concrete classes, not interfaces, are allowed to use the @{0} annotation.  Either convert the interface {1} to a class so that it may be used as a valid bean or move the @{0} annotation to the classes that implement this interface.
+
+# fail(ejbName, "abstractAnnotatedAsBean", annotationClass.getSimpleName(), beanClass.getName());
+1.abstractAnnotatedAsBean = @{0} cannot be applied to abstract classes.
+2.abstractAnnotatedAsBean = @{0} cannot be applied to an abstract class: {1}
+3.abstractAnnotatedAsBean = Only concrete classes, not abstract classes, are allowed to use the @{0} annotation.  Either convert the abstract class {1} to a concrete class so that it may be used as a valid bean or move the @{0} annotation to the classes that subclass from this class.
+
+# fail(ejbName, "multiplyAnnotatedAsBean", annotationClass.getSimpleName(), secondAnnotation.getSimpleName(), ejbName, beanClass.getName())
+1.multiplyAnnotatedAsBean = Identical 'name' used in both @{0} and @{1} annotations.
+2.multiplyAnnotatedAsBean = Identical 'name' used in both @{0} and @{1} annotations: name={2}
+3.multiplyAnnotatedAsBean = When attempting to deploy a bean as both @{0} and @{1} different values must be used for the 'name' attributes as all ejb-names must be unique within a given ejb-jar.  Update the @{1} annotation to explicitly set the 'name' attribute to a different value.  For example: @{1}(name = "{1}{2}")
+
+# fail(b, "noInterfaceDeclared.entity", ejbClass.getSimpleName());
+1.noInterfaceDeclared.entity = EJBHome or EJBLocalHome interface required.
+2.noInterfaceDeclared.entity = EJBHome or EJBLocalHome interface required.
+3.noInterfaceDeclared.entity = EJB 2.x and 1.x entity beans require EJBHome or EJBLocalHome interfaces to be accessed.  An example of valid component (i.e. pre-EJB 3.0) interfaces for this bean might be:\
+    public interface {0}Home extends javax.ejb.EJBLocalHome {\
+        {0}Object create() throws javax.ejb.CreateException;        \
+    }\
+\
+    public interface {0}Object extends javax.ejb.EJBLocalObject {\
+        \
+    }\
+
+
+# fail(b, "noInterfaceDeclared.session", ejbClass.getSimpleName());
+1.noInterfaceDeclared.session = Business Interface or @WebService annotation required.
+2.noInterfaceDeclared.session = Business Interface or @WebService annotation required.
+3.noInterfaceDeclared.session = All EJB 3.0 and earlier Session beans must either implement an interface, declare one via annotation or xml, or be annotated with @javax.jws.WebService.  An example interface for this bean might be:\
+    @Local\
+    public interface {0}Local {\
+        // add the methods from {0} you'd like to expose  \
+    }\
+\
+Which can then be implemented by the {0} class.\
+
+
+# fail(b, "notAnInterface", interfce.getName(), tagName);
+1.notAnInterface = Business remotes and locals must be interfaces.
+2.notAnInterface = Class tagged as {1} is not an interface: {0}
+3.notAnInterface = All business remote and business local views must be java interfaces.  Classes, abstract classes or enums are not allowed.  Either convert {0} to an interface or remove the related {1} xml tag from your ejb-jar.xml.
+
+# fail(ejbName, "ann.notAnInterface", annotationName, interfce.getName());
+1.ann.notAnInterface = @{0} lists a non-interface.
+2.ann.notAnInterface = @{0} lists a non-interface: {1}
+3.ann.notAnInterface = All business remote and business local views must be java interfaces.  Classes, abstract classes or enums are not allowed.  Either convert {1} to an interface or remove it from the @{0} list in the bean class.
+
+# warn(b, "interface.beanOnlyAnnotation", annotation.getSimpleName(), interfce.getName(), b.getEjbClass());
+1.interface.beanOnlyAnnotation = Ignoring @{0}.  Annotation only usable on the bean class.
+2.interface.beanOnlyAnnotation = Ignoring @{0} used on interface {1}.  Annotation only usable on the bean class.
+3.interface.beanOnlyAnnotation = @{0} is only usable on the bean classes, not its interfaces.  This annotation will be ignored unless it is moved to the bean class {2}.
+
+# warn(b, "interfaceMethod.beanOnlyAnnotation", annotation.getSimpleName(), interfce.getName(), method.getName(), b.getEjbClass());
+1.interfaceMethod.beanOnlyAnnotation = Ignoring @{0}.  Annotation only usable on the bean class.
+2.interfaceMethod.beanOnlyAnnotation = Ignoring @{0} used on interface {1} method {2}.  Annotation only usable on the bean class.
+3.interfaceMethod.beanOnlyAnnotation = @{0} is only usable on the bean classes, not its interfaces.  This annotation will be ignored unless it is moved to the {2} method in the bean class {3}.