use of org.apache.openejb.core.ivm.naming.ContextualJndiReference in project tomee by apache.
the class Assembler method destroyApplication.
public void destroyApplication(final AppInfo appInfo) throws UndeployException {
final ReentrantLock l = lock;
l.lock();
try {
deployedApplications.remove(appInfo.path);
logger.info("destroyApplication.start", appInfo.path);
final Context globalContext = containerSystem.getJNDIContext();
final AppContext appContext = containerSystem.getAppContext(appInfo.appId);
final ClassLoader classLoader = appContext.getClassLoader();
SystemInstance.get().fireEvent(new AssemblerBeforeApplicationDestroyed(appInfo, appContext));
//noinspection ConstantConditions
if (null == appContext) {
logger.warning("Application id '" + appInfo.appId + "' not found in: " + Arrays.toString(containerSystem.getAppContextKeys()));
return;
} else {
final WebBeansContext webBeansContext = appContext.getWebBeansContext();
if (webBeansContext != null) {
final ClassLoader old = Thread.currentThread().getContextClassLoader();
Thread.currentThread().setContextClassLoader(classLoader);
try {
final ServletContext context = appContext.isStandaloneModule() && appContext.getWebContexts().iterator().hasNext() ? appContext.getWebContexts().iterator().next().getServletContext() : null;
webBeansContext.getService(ContainerLifecycle.class).stopApplication(context);
} finally {
Thread.currentThread().setContextClassLoader(old);
}
}
final Map<String, Object> cb = appContext.getBindings();
for (final Entry<String, Object> value : cb.entrySet()) {
String path = value.getKey();
if (path.startsWith("global")) {
path = "java:" + path;
}
if (!path.startsWith("java:global")) {
continue;
}
unbind(globalContext, path);
unbind(globalContext, "openejb/global/" + path.substring("java:".length()));
unbind(globalContext, path.substring("java:global".length()));
}
if (appInfo.appId != null && !appInfo.appId.isEmpty() && !"openejb".equals(appInfo.appId)) {
unbind(globalContext, "global/" + appInfo.appId);
unbind(globalContext, appInfo.appId);
}
}
final EjbResolver globalResolver = new EjbResolver(null, EjbResolver.Scope.GLOBAL);
for (final AppInfo info : deployedApplications.values()) {
globalResolver.addAll(info.ejbJars);
}
SystemInstance.get().setComponent(EjbResolver.class, globalResolver);
final UndeployException undeployException = new UndeployException(messages.format("destroyApplication.failed", appInfo.path));
final WebAppBuilder webAppBuilder = SystemInstance.get().getComponent(WebAppBuilder.class);
if (webAppBuilder != null && !appInfo.webAppAlone) {
try {
webAppBuilder.undeployWebApps(appInfo);
} catch (final Exception e) {
undeployException.getCauses().add(new Exception("App: " + appInfo.path + ": " + e.getMessage(), e));
}
}
// get all of the ejb deployments
List<BeanContext> deployments = new ArrayList<BeanContext>();
for (final EjbJarInfo ejbJarInfo : appInfo.ejbJars) {
for (final EnterpriseBeanInfo beanInfo : ejbJarInfo.enterpriseBeans) {
final String deploymentId = beanInfo.ejbDeploymentId;
final BeanContext beanContext = containerSystem.getBeanContext(deploymentId);
if (beanContext == null) {
undeployException.getCauses().add(new Exception("deployment not found: " + deploymentId));
} else {
deployments.add(beanContext);
}
}
}
// Just as with startup we need to get things in an
// order that respects the singleton @DependsOn information
// Theoreticlly if a Singleton depends on something in its
// @PostConstruct, it can depend on it in its @PreDestroy.
// Therefore we want to make sure that if A dependsOn B,
// that we destroy A first then B so that B will still be
// usable in the @PreDestroy method of A.
// Sort them into the original starting order
deployments = sort(deployments);
// reverse that to get the stopping order
Collections.reverse(deployments);
// stop
for (final BeanContext deployment : deployments) {
final String deploymentID = String.valueOf(deployment.getDeploymentID());
try {
final Container container = deployment.getContainer();
container.stop(deployment);
} catch (final Throwable t) {
undeployException.getCauses().add(new Exception("bean: " + deploymentID + ": " + t.getMessage(), t));
}
}
// undeploy
for (final BeanContext bean : deployments) {
final String deploymentID = String.valueOf(bean.getDeploymentID());
try {
final Container container = bean.getContainer();
container.undeploy(bean);
bean.setContainer(null);
} catch (final Throwable t) {
undeployException.getCauses().add(new Exception("bean: " + deploymentID + ": " + t.getMessage(), t));
} finally {
bean.setDestroyed(true);
}
}
if (webAppBuilder != null && appInfo.webAppAlone) {
// now that EJB are stopped we can undeploy webapps
try {
webAppBuilder.undeployWebApps(appInfo);
} catch (final Exception e) {
undeployException.getCauses().add(new Exception("App: " + appInfo.path + ": " + e.getMessage(), e));
}
}
// get the client ids
final List<String> clientIds = new ArrayList<String>();
for (final ClientInfo clientInfo : appInfo.clients) {
clientIds.add(clientInfo.moduleId);
for (final String className : clientInfo.localClients) {
clientIds.add(className);
}
for (final String className : clientInfo.remoteClients) {
clientIds.add(className);
}
}
for (final WebContext webContext : appContext.getWebContexts()) {
containerSystem.removeWebContext(webContext);
}
TldScanner.forceCompleteClean(classLoader);
// Clear out naming for all components first
for (final BeanContext deployment : deployments) {
final String deploymentID = String.valueOf(deployment.getDeploymentID());
try {
containerSystem.removeBeanContext(deployment);
} catch (final Throwable t) {
undeployException.getCauses().add(new Exception(deploymentID, t));
}
final JndiBuilder.Bindings bindings = deployment.get(JndiBuilder.Bindings.class);
if (bindings != null) {
for (final String name : bindings.getBindings()) {
try {
globalContext.unbind(name);
} catch (final Throwable t) {
undeployException.getCauses().add(new Exception("bean: " + deploymentID + ": " + t.getMessage(), t));
}
}
}
}
// stop this executor only now since @PreDestroy can trigger some stop events
final AsynchronousPool pool = appContext.get(AsynchronousPool.class);
if (pool != null) {
pool.stop();
}
for (final CommonInfoObject jar : listCommonInfoObjectsForAppInfo(appInfo)) {
try {
globalContext.unbind(VALIDATOR_FACTORY_NAMING_CONTEXT + jar.uniqueId);
globalContext.unbind(VALIDATOR_NAMING_CONTEXT + jar.uniqueId);
} catch (final NamingException e) {
if (EjbJarInfo.class.isInstance(jar)) {
undeployException.getCauses().add(new Exception("validator: " + jar.uniqueId + ": " + e.getMessage(), e));
}
// else an error but not that important
}
}
try {
if (globalContext instanceof IvmContext) {
final IvmContext ivmContext = (IvmContext) globalContext;
ivmContext.prune("openejb/Deployment");
ivmContext.prune("openejb/local");
ivmContext.prune("openejb/remote");
ivmContext.prune("openejb/global");
}
} catch (final NamingException e) {
undeployException.getCauses().add(new Exception("Unable to prune openejb/Deployments and openejb/local namespaces, this could cause future deployments to fail.", e));
}
deployments.clear();
for (final String clientId : clientIds) {
try {
globalContext.unbind("/openejb/client/" + clientId);
} catch (final Throwable t) {
undeployException.getCauses().add(new Exception("client: " + clientId + ": " + t.getMessage(), t));
}
}
// mbeans
final MBeanServer server = LocalMBeanServer.get();
for (final Object objectName : appInfo.jmx.values()) {
try {
final ObjectName on = new ObjectName((String) objectName);
if (server.isRegistered(on)) {
server.unregisterMBean(on);
}
final CreationalContext cc = creationalContextForAppMbeans.remove(on);
if (cc != null) {
cc.release();
}
} catch (final InstanceNotFoundException e) {
logger.warning("can't unregister " + objectName + " because the mbean was not found", e);
} catch (final MBeanRegistrationException e) {
logger.warning("can't unregister " + objectName, e);
} catch (final MalformedObjectNameException mone) {
logger.warning("can't unregister because the ObjectName is malformed: " + objectName, mone);
}
}
// destroy PUs before resources since the JPA provider can use datasources
for (final PersistenceUnitInfo unitInfo : appInfo.persistenceUnits) {
try {
final Object object = globalContext.lookup(PERSISTENCE_UNIT_NAMING_CONTEXT + unitInfo.id);
globalContext.unbind(PERSISTENCE_UNIT_NAMING_CONTEXT + unitInfo.id);
// close EMF so all resources are released
final ReloadableEntityManagerFactory remf = (ReloadableEntityManagerFactory) object;
remf.close();
persistenceClassLoaderHandler.destroy(unitInfo.id);
remf.unregister();
} catch (final Throwable t) {
undeployException.getCauses().add(new Exception("persistence-unit: " + unitInfo.id + ": " + t.getMessage(), t));
}
}
for (final String id : appInfo.resourceAliases) {
final String name = OPENEJB_RESOURCE_JNDI_PREFIX + id;
ContextualJndiReference.followReference.set(false);
try {
final Object object;
try {
object = globalContext.lookup(name);
} finally {
ContextualJndiReference.followReference.remove();
}
if (object instanceof ContextualJndiReference) {
final ContextualJndiReference contextualJndiReference = ContextualJndiReference.class.cast(object);
contextualJndiReference.removePrefix(appContext.getId());
if (contextualJndiReference.hasNoMorePrefix()) {
globalContext.unbind(name);
}
// else not the last deployed application to use this resource so keep it
} else {
globalContext.unbind(name);
}
} catch (final NamingException e) {
logger.warning("can't unbind resource '{0}'", id);
}
}
for (final String id : appInfo.resourceIds) {
final String name = OPENEJB_RESOURCE_JNDI_PREFIX + id;
try {
destroyLookedUpResource(globalContext, id, name);
} catch (final NamingException e) {
logger.warning("can't unbind resource '{0}'", id);
}
}
for (final ConnectorInfo connector : appInfo.connectors) {
if (connector.resourceAdapter == null || connector.resourceAdapter.id == null) {
continue;
}
final String name = OPENEJB_RESOURCE_JNDI_PREFIX + connector.resourceAdapter.id;
try {
destroyLookedUpResource(globalContext, connector.resourceAdapter.id, name);
} catch (final NamingException e) {
logger.warning("can't unbind resource '{0}'", connector);
}
for (final ResourceInfo outbound : connector.outbound) {
try {
destroyLookedUpResource(globalContext, outbound.id, OPENEJB_RESOURCE_JNDI_PREFIX + outbound.id);
} catch (final Exception e) {
// no-op
}
}
for (final ResourceInfo outbound : connector.adminObject) {
try {
destroyLookedUpResource(globalContext, outbound.id, OPENEJB_RESOURCE_JNDI_PREFIX + outbound.id);
} catch (final Exception e) {
// no-op
}
}
for (final MdbContainerInfo container : connector.inbound) {
try {
containerSystem.removeContainer(container.id);
config.containerSystem.containers.remove(container);
this.containerSystem.getJNDIContext().unbind(JAVA_OPENEJB_NAMING_CONTEXT + container.service + "/" + container.id);
} catch (final Exception e) {
// no-op
}
}
}
for (final String id : appInfo.containerIds) {
removeContainer(id);
}
containerSystem.removeAppContext(appInfo.appId);
if (!appInfo.properties.containsKey("tomee.destroying")) {
// destroy tomee classloader after resources cleanup
try {
final Method m = classLoader.getClass().getMethod("internalStop");
m.invoke(classLoader);
} catch (final NoSuchMethodException nsme) {
// no-op
} catch (final Exception e) {
logger.error("error stopping classloader of webapp " + appInfo.appId, e);
}
ClassLoaderUtil.cleanOpenJPACache(classLoader);
}
ClassLoaderUtil.destroyClassLoader(appInfo.appId, appInfo.path);
if (undeployException.getCauses().size() > 0) {
throw undeployException;
}
logger.debug("destroyApplication.success", appInfo.path);
} finally {
l.unlock();
}
}
use of org.apache.openejb.core.ivm.naming.ContextualJndiReference in project tomee by apache.
the class Assembler method bindResource.
private void bindResource(final String id, final Object service, final boolean canReplace) throws OpenEJBException {
final String name = OPENEJB_RESOURCE_JNDI_PREFIX + id;
final Context jndiContext = containerSystem.getJNDIContext();
Object existing = null;
try {
ContextualJndiReference.followReference.set(false);
existing = jndiContext.lookup(name);
} catch (final Exception ignored) {
// no-op
} finally {
// if the lookup fails the remove is not done
ContextualJndiReference.followReference.remove();
}
boolean rebind = false;
if (existing != null) {
final boolean existingIsContextual = ContextualJndiReference.class.isInstance(existing);
final boolean serviceIsExisting = ContextualJndiReference.class.isInstance(service);
if (!existingIsContextual && serviceIsExisting) {
ContextualJndiReference.class.cast(service).setDefaultValue(existing);
rebind = true;
} else if (existingIsContextual && !serviceIsExisting) {
ContextualJndiReference.class.cast(existing).setDefaultValue(service);
} else if (existingIsContextual) {
// && serviceIsExisting is always true here
final ContextualJndiReference contextual = ContextualJndiReference.class.cast(existing);
if (canReplace && contextual.prefixesSize() == 1) {
// replace!
contextual.removePrefix(contextual.lastPrefix());
contextual.setDefaultValue(service);
} else {
contextual.addPrefix(ContextualJndiReference.class.cast(service).lastPrefix());
}
return;
}
}
try {
if (canReplace && existing != null) {
jndiContext.unbind(name);
}
if (rebind) {
jndiContext.rebind(name, service);
} else {
jndiContext.bind(name, service);
}
} catch (final NameAlreadyBoundException nabe) {
logger.warning("unbounding resource " + name + " can happen because of a redeployment or because of a duplicated id");
try {
jndiContext.unbind(name);
jndiContext.bind(name, service);
} catch (final NamingException e) {
throw new OpenEJBException("Cannot bind resource adapter with id " + id, e);
}
} catch (final NamingException e) {
throw new OpenEJBException("Cannot bind resource adapter with id " + id, e);
}
}
use of org.apache.openejb.core.ivm.naming.ContextualJndiReference in project tomee by apache.
the class Assembler method createResource.
public void createResource(final Collection<ServiceInfo> infos, final ResourceInfo serviceInfo) throws OpenEJBException {
final boolean usesCdiPwdCipher = usesCdiPwdCipher(serviceInfo);
final Object service = "true".equalsIgnoreCase(String.valueOf(serviceInfo.properties.remove("Lazy"))) || usesCdiPwdCipher ? newLazyResource(infos, serviceInfo) : doCreateResource(infos, serviceInfo);
if (usesCdiPwdCipher && !serviceInfo.properties.contains("InitializeAfterDeployment")) {
serviceInfo.properties.put("InitializeAfterDeployment", "true");
}
bindResource(serviceInfo.id, service, false);
for (final String alias : serviceInfo.aliases) {
bindResource(alias, service, false);
}
if (serviceInfo.originAppName != null && !serviceInfo.originAppName.isEmpty() && !"/".equals(serviceInfo.originAppName) && !serviceInfo.id.startsWith("global")) {
final String baseJndiName = serviceInfo.id.substring(serviceInfo.originAppName.length() + 1);
serviceInfo.aliases.add(baseJndiName);
final ContextualJndiReference ref = new ContextualJndiReference(baseJndiName);
ref.addPrefix(serviceInfo.originAppName);
bindResource(baseJndiName, ref, false);
}
// Update the config tree
config.facilities.resources.add(serviceInfo);
if (logger.isDebugEnabled()) {
// weird to check parent logger but save time and it is almost never activated
logger.getChildLogger("service").debug("createService.success", serviceInfo.service, serviceInfo.id, serviceInfo.className);
}
}
Aggregations