} catch (Exception e) {
startupLogger.warning("Unable to scrape for @Stateful, @Stateless, @Singleton or @MessageDriven annotations. AnnotationFinder failed.", e);
return ejbModule;
}
IAnnotationFinder finder = ejbModule.getFinder();
final List<String> managedClasses;
{
final Beans beans = ejbModule.getBeans();
if (beans != null) {
managedClasses = beans.getManagedClasses();
final List<String> classNames = getBeanClasses(finder);
for (String rawClassName : classNames) {
final String className = realClassName(rawClassName);
try {
final ClassLoader loader = ejbModule.getClassLoader();
final Class<?> clazz = loader.loadClass(className);
// The following can NOT be beans in CDI
// 1. Non-static inner classes
if (clazz.getEnclosingClass() != null && !Modifier.isStatic(clazz.getModifiers())) continue;
//
// // 2. Abstract classes (unless they are an @Decorator)
// if (Modifier.isAbstract(clazz.getModifiers()) && !clazz.isAnnotationPresent(javax.decorator.Decorator.class)) continue;
//
// 3. Implementations of Extension
if (Extension.class.isAssignableFrom(clazz)) continue;
managedClasses.add(className);
} catch (ClassNotFoundException e) {
// todo log debug warning
} catch (java.lang.NoClassDefFoundError e) {
}
}
// 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))) {
// with maven 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);
} else {
managedClasses = new ArrayList<String>();
}
}
final Set<Class<?>> specializingClasses = new HashSet<Class<?>>();
// Fill in default sessionType for xml declared EJBs
for (EnterpriseBean bean : ejbModule.getEjbJar().getEnterpriseBeans()) {
if (!(bean instanceof SessionBean)) continue;
SessionBean sessionBean = (SessionBean) bean;
if (sessionBean.getSessionType() != null) continue;
try {
final Class<?> clazz = ejbModule.getClassLoader().loadClass(bean.getEjbClass());
sessionBean.setSessionType(getSessionType(clazz));
} catch (Throwable handledInValidation) {
}
}
// Fill in default ejbName for xml declared EJBs
for (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 (Throwable handledInValidation) {
}
ejbModule.getEjbJar().addEnterpriseBean(bean);
}
}
/* 19.2: ejb-name: Default is the unqualified name of the bean class */
EjbJar ejbJar = ejbModule.getEjbJar();
for (Annotated<Class<?>> beanClass : finder.findMetaAnnotatedClasses(Singleton.class)) {
if (beanClass.isAnnotationPresent(Specializes.class)) {
managedClasses.remove(beanClass.get().getName());
specializingClasses.add(beanClass.get());
continue;
}
Singleton singleton = beanClass.getAnnotation(Singleton.class);
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) {
SessionBean sessionBean = (SessionBean) enterpriseBean;
sessionBean.setSessionType(SessionType.SINGLETON);
if (singleton.mappedName() != null) {
sessionBean.setMappedName(singleton.mappedName());
}
}
LegacyProcessor.process(beanClass.get(), enterpriseBean);
}
for (Annotated<Class<?>> beanClass : finder.findMetaAnnotatedClasses(Stateless.class)) {
if (beanClass.isAnnotationPresent(Specializes.class)) {
managedClasses.remove(beanClass.get().getName());
specializingClasses.add(beanClass.get());
continue;
}
Stateless stateless = beanClass.getAnnotation(Stateless.class);
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) {
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 (Annotated<Class<?>> beanClass : finder.findMetaAnnotatedClasses(Stateful.class)) {
if (beanClass.isAnnotationPresent(Specializes.class)) {
managedClasses.remove(beanClass.get().getName());
specializingClasses.add(beanClass.get());
continue;
}
Stateful stateful = beanClass.getAnnotation(Stateful.class);
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) {
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());
}
}
LegacyProcessor.process(beanClass.get(), enterpriseBean);
}
for (Annotated<Class<?>> beanClass : finder.findMetaAnnotatedClasses(ManagedBean.class)) {
if (beanClass.isAnnotationPresent(Specializes.class)) {
managedClasses.remove(beanClass.get().getName());
specializingClasses.add(beanClass.get());
continue;
}
ManagedBean managed = beanClass.getAnnotation(ManagedBean.class);
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) {
SessionBean sessionBean = (SessionBean) enterpriseBean;
sessionBean.setSessionType(SessionType.MANAGED);
final TransactionType transactionType = sessionBean.getTransactionType();
if (transactionType == null) sessionBean.setTransactionType(TransactionType.BEAN);
}
}
for (Annotated<Class<?>> beanClass : finder.findMetaAnnotatedClasses(MessageDriven.class)) {
if (beanClass.isAnnotationPresent(Specializes.class)) {
managedClasses.remove(beanClass.get().getName());
specializingClasses.add(beanClass.get());
continue;
}
MessageDriven mdb = beanClass.getAnnotation(MessageDriven.class);
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);
}
for (Class<?> specializingClass : sortClassesParentFirst(new ArrayList<Class<?>>(specializingClasses))) {
final Class<?> parent = specializingClass.getSuperclass();
if (parent == null || parent.equals(Object.class)) {
ejbModule.getValidation().fail(specializingClass.getSimpleName(), "specializes.extendsNothing", specializingClass.getName());
}
boolean found = false;
for (EnterpriseBean enterpriseBean : ejbJar.getEnterpriseBeans()) {
final String ejbClass = enterpriseBean.getEjbClass();
if (ejbClass != null && ejbClass.equals(parent.getName())) {
managedClasses.remove(ejbClass);
enterpriseBean.setEjbClass(specializingClass.getName());
found = true;
}
}
if (!found) {
ejbModule.getValidation().fail(specializingClass.getSimpleName(), "specializes.extendsSimpleBean", specializingClass.getName());
}
}
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)");
List<Class<?>> appExceptions = finder.findAnnotatedClasses(ApplicationException.class);
for (Class<?> exceptionClass : appExceptions) {
startupLogger.debug("...handling " + exceptionClass);
ApplicationException annotation = exceptionClass.getAnnotation(ApplicationException.class);
if (assemblyDescriptor.getApplicationException(exceptionClass) == null) {
startupLogger.debug("...adding " + exceptionClass + " with rollback=" + annotation.rollback());