File generatedJar = cmpJarBuilder.getJarFile();
if (generatedJar != null) {
classLoader = ClassLoaderUtil.createClassLoader(appInfo.path, new URL []{generatedJar.toURI().toURL()}, classLoader);
}
final AppContext appContext = new AppContext(appInfo.appId, SystemInstance.get(), classLoader, globalJndiContext, appJndiContext, appInfo.standaloneModule);
appContext.getInjections().addAll(injections);
appContext.getBindings().putAll(globalBindings);
appContext.getBindings().putAll(appBindings);
containerSystem.addAppContext(appContext);
final Context containerSystemContext = containerSystem.getJNDIContext();
if (!SystemInstance.get().hasProperty("openejb.geronimo")) {
// Bean Validation
// ValidatorFactory needs to be put in the map sent to the entity manager factory
// so it has to be constructed before
final List<CommonInfoObject> vfs = new ArrayList<CommonInfoObject>();
for (ClientInfo clientInfo : appInfo.clients) {
vfs.add(clientInfo);
}
for (ConnectorInfo connectorInfo : appInfo.connectors) {
vfs.add(connectorInfo);
}
for (EjbJarInfo ejbJarInfo : appInfo.ejbJars) {
vfs.add(ejbJarInfo);
}
for (WebAppInfo webAppInfo : appInfo.webApps) {
vfs.add(webAppInfo);
}
final Map<String, ValidatorFactory> validatorFactories = new HashMap<String, ValidatorFactory>();
for (CommonInfoObject info : vfs) {
ValidatorFactory factory = null;
try {
factory = ValidatorBuilder.buildFactory(classLoader, info.validationInfo);
} catch (ValidationException ve) {
logger.warning("can't build the validation factory for module " + info.uniqueId, ve);
}
if (factory != null) {
validatorFactories.put(info.uniqueId, factory);
}
}
moduleIds.addAll(validatorFactories.keySet());
// validators bindings
for (Entry<String, ValidatorFactory> validatorFactory : validatorFactories.entrySet()) {
String id = validatorFactory.getKey();
ValidatorFactory factory = validatorFactory.getValue();
try {
containerSystemContext.bind(VALIDATOR_FACTORY_NAMING_CONTEXT + id, factory);
containerSystemContext.bind(VALIDATOR_NAMING_CONTEXT + id, factory.usingContext().getValidator());
} catch (NameAlreadyBoundException e) {
throw new OpenEJBException("ValidatorFactory already exists for module " + id, e);
} catch (Exception e) {
throw new OpenEJBException(e);
}
}
}
// JPA - Persistence Units MUST be processed first since they will add ClassFileTransformers
// to the class loader which must be added before any classes are loaded
Map<String, String> units = new HashMap<String, String>();
PersistenceBuilder persistenceBuilder = new PersistenceBuilder(persistenceClassLoaderHandler);
for (PersistenceUnitInfo info : appInfo.persistenceUnits) {
ReloadableEntityManagerFactory factory;
try {
factory = persistenceBuilder.createEntityManagerFactory(info, classLoader);
containerSystem.getJNDIContext().bind(PERSISTENCE_UNIT_NAMING_CONTEXT + info.id, factory);
units.put(info.name, PERSISTENCE_UNIT_NAMING_CONTEXT + info.id);
} catch (NameAlreadyBoundException e) {
throw new OpenEJBException("PersistenceUnit already deployed: " + info.persistenceUnitRootUrl);
} catch (Exception e) {
throw new OpenEJBException(e);
}
factory.register();
}
// Connectors
for (ConnectorInfo connector : appInfo.connectors) {
ClassLoader oldClassLoader = Thread.currentThread().getContextClassLoader();
Thread.currentThread().setContextClassLoader(classLoader);
try {
// todo add undeployment code for these
if (connector.resourceAdapter != null) {
createResource(connector.resourceAdapter);
}
for (ResourceInfo outbound : connector.outbound) {
createResource(outbound);
}
for (MdbContainerInfo inbound : connector.inbound) {
createContainer(inbound);
}
for (ResourceInfo adminObject : connector.adminObject) {
createResource(adminObject);
}
} finally {
Thread.currentThread().setContextClassLoader(oldClassLoader);
}
}
List<BeanContext> allDeployments = new ArrayList<BeanContext>();
// EJB
EjbJarBuilder ejbJarBuilder = new EjbJarBuilder(props, appContext);
for (EjbJarInfo ejbJar : appInfo.ejbJars) {
HashMap<String, BeanContext> deployments = ejbJarBuilder.build(ejbJar, injections);
JaccPermissionsBuilder jaccPermissionsBuilder = new JaccPermissionsBuilder();
PolicyContext policyContext = jaccPermissionsBuilder.build(ejbJar, deployments);
jaccPermissionsBuilder.install(policyContext);
TransactionPolicyFactory transactionPolicyFactory = createTransactionPolicyFactory(ejbJar, classLoader);
for (BeanContext beanContext : deployments.values()) {
beanContext.setTransactionPolicyFactory(transactionPolicyFactory);
}
MethodTransactionBuilder methodTransactionBuilder = new MethodTransactionBuilder();
methodTransactionBuilder.build(deployments, ejbJar.methodTransactions);
MethodConcurrencyBuilder methodConcurrencyBuilder = new MethodConcurrencyBuilder();
methodConcurrencyBuilder.build(deployments, ejbJar.methodConcurrency);
for (BeanContext beanContext : deployments.values()) {
containerSystem.addDeployment(beanContext);
}
//bind ejbs into global jndi
jndiBuilder.build(ejbJar, deployments);
// setup timers/asynchronous methods - must be after transaction attributes are set
for (BeanContext beanContext : deployments.values()) {
if (beanContext.getComponentType() != BeanType.STATEFUL) {
Method ejbTimeout = beanContext.getEjbTimeout();
boolean timerServiceRequired = false;
if (ejbTimeout != null) {
// If user set the tx attribute to RequiresNew change it to Required so a new transaction is not started
if (beanContext.getTransactionType(ejbTimeout) == TransactionType.RequiresNew) {
beanContext.setMethodTransactionAttribute(ejbTimeout, TransactionType.Required);
}
timerServiceRequired = true;
}
for (Iterator<Map.Entry<Method, MethodContext>> it = beanContext.iteratorMethodContext(); it.hasNext();) {
Map.Entry<Method, MethodContext> entry = it.next();
MethodContext methodContext = entry.getValue();
if (methodContext.getSchedules().size() > 0) {
timerServiceRequired = true;
Method method = entry.getKey();
//TODO Need ?
if (beanContext.getTransactionType(method) == TransactionType.RequiresNew) {
beanContext.setMethodTransactionAttribute(method, TransactionType.Required);
}
}
}
if (timerServiceRequired) {
// Create the timer
EjbTimerServiceImpl timerService = new EjbTimerServiceImpl(beanContext);
//Load auto-start timers
TimerStore timerStore = timerService.getTimerStore();
for (Iterator<Map.Entry<Method, MethodContext>> it = beanContext.iteratorMethodContext(); it.hasNext();) {
Map.Entry<Method, MethodContext> entry = it.next();
MethodContext methodContext = entry.getValue();
for(ScheduleData scheduleData : methodContext.getSchedules()) {
timerStore.createCalendarTimer(timerService, (String) beanContext.getDeploymentID(), null, entry.getKey(), scheduleData.getExpression(), scheduleData.getConfig());
}
}
beanContext.setEjbTimerService(timerService);
} else {
beanContext.setEjbTimerService(new NullEjbTimerServiceImpl());
}
}
//set asynchronous methods transaction
//TODO ???
for (Iterator<Entry<Method, MethodContext>> it = beanContext.iteratorMethodContext(); it.hasNext();) {
Entry<Method, MethodContext> entry = it.next();
if (entry.getValue().isAsynchronous() && beanContext.getTransactionType(entry.getKey()) == TransactionType.RequiresNew) {
beanContext.setMethodTransactionAttribute(entry.getKey(), TransactionType.Required);
}
}
}
// process application exceptions
for (ApplicationExceptionInfo exceptionInfo : ejbJar.applicationException) {
try {
Class exceptionClass = classLoader.loadClass(exceptionInfo.exceptionClass);
for (BeanContext beanContext : deployments.values()) {
beanContext.addApplicationException(exceptionClass, exceptionInfo.rollback, exceptionInfo.inherited);
}
} catch (ClassNotFoundException e) {
logger.error("createApplication.invalidClass", e, exceptionInfo.exceptionClass, e.getMessage());
}
}
allDeployments.addAll(deployments.values());
}
allDeployments = sort(allDeployments);
appContext.getBeanContexts().addAll(allDeployments);
new CdiBuilder().build(appInfo, appContext, allDeployments);
ensureWebBeansContext(appContext);
appJndiContext.bind("app/BeanManager", appContext.getBeanManager());
appContext.getBindings().put("app/BeanManager", appContext.getBeanManager());
// now that everything is configured, deploy to the container
if (start) {
// deploy
for (BeanContext deployment : allDeployments) {
try {
Container container = deployment.getContainer();
container.deploy(deployment);
if (!((String) deployment.getDeploymentID()).endsWith(".Comp")
&& !deployment.isHidden()) {
logger.info("createApplication.createdEjb", deployment.getDeploymentID(), deployment.getEjbName(), container.getContainerID());
}
if (logger.isDebugEnabled()) {
for (Map.Entry<Object, Object> entry : deployment.getProperties().entrySet()) {
logger.info("createApplication.createdEjb.property", deployment.getEjbName(), entry.getKey(), entry.getValue());
}
}
} catch (Throwable t) {
throw new OpenEJBException("Error deploying '"+deployment.getEjbName()+"'. Exception: "+t.getClass()+": "+t.getMessage(), t);
}
}
// start
for (BeanContext deployment : allDeployments) {
try {
Container container = deployment.getContainer();
container.start(deployment);
if (!((String) deployment.getDeploymentID()).endsWith(".Comp")
&& !deployment.isHidden()) {
logger.info("createApplication.startedEjb", deployment.getDeploymentID(), deployment.getEjbName(), container.getContainerID());
}
} catch (Throwable t) {
throw new OpenEJBException("Error starting '"+deployment.getEjbName()+"'. Exception: "+t.getClass()+": "+t.getMessage(), t);
}
}
}
// App Client
for (ClientInfo clientInfo : appInfo.clients) {
// determine the injections
List<Injection> clientInjections = injectionBuilder.buildInjections(clientInfo.jndiEnc);
// build the enc
JndiEncBuilder jndiEncBuilder = new JndiEncBuilder(clientInfo.jndiEnc, clientInjections, "Bean", clientInfo.moduleId, null, clientInfo.uniqueId, classLoader);
// if there is at least a remote client classes
// or if there is no local client classes
// then, we can set the client flag
if ((clientInfo.remoteClients.size() > 0) || (clientInfo.localClients.size() == 0)) {
jndiEncBuilder.setClient(true);
}
jndiEncBuilder.setUseCrossClassLoaderRef(false);
Context context = jndiEncBuilder.build(JndiEncBuilder.JndiScope.comp);
// Debug.printContext(context);
containerSystemContext.bind("openejb/client/" + clientInfo.moduleId, context);
if (clientInfo.path != null) {
context.bind("info/path", clientInfo.path);
}
if (clientInfo.mainClass != null) {
context.bind("info/mainClass", clientInfo.mainClass);
}
if (clientInfo.callbackHandler != null) {
context.bind("info/callbackHandler", clientInfo.callbackHandler);
}
context.bind("info/injections", clientInjections);
for (String clientClassName : clientInfo.remoteClients) {
containerSystemContext.bind("openejb/client/" + clientClassName, clientInfo.moduleId);
}
for (String clientClassName : clientInfo.localClients) {
containerSystemContext.bind("openejb/client/" + clientClassName, clientInfo.moduleId);
logger.getChildLogger("client").info("createApplication.createLocalClient", clientClassName, clientInfo.moduleId);
}
}
SystemInstance systemInstance = SystemInstance.get();
// WebApp
WebAppBuilder webAppBuilder = systemInstance.getComponent(WebAppBuilder.class);
if (webAppBuilder != null) {
webAppBuilder.deployWebApps(appInfo, classLoader);
}
if (start) {
EjbResolver globalEjbResolver = systemInstance.getComponent(EjbResolver.class);
globalEjbResolver.addAll(appInfo.ejbJars);
}
// bind all global values on global context
for (Map.Entry<String, Object> value : appContext.getBindings().entrySet()) {
String path = value.getKey();
if (!path.startsWith("global") || path.equalsIgnoreCase("global/dummy")) { // dummy bound for each app
continue;
}
// a bit weird but just to be consistent if user doesn't lookup directly the resource
Context lastContext = Contexts.createSubcontexts(containerSystemContext, path);
try {
lastContext.bind(path.substring(path.lastIndexOf("/") + 1, path.length()), value.getValue());
} catch (NameAlreadyBoundException nabe) {
nabe.printStackTrace();
}
containerSystemContext.rebind(path, value.getValue());
}
// deploy MBeans
for (String mbean : appInfo.mbeans) {
deployMBean(appContext.getBeanManager(), classLoader, mbean, appInfo.jmx, appInfo.appId);
}
for (EjbJarInfo ejbJarInfo : appInfo.ejbJars) {
for (String mbean : ejbJarInfo.mbeans) {
deployMBean(appContext.getBeanManager(), classLoader, mbean, appInfo.jmx, ejbJarInfo.moduleName);
}
}
for (ConnectorInfo connectorInfo : appInfo.connectors) {
for (String mbean : connectorInfo.mbeans) {
deployMBean(appContext.getBeanManager(), classLoader, mbean, appInfo.jmx, appInfo.appId + ".add-lib");
}
}
logger.info("createApplication.success", appInfo.path);