try {
clazz = classLoader.loadClass(bean.getEjbClass());
} catch (ClassNotFoundException e) {
throw new OpenEJBException("Unable to load bean class: " + bean.getEjbClass(), e);
}
ClassFinder classFinder = new ClassFinder(clazz);
ClassFinder inheritedClassFinder = createInheritedClassFinder(clazz);
/*
* @PostConstruct
* @PreDestroy
* @AroundInvoke
* @Timeout
* @PostActivate
* @PrePassivate
* @Init
* @Remove
*/
processCallbacks(bean, inheritedClassFinder);
/*
* @TransactionManagement
*/
if (bean.getTransactionType() == null) {
TransactionManagement tx = getInheritableAnnotation(clazz, TransactionManagement.class);
TransactionManagementType transactionType = TransactionManagementType.CONTAINER;
if (tx != null) {
transactionType = tx.value();
}
switch (transactionType) {
case BEAN:
bean.setTransactionType(TransactionType.BEAN);
break;
case CONTAINER:
bean.setTransactionType(TransactionType.CONTAINER);
break;
}
}
AssemblyDescriptor assemblyDescriptor = ejbModule.getEjbJar().getAssemblyDescriptor();
/*
* @ApplicationException
*/
processApplicationExceptions(clazz, assemblyDescriptor);
/*
* TransactionAttribute
*/
if (bean.getTransactionType() == TransactionType.CONTAINER) {
processAttributes(new TransactionAttributeHandler(assemblyDescriptor, ejbName), clazz, inheritedClassFinder);
} else {
checkAttributes(new TransactionAttributeHandler(assemblyDescriptor, ejbName), ejbName, ejbModule, classFinder, "invalidTransactionAttribute");
}
/*
* @RolesAllowed
* @PermitAll
* @DenyAll
* @RunAs
* @DeclareRoles
*/
processSecurityAnnotations(clazz, ejbName, ejbModule, inheritedClassFinder, bean);
/*
* @Schedule
* @Schedules
*/
Set<Method> scheduleMethods = new HashSet<Method>();
scheduleMethods.addAll(inheritedClassFinder.findAnnotatedMethods(javax.ejb.Schedules.class));
scheduleMethods.addAll(inheritedClassFinder.findAnnotatedMethods(javax.ejb.Schedule.class));
Map<String, List<MethodAttribute>> existingDeclarations = assemblyDescriptor.getMethodScheduleMap(ejbName);
for (Method method : scheduleMethods) {
// Don't add the schedules from annotations if the schedules have been
// supplied for this method via xml. The xml is considered an override.
if (hasMethodAttribute(existingDeclarations, method)) break;
List<javax.ejb.Schedule> list = new ArrayList<javax.ejb.Schedule>();
javax.ejb.Schedules schedulesAnnotation = method.getAnnotation(javax.ejb.Schedules.class);
if (schedulesAnnotation != null) {
list.addAll(asList(schedulesAnnotation.value()));
}
javax.ejb.Schedule scheduleAnnotation = method.getAnnotation(javax.ejb.Schedule.class);
if (scheduleAnnotation != null) {
list.add(scheduleAnnotation);
}
if (list.size() == 0) continue;
MethodSchedule methodSchedule = new MethodSchedule(ejbName, method);
for (javax.ejb.Schedule schedule : list) {
Schedule s = new Schedule();
s.setSecond(schedule.second());
s.setMinute(schedule.minute());
s.setHour(schedule.hour());
s.setDayOfWeek(schedule.dayOfWeek());
s.setDayOfMonth(schedule.dayOfMonth());
s.setMonth(schedule.month());
s.setYear(schedule.year());
s.setPersistent(schedule.persistent());
s.setInfo(schedule.info());
methodSchedule.getSchedule().add(s);
}
assemblyDescriptor.getMethodSchedule().add(methodSchedule);
}
/*
* Add any interceptors they may have referenced in xml but did not declare
*/
for (InterceptorBinding binding : assemblyDescriptor.getInterceptorBinding()) {
EjbJar ejbJar = ejbModule.getEjbJar();
List<String> list = new ArrayList<String>(binding.getInterceptorClass());
if (binding.getInterceptorOrder() != null){
list.clear();
list.addAll(binding.getInterceptorOrder().getInterceptorClass());
}
for (String interceptor : list) {
if (ejbJar.getInterceptor(interceptor) == null) {
logger.debug("Adding '<ejb-jar><interceptors><interceptor>' entry for undeclared interceptor " + interceptor);
ejbJar.addInterceptor(new Interceptor(interceptor));
}
}
}
/*
* @Interceptors
*/
for (Class<?> interceptorsAnnotatedClass : inheritedClassFinder.findAnnotatedClasses(Interceptors.class)) {
Interceptors interceptors = interceptorsAnnotatedClass.getAnnotation(Interceptors.class);
EjbJar ejbJar = ejbModule.getEjbJar();
for (Class interceptor : interceptors.value()) {
if (ejbJar.getInterceptor(interceptor.getName()) == null) {
ejbJar.addInterceptor(new Interceptor(interceptor.getName()));
}
}
InterceptorBinding binding = new InterceptorBinding(bean);
assemblyDescriptor.getInterceptorBinding().add(0, binding);
for (Class interceptor : interceptors.value()) {
binding.getInterceptorClass().add(interceptor.getName());
}
}
for (Method method : inheritedClassFinder.findAnnotatedMethods(Interceptors.class)) {
Interceptors interceptors = method.getAnnotation(Interceptors.class);
if (interceptors != null) {
EjbJar ejbJar = ejbModule.getEjbJar();
for (Class interceptor : interceptors.value()) {
if (ejbJar.getInterceptor(interceptor.getName()) == null) {
ejbJar.addInterceptor(new Interceptor(interceptor.getName()));
}
}
InterceptorBinding binding = new InterceptorBinding(bean);
assemblyDescriptor.getInterceptorBinding().add(0, binding);
for (Class interceptor : interceptors.value()) {
binding.getInterceptorClass().add(interceptor.getName());
}
binding.setMethod(new NamedMethod(method));
}
}
/*
* @ExcludeDefaultInterceptors
*/
ExcludeDefaultInterceptors excludeDefaultInterceptors = clazz.getAnnotation(ExcludeDefaultInterceptors.class);
if (excludeDefaultInterceptors != null) {
InterceptorBinding binding = assemblyDescriptor.addInterceptorBinding(new InterceptorBinding(bean));
binding.setExcludeDefaultInterceptors(true);
}
for (Method method : classFinder.findAnnotatedMethods(ExcludeDefaultInterceptors.class)) {
InterceptorBinding binding = assemblyDescriptor.addInterceptorBinding(new InterceptorBinding(bean));
binding.setExcludeDefaultInterceptors(true);
binding.setMethod(new NamedMethod(method));
}
ExcludeClassInterceptors excludeClassInterceptors = clazz.getAnnotation(ExcludeClassInterceptors.class);
if (excludeClassInterceptors != null) {
InterceptorBinding binding = assemblyDescriptor.addInterceptorBinding(new InterceptorBinding(bean));
binding.setExcludeClassInterceptors(true);
}
for (Method method : classFinder.findAnnotatedMethods(ExcludeClassInterceptors.class)) {
InterceptorBinding binding = assemblyDescriptor.addInterceptorBinding(new InterceptorBinding(bean));
binding.setExcludeClassInterceptors(true);
binding.setMethod(new NamedMethod(method));
}
/**
* All beans except MDBs have remoting capabilities (busines or legacy interfaces)
*/
if (bean instanceof RemoteBean) {
RemoteBean remoteBean = (RemoteBean) bean;
/*
* @RemoteHome
*/
if (remoteBean.getHome() == null) {
RemoteHome remoteHome = getInheritableAnnotation(clazz, RemoteHome.class);
if (remoteHome != null) {
Class<?> homeClass = remoteHome.value();
try {
Method create = null;
for (Method method : homeClass.getMethods()) {
if (method.getName().startsWith("create")) {
create = method;
break;
}
}
if (create == null) throw new NoSuchMethodException("create");
Class<?> remoteClass = create.getReturnType();
remoteBean.setHome(homeClass.getName());
remoteBean.setRemote(remoteClass.getName());
} catch (NoSuchMethodException e) {
logger.error("Class annotated as a RemoteHome has no 'create()' method. Unable to determine remote interface type. Bean class: " + clazz.getName() + ", Home class: " + homeClass.getName());
}
}
}
/*
* @LocalHome
*/
if (remoteBean.getLocalHome() == null) {
LocalHome localHome = getInheritableAnnotation(clazz, LocalHome.class);
if (localHome != null) {
Class<?> homeClass = localHome.value();
try {
Method create = null;
for (Method method : homeClass.getMethods()) {
if (method.getName().startsWith("create")) {
create = method;
break;
}
}
if (create == null) throw new NoSuchMethodException("create");
Class<?> remoteClass = create.getReturnType();
remoteBean.setLocalHome(homeClass.getName());
remoteBean.setLocal(remoteClass.getName());
} catch (NoSuchMethodException e) {
logger.error("Class annotated as a LocalHome has no 'create()' method. Unable to determine remote interface type. Bean class: " + clazz.getName() + ", Home class: " + homeClass.getName());
}
}
}
/*
* Annotations specific to @Stateless, @Stateful and @Singleton beans
*/
if (remoteBean instanceof SessionBean) {
SessionBean sessionBean = (SessionBean) remoteBean;
/*
* @Remote
* @Local
* @WebService
* @WebServiceProvider
*/
processSessionInterfaces(sessionBean, clazz, ejbModule);
/*
* Annotations specific to @Singleton beans
*/
if (sessionBean.getSessionType() == SessionType.SINGLETON) {
/*
* @ConcurrencyManagement
*/
if (sessionBean.getConcurrencyType() == null) {
ConcurrencyManagement tx = getInheritableAnnotation(clazz, ConcurrencyManagement.class);
ConcurrencyManagementType concurrencyType = ConcurrencyManagementType.CONTAINER;
if (tx != null) {
concurrencyType = tx.value();
}
switch (concurrencyType) {
case BEAN:
sessionBean.setConcurrencyType(ConcurrencyType.BEAN);
break;
case CONTAINER:
sessionBean.setConcurrencyType(ConcurrencyType.CONTAINER);
break;
}
}
/*
* @Lock
*/
if (sessionBean.getConcurrencyType() == ConcurrencyType.CONTAINER) {
processAttributes(new ConcurrencyAttributeHandler(assemblyDescriptor, ejbName), clazz, inheritedClassFinder);
} else {
checkAttributes(new ConcurrencyAttributeHandler(assemblyDescriptor, ejbName), ejbName, ejbModule, classFinder, "invalidConcurrencyAttribute");
}
/*
* @Startup
*/
if (!sessionBean.hasLoadOnStartup()) {
Startup startup = getInheritableAnnotation(clazz, Startup.class);
sessionBean.setLoadOnStartup(startup != null);
}
/*
* @DependsOn
*/
if (sessionBean.getDependsOn() == null) {
DependsOn dependsOn = getInheritableAnnotation(clazz, DependsOn.class);
if (dependsOn != null) {
sessionBean.setDependsOn(dependsOn.value());
} else {
sessionBean.setDependsOn(Collections.EMPTY_LIST);
}
}
}
}
}
if (bean instanceof MessageDrivenBean) {
/*
* @ActivationConfigProperty
*/
MessageDrivenBean mdb = (MessageDrivenBean) bean;
MessageDriven messageDriven = clazz.getAnnotation(MessageDriven.class);
if (messageDriven != null) {
javax.ejb.ActivationConfigProperty[] configProperties = messageDriven.activationConfig();
if (configProperties != null) {
ActivationConfig activationConfig = mdb.getActivationConfig();
if (activationConfig == null) {
activationConfig = new ActivationConfig();
mdb.setActivationConfig(activationConfig);
}
Properties properties = activationConfig.toProperties();
for (javax.ejb.ActivationConfigProperty property : configProperties) {
if (!properties.containsKey(property.propertyName())) {
activationConfig.addProperty(property.propertyName(), property.propertyValue());
}
}
}
if (mdb.getMessagingType() == null) {
Class<?> interfce = messageDriven.messageListenerInterface();
if (interfce != null && !interfce.equals(Object.class)) {
if (!interfce.isInterface()) {
// TODO: Move this check to o.a.o.c.rules.CheckClasses and do it for all MDBs, annotated or not
throw new OpenEJBException("MessageListenerInterface property of @MessageDriven is not an interface");
}
mdb.setMessagingType(interfce.getName());
}
}
}
/*
* Determine the MessageListener interface
*/
if (mdb.getMessagingType() == null) {
List<Class<?>> interfaces = new ArrayList<Class<?>>();
for (Class<?> intf : clazz.getInterfaces()) {
String name = intf.getName();
if (!name.equals("java.io.Serializable") &&
!name.equals("java.io.Externalizable") &&
!name.startsWith("javax.ejb.")) {
interfaces.add(intf);
}
}
if (interfaces.size() != 1) {
String msg = "When annotating a bean class as @MessageDriven without declaring messageListenerInterface, the bean must implement exactly one interface, no more and no less. beanClass=" + clazz.getName() + " interfaces=";
for (Class<?> intf : interfaces) {
msg += intf.getName() + ", ";
}
// TODO: Make this a validation failure, not an exception
throw new IllegalStateException(msg);
}
mdb.setMessagingType(interfaces.get(0).getName());
}
}
// add webservice handler classes to the class finder used in annotation processing
Set<Class<?>> classes = new HashSet<Class<?>>();
classes.add(clazz);
if (ejbModule.getWebservices() != null) {
for (WebserviceDescription webservice : ejbModule.getWebservices().getWebserviceDescription()) {
for (PortComponent port : webservice.getPortComponent()) {
// only process port definitions for this ejb
if (!ejbName.equals(port.getServiceImplBean().getEjbLink())) continue;
if (port.getHandlerChains() == null) continue;
for (org.apache.openejb.jee.HandlerChain handlerChain : port.getHandlerChains().getHandlerChain()) {
for (Handler handler : handlerChain.getHandler()) {
String handlerClass = handler.getHandlerClass();
if (handlerClass != null) {
try {
Class handlerClazz = classLoader.loadClass(handlerClass);
classes.add(handlerClazz);
} catch (ClassNotFoundException e) {
throw new OpenEJBException("Unable to load webservice handler class: " + handlerClass, e);
}
}
}
}
}
}
}
inheritedClassFinder = createInheritedClassFinder(classes.toArray(new Class<?>[classes.size()]));
/*
* @EJB
* @Resource
* @WebServiceRef
* @PersistenceUnit
* @PersistenceContext
*/
buildAnnotatedRefs(bean, inheritedClassFinder, classLoader);
processWebServiceClientHandlers(bean, classLoader);
}
for (Interceptor interceptor : ejbModule.getEjbJar().getInterceptors()) {
Class<?> clazz;
try {
clazz = classLoader.loadClass(interceptor.getInterceptorClass());
} catch (ClassNotFoundException e) {
throw new OpenEJBException("Unable to load interceptor class: " + interceptor.getInterceptorClass(), e);
}
ClassFinder inheritedClassFinder = createInheritedClassFinder(clazz);
/*
* @PostConstruct
* @PreDestroy
* @AroundInvoke