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;
}