public EjbModule deploy()

in container/openejb-core/src/main/java/org/apache/openejb/config/AnnotationDeployer.java [1290:1574]


        public EjbModule deploy(final EjbModule ejbModule) throws OpenEJBException {
            if (ejbModule.getEjbJar() != null && ejbModule.getEjbJar().isMetadataComplete()) {
                return ejbModule;
            }

            try {
                if (ejbModule.getFinder() == null) {
                    ejbModule.setFinder(FinderFactory.createFinder(ejbModule));
                }
            } catch (final MalformedURLException e) {
                startupLogger.warning("startup.scrapeFailedForModule", ejbModule.getJarLocation());
                return ejbModule;
            } catch (final Exception e) {
                startupLogger.warning("Unable to scrape for @Stateful, @Stateless, @Singleton or @MessageDriven annotations. AnnotationFinder failed.", e);
                return ejbModule;
            }

            final IAnnotationFinder finder = ejbModule.getFinder();

            // Fill in default sessionType for xml declared EJBs
            for (final EnterpriseBean bean : ejbModule.getEjbJar().getEnterpriseBeans()) {
                if (!(bean instanceof SessionBean)) {
                    continue;
                }

                final SessionBean sessionBean = (SessionBean) bean;

                if (sessionBean.getSessionType() != null) {
                    continue;
                }

                try {
                    final Class<?> clazz = ejbModule.getClassLoader().loadClass(bean.getEjbClass());
                    sessionBean.setSessionType(getSessionType(clazz));
                } catch (final Throwable handledInValidation) {
                    // no-op
                }
            }

            // Fill in default ejbName for xml declared EJBs
            for (final EnterpriseBean bean : ejbModule.getEjbJar().getEnterpriseBeans()) {
                if (bean.getEjbClass() == null) {
                    continue;
                }
                if (bean.getEjbName() == null || bean.getEjbName().startsWith("@NULL@")) {
                    ejbModule.getEjbJar().removeEnterpriseBean(bean.getEjbName());
                    try {
                        final Class<?> clazz = ejbModule.getClassLoader().loadClass(bean.getEjbClass());
                        final String ejbName = getEjbName(bean, clazz);
                        bean.setEjbName(ejbName);
                    } catch (final Throwable handledInValidation) {
                        // no-op
                    }
                    ejbModule.getEjbJar().addEnterpriseBean(bean);
                }
            }
            /* 19.2:  ejb-name: Default is the unqualified name of the bean class */

            final EjbJar ejbJar = ejbModule.getEjbJar();
            for (final Annotated<Class<?>> beanClass : finder.findMetaAnnotatedClasses(Singleton.class)) {
                final Singleton singleton = beanClass.getAnnotation(Singleton.class);
                final String ejbName = getEjbName(singleton, beanClass.get());

                if (!isValidEjbAnnotationUsage(Singleton.class, beanClass, ejbName, ejbModule)) {
                    continue;
                }

                EnterpriseBean enterpriseBean = ejbJar.getEnterpriseBean(ejbName);
                if (enterpriseBean == null) {
                    enterpriseBean = new SingletonBean(ejbName, beanClass.get());
                    ejbJar.addEnterpriseBean(enterpriseBean);
                }
                if (enterpriseBean.getEjbClass() == null) {
                    enterpriseBean.setEjbClass(beanClass.get());
                }
                if (enterpriseBean instanceof SessionBean) {
                    final SessionBean sessionBean = (SessionBean) enterpriseBean;
                    sessionBean.setSessionType(SessionType.SINGLETON);

                    if (singleton.mappedName() != null) {
                        sessionBean.setMappedName(singleton.mappedName());
                    }
                }
                LegacyProcessor.process(beanClass.get(), enterpriseBean);
            }

            for (final Annotated<Class<?>> beanClass : finder.findMetaAnnotatedClasses(Stateless.class)) {
                final Stateless stateless = beanClass.getAnnotation(Stateless.class);
                final String ejbName = getEjbName(stateless, beanClass.get());

                if (!isValidEjbAnnotationUsage(Stateless.class, beanClass, ejbName, ejbModule)) {
                    continue;
                }

                EnterpriseBean enterpriseBean = ejbJar.getEnterpriseBean(ejbName);
                if (enterpriseBean == null) {
                    enterpriseBean = new StatelessBean(ejbName, beanClass.get());
                    ejbJar.addEnterpriseBean(enterpriseBean);
                }
                if (enterpriseBean.getEjbClass() == null) {
                    enterpriseBean.setEjbClass(beanClass.get());
                }
                if (enterpriseBean instanceof SessionBean) {
                    final SessionBean sessionBean = (SessionBean) enterpriseBean;
                    sessionBean.setSessionType(SessionType.STATELESS);

                    if (stateless.mappedName() != null) {
                        sessionBean.setMappedName(stateless.mappedName());
                    }
                }
                LegacyProcessor.process(beanClass.get(), enterpriseBean);
            }

            // The Specialization code is good, but it possibly needs to be moved to after the full processing of the bean
            // the plus is that it would get the required interfaces.  The minus is that it would get all the other items

            // Possibly study alternatives.  Alternatives might have different meta data completely while it seems Specializing beans inherit all meta-data

            // Anyway.. the qualifiers aren't getting inherited, so we need to fix that

            for (final Annotated<Class<?>> beanClass : finder.findMetaAnnotatedClasses(Stateful.class)) {
                final Stateful stateful = beanClass.getAnnotation(Stateful.class);
                final String ejbName = getEjbName(stateful, beanClass.get());

                if (!isValidEjbAnnotationUsage(Stateful.class, beanClass, ejbName, ejbModule)) {
                    continue;
                }

                EnterpriseBean enterpriseBean = ejbJar.getEnterpriseBean(ejbName);
                if (enterpriseBean == null) {
                    enterpriseBean = new StatefulBean(ejbName, beanClass.get());
                    ejbJar.addEnterpriseBean(enterpriseBean);
                }
                if (enterpriseBean.getEjbClass() == null) {
                    enterpriseBean.setEjbClass(beanClass.get());
                }
                if (enterpriseBean instanceof SessionBean) {
                    final SessionBean sessionBean = (SessionBean) enterpriseBean;
                    // TODO: We might be stepping on an xml override here
                    sessionBean.setSessionType(SessionType.STATEFUL);
                    if (stateful.mappedName() != null) {
                        sessionBean.setMappedName(stateful.mappedName());
                    }
                    if (sessionBean.getPassivationCapable() == null) {
                        sessionBean.setPassivationCapable(stateful.passivationCapable());
                    }
                }
                LegacyProcessor.process(beanClass.get(), enterpriseBean);
            }

            for (final Annotated<Class<?>> beanClass : finder.findMetaAnnotatedClasses(ManagedBean.class)) {
                final ManagedBean managed = beanClass.getAnnotation(ManagedBean.class);
                final String ejbName = getEjbName(managed, beanClass.get());

                // TODO: this is actually against the spec, but the requirement is rather silly
                // (allowing @Stateful and @ManagedBean on the same class)
                // If the TCK doesn't complain we should discourage it
                if (!isValidEjbAnnotationUsage(ManagedBean.class, beanClass, ejbName, ejbModule)) {
                    continue;
                }

                EnterpriseBean enterpriseBean = ejbJar.getEnterpriseBean(ejbName);
                if (enterpriseBean == null) {
                    enterpriseBean = new org.apache.openejb.jee.ManagedBean(ejbName, beanClass.get());
                    ejbJar.addEnterpriseBean(enterpriseBean);
                }
                if (enterpriseBean.getEjbClass() == null) {
                    enterpriseBean.setEjbClass(beanClass.get());
                }
                if (enterpriseBean instanceof SessionBean) {
                    final SessionBean sessionBean = (SessionBean) enterpriseBean;
                    sessionBean.setSessionType(SessionType.MANAGED);

                    final TransactionType transactionType = sessionBean.getTransactionType();
                    if (transactionType == null) {
                        sessionBean.setTransactionType(TransactionType.BEAN);
                    }
                }
            }

            for (final Annotated<Class<?>> beanClass : finder.findMetaAnnotatedClasses(MessageDriven.class)) {
                final MessageDriven mdb = beanClass.getAnnotation(MessageDriven.class);
                final String ejbName = getEjbName(mdb, beanClass.get());

                if (!isValidEjbAnnotationUsage(MessageDriven.class, beanClass, ejbName, ejbModule)) {
                    continue;
                }

                MessageDrivenBean messageBean = (MessageDrivenBean) ejbJar.getEnterpriseBean(ejbName);
                if (messageBean == null) {
                    messageBean = new MessageDrivenBean(ejbName);
                    ejbJar.addEnterpriseBean(messageBean);
                }
                if (messageBean.getEjbClass() == null) {
                    messageBean.setEjbClass(beanClass.get());
                }
                LegacyProcessor.process(beanClass.get(), messageBean);
            }

            AssemblyDescriptor assemblyDescriptor = ejbModule.getEjbJar().getAssemblyDescriptor();
            if (assemblyDescriptor == null) {
                assemblyDescriptor = new AssemblyDescriptor();
                ejbModule.getEjbJar().setAssemblyDescriptor(assemblyDescriptor);
            }

            startupLogger.debug("Searching for annotated application exceptions (see OPENEJB-980)");
            final List<Class<?>> appExceptions = finder.findAnnotatedClasses(ApplicationException.class);
            for (final Class<?> exceptionClass : appExceptions) {
                startupLogger.debug("...handling " + exceptionClass);
                final ApplicationException annotation = exceptionClass.getAnnotation(ApplicationException.class);
                if (assemblyDescriptor.getApplicationException(exceptionClass) == null) {
                    startupLogger.debug("...adding " + exceptionClass + " with rollback=" + annotation.rollback());
                    assemblyDescriptor.addApplicationException(exceptionClass, annotation.rollback(), annotation.inherited());
                } else {
                    mergeApplicationExceptionAnnotation(assemblyDescriptor, exceptionClass, annotation);
                }
            }

            { // after having found EJB for auto CDI activation
                final Map<URL, List<String>> managedClasses;
                Beans beans = ejbModule.getBeans();

                final boolean deployComp;
                if (beans == null && !ejbJar.getEnterpriseBeansByEjbName().isEmpty()
                        && isActivateCdiForEjbOnlyModules(ejbModule)) {
                    logger.info("Activating CDI in ACTIVATED mode in module '" + ejbModule.getModuleUri() + "' cause EJB were found\n" +
                            "  add openejb.cdi.activated=false in application.properties to switch it off or\n" +
                            "  openejb.cdi.activated-on-ejb=false in conf/system.properties" +
                            "  to switch it off");
                    beans = new Beans();
                    beans.setBeanDiscoveryMode("ANNOTATED");
                    beans.setVersion("1.1");
                    try {
                        ejbModule.getModuleUri().toURL();
                        beans.setUri(ejbModule.getModuleUri().toASCIIString());
                    } catch (final MalformedURLException | IllegalArgumentException iae) { // test? fake a URI
                        beans.setUri(URI.create("jar:file://!/" + ejbModule.getModuleUri().toASCIIString() + "/META-INF/beans.xml").toASCIIString());
                    }
                    ejbModule.setBeans(beans);
                    deployComp = false; // no need normally since mainly only EJB will be injectable
                } else {
                    deployComp = true;
                }

                if (beans != null) {
                    managedClasses = beans.getManagedClasses();
                    getBeanClasses(beans.getUri(), finder, managedClasses, beans.getNotManagedClasses(), ejbModule.getAltDDs());

                    if (deployComp) {
                        // passing jar location to be able to manage maven classes/test-classes which have the same moduleId
                        String id = ejbModule.getModuleId();
                        if (ejbModule.getJarLocation() != null &&
                                (ejbModule.getJarLocation().contains(ejbModule.getModuleId() + "/target/test-classes".replace("/", File.separator)) ||
                                        ejbModule.getJarLocation().contains(ejbModule.getModuleId() + "/build/classes/test".replace("/", File.separator)))) {
                            // with maven/gradle if both src/main/java and src/test/java are deployed
                            // moduleId.Comp exists twice so it fails
                            // here we simply modify the test comp bean name to avoid it
                            id += "_test";
                        }
                        final String name = BeanContext.Comp.openejbCompName(id);
                        final org.apache.openejb.jee.ManagedBean managedBean = new CompManagedBean(name, BeanContext.Comp.class);
                        managedBean.setTransactionType(TransactionType.BEAN);
                        ejbModule.getEjbJar().addEnterpriseBean(managedBean);

                        if ("true".equals(SystemInstance.get().getProperty("openejb.cdi.support.@Startup", "true"))) {
                            final List<Annotated<Class<?>>> forceStart = finder.findMetaAnnotatedClasses(Startup.class);
                            final List<String> startupBeans = beans.getStartupBeans();
                            for (final Annotated<Class<?>> clazz : forceStart) {
                                startupBeans.add(clazz.get().getName());
                            }
                        }
                    }
                }
            }

            // ejb can be rest bean and only then in standalone so scan providers here too
            // adding them to app since they should be in the app classloader
            if (ejbModule.getAppModule() != null) {
                addJaxRsProviders(finder, ejbModule.getAppModule().getJaxRsProviders(), Provider.class);
            }

            autoJpa(ejbModule);

            return ejbModule;
        }