/** * Copyright (c) 2000-present Liferay, Inc. All rights reserved. * * This library is free software; you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License as published by the Free * Software Foundation; either version 2.1 of the License, or (at your option) * any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. */ package com.liferay.portal.spring.context; import com.liferay.portal.bean.BeanLocatorImpl; import com.liferay.portal.dao.orm.hibernate.FieldInterceptionHelperUtil; import com.liferay.portal.deploy.hot.CustomJspBagRegistryUtil; import com.liferay.portal.deploy.hot.ServiceWrapperRegistry; import com.liferay.portal.kernel.bean.PortalBeanLocatorUtil; import com.liferay.portal.kernel.cache.CacheRegistryUtil; import com.liferay.portal.kernel.cache.MultiVMPoolUtil; import com.liferay.portal.kernel.cache.SingleVMPoolUtil; import com.liferay.portal.kernel.cache.thread.local.ThreadLocalCacheManager; import com.liferay.portal.kernel.dao.db.DBManagerUtil; import com.liferay.portal.kernel.deploy.DeployManagerUtil; import com.liferay.portal.kernel.deploy.hot.HotDeployUtil; import com.liferay.portal.kernel.exception.LoggedExceptionInInitializerError; import com.liferay.portal.kernel.executor.PortalExecutorManager; import com.liferay.portal.kernel.log.Log; import com.liferay.portal.kernel.log.LogFactoryUtil; import com.liferay.portal.kernel.messaging.MessageBus; import com.liferay.portal.kernel.messaging.sender.SingleDestinationMessageSenderFactory; import com.liferay.portal.kernel.portlet.PortletBagPool; import com.liferay.portal.kernel.process.ClassPathUtil; import com.liferay.portal.kernel.scheduler.SchedulerEngineHelper; import com.liferay.portal.kernel.servlet.DirectServletRegistryUtil; import com.liferay.portal.kernel.servlet.PortletSessionListenerManager; import com.liferay.portal.kernel.servlet.SerializableSessionAttributeListener; import com.liferay.portal.kernel.servlet.ServletContextPool; import com.liferay.portal.kernel.template.TemplateResourceLoaderUtil; import com.liferay.portal.kernel.util.CharPool; import com.liferay.portal.kernel.util.ClassLoaderPool; import com.liferay.portal.kernel.util.ClassLoaderUtil; import com.liferay.portal.kernel.util.ClearThreadLocalUtil; import com.liferay.portal.kernel.util.ClearTimerThreadUtil; import com.liferay.portal.kernel.util.InstancePool; import com.liferay.portal.kernel.util.JavaConstants; import com.liferay.portal.kernel.util.MethodCache; import com.liferay.portal.kernel.util.PortalLifecycleUtil; import com.liferay.portal.kernel.util.PropsKeys; import com.liferay.portal.kernel.util.ReferenceRegistry; import com.liferay.portal.kernel.util.ReflectionUtil; import com.liferay.portal.kernel.util.ServerDetector; import com.liferay.portal.kernel.util.StringPool; import com.liferay.portal.kernel.util.StringUtil; import com.liferay.portal.kernel.util.SystemProperties; import com.liferay.portal.kernel.util.Validator; import com.liferay.portal.module.framework.ModuleFrameworkUtilAdapter; import com.liferay.portal.security.lang.SecurityManagerUtil; import com.liferay.portal.servlet.PortalSessionListener; import com.liferay.portal.spring.aop.DynamicProxyCreator; import com.liferay.portal.spring.bean.BeanReferenceRefreshUtil; import com.liferay.portal.util.InitUtil; import com.liferay.portal.util.PropsValues; import com.liferay.portal.util.WebAppPool; import com.liferay.portlet.PortletContextBagPool; import com.liferay.registry.dependency.ServiceDependencyListener; import com.liferay.registry.dependency.ServiceDependencyManager; import java.beans.PropertyDescriptor; import java.io.Closeable; import java.io.File; import java.io.IOException; import java.lang.reflect.Field; import java.util.Map; import javax.servlet.ServletContext; import javax.servlet.ServletContextEvent; import javax.sql.DataSource; import org.springframework.beans.CachedIntrospectionResults; import org.springframework.beans.factory.config.AutowireCapableBeanFactory; import org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory; import org.springframework.context.ApplicationContext; import org.springframework.web.context.ContextLoader; import org.springframework.web.context.ContextLoaderListener; /** * @author Michael Young * @author Shuyang Zhou * @author Raymond Augé */ public class PortalContextLoaderListener extends ContextLoaderListener { public static String getPortalServletContextName() { return _portalServletContextName; } public static String getPortalServletContextPath() { return _portalServletContextPath; } @Override public void contextDestroyed(ServletContextEvent servletContextEvent) { PortalContextLoaderLifecycleThreadLocal.setDestroying(true); ThreadLocalCacheManager.destroy(); if (_serviceWrapperRegistry != null) { _serviceWrapperRegistry.close(); } try { ClearThreadLocalUtil.clearThreadLocal(); } catch (Exception e) { _log.error(e, e); } try { ClearTimerThreadUtil.clearTimerThread(); } catch (Exception e) { _log.error(e, e); } try { DirectServletRegistryUtil.clearServlets(); } catch (Exception e) { _log.error(e, e); } try { HotDeployUtil.reset(); } catch (Exception e) { _log.error(e, e); } try { PortalLifecycleUtil.reset(); } catch (Exception e) { _log.error(e, e); } closeDataSource("counterDataSourceImpl"); closeDataSource("liferayDataSourceImpl"); try { super.contextDestroyed(servletContextEvent); try { ModuleFrameworkUtilAdapter.stopRuntime(); } catch (Exception e) { _log.error(e, e); } try { ModuleFrameworkUtilAdapter.stopFramework( PropsValues.MODULE_FRAMEWORK_STOP_WAIT_TIMEOUT); } catch (Exception e) { _log.error(e, e); } ModuleFrameworkUtilAdapter.unregisterContext( _arrayApplicationContext); _arrayApplicationContext.close(); } finally { PortalContextLoaderLifecycleThreadLocal.setDestroying(false); SecurityManagerUtil.destroy(); } } @Override public void contextInitialized(ServletContextEvent servletContextEvent) { Thread currentThread = Thread.currentThread(); SystemProperties.load(currentThread.getContextClassLoader()); DBManagerUtil.reset(); DeployManagerUtil.reset(); InstancePool.reset(); MethodCache.reset(); PortalBeanLocatorUtil.reset(); PortletBagPool.reset(); ReferenceRegistry.releaseReferences(); FieldInterceptionHelperUtil.initialize(); final ServletContext servletContext = servletContextEvent.getServletContext(); String portalLibDir = servletContext.getRealPath("/WEB-INF/lib"); portalLibDir = StringUtil.replace( portalLibDir, CharPool.BACK_SLASH, CharPool.FORWARD_SLASH); if (Validator.isNotNull(portalLibDir)) { SystemProperties.set( PropsKeys.LIFERAY_LIB_PORTAL_DIR, portalLibDir); } ClassPathUtil.initializeClassPaths(servletContext); InitUtil.init(); _portalServletContextName = servletContext.getServletContextName(); if (_portalServletContextName == null) { _portalServletContextName = StringPool.BLANK; } if (ServerDetector.isJetty() && _portalServletContextName.equals(StringPool.SLASH)) { _portalServletContextName = StringPool.BLANK; } _portalServletContextPath = servletContext.getContextPath(); File tempDir = (File)servletContext.getAttribute( JavaConstants.JAVAX_SERVLET_CONTEXT_TEMPDIR); PropsValues.LIFERAY_WEB_PORTAL_CONTEXT_TEMPDIR = tempDir.getAbsolutePath(); try { ModuleFrameworkUtilAdapter.initFramework(); _arrayApplicationContext = new ArrayApplicationContext( PropsValues.SPRING_INFRASTRUCTURE_CONFIGS); servletContext.setAttribute( PortalApplicationContext.PARENT_APPLICATION_CONTEXT, _arrayApplicationContext); ModuleFrameworkUtilAdapter.registerContext( _arrayApplicationContext); ModuleFrameworkUtilAdapter.startFramework(); ModuleFrameworkUtilAdapter.startRuntime(); } catch (Exception e) { throw new RuntimeException(e); } ServiceDependencyManager serviceDependencyManager = new ServiceDependencyManager(); serviceDependencyManager.addServiceDependencyListener( new ServiceDependencyListener() { @Override public void dependenciesFulfilled() { _serviceWrapperRegistry = new ServiceWrapperRegistry(); } @Override public void destroy() { } }); serviceDependencyManager.registerDependencies( MessageBus.class, PortalExecutorManager.class, SchedulerEngineHelper.class, SingleDestinationMessageSenderFactory.class); ClassLoader portalClassLoader = ClassLoaderUtil.getPortalClassLoader(); ClassLoaderPool.register(_portalServletContextName, portalClassLoader); PortalContextLoaderLifecycleThreadLocal.setInitializing(true); try { super.contextInitialized(servletContextEvent); } finally { PortalContextLoaderLifecycleThreadLocal.setInitializing(false); } ApplicationContext applicationContext = ContextLoader.getCurrentWebApplicationContext(); try { BeanReferenceRefreshUtil.refresh( applicationContext.getAutowireCapableBeanFactory()); } catch (Exception e) { _log.error(e, e); } InitUtil.registerSpringInitialized(); if (PropsValues.CACHE_CLEAR_ON_CONTEXT_INITIALIZATION) { CacheRegistryUtil.clear(); PortletContextBagPool.clear(); WebAppPool.clear(); TemplateResourceLoaderUtil.clearCache(); ServletContextPool.clear(); MultiVMPoolUtil.clear(); SingleVMPoolUtil.clear(); } ServletContextPool.put(_portalServletContextName, servletContext); BeanLocatorImpl beanLocatorImpl = new BeanLocatorImpl( portalClassLoader, applicationContext); PortalBeanLocatorUtil.setBeanLocator(beanLocatorImpl); ClassLoader classLoader = portalClassLoader; while (classLoader != null) { CachedIntrospectionResults.clearClassLoader(classLoader); classLoader = classLoader.getParent(); } AutowireCapableBeanFactory autowireCapableBeanFactory = applicationContext.getAutowireCapableBeanFactory(); clearFilteredPropertyDescriptorsCache(autowireCapableBeanFactory); DynamicProxyCreator dynamicProxyCreator = DynamicProxyCreator.getDynamicProxyCreator(); dynamicProxyCreator.clear(); try { ModuleFrameworkUtilAdapter.registerContext(applicationContext); } catch (Exception e) { throw new RuntimeException(e); } CustomJspBagRegistryUtil.getCustomJspBags(); initListeners(servletContext); } protected void clearFilteredPropertyDescriptorsCache( AutowireCapableBeanFactory autowireCapableBeanFactory) { try { Map<Class<?>, PropertyDescriptor[]> filteredPropertyDescriptorsCache = (Map<Class<?>, PropertyDescriptor[]>) _FILTERED_PROPERTY_DESCRIPTORS_CACHE_FIELD.get( autowireCapableBeanFactory); filteredPropertyDescriptorsCache.clear(); } catch (Exception e) { _log.error(e, e); } } protected void closeDataSource(String name) { DataSource dataSource = (DataSource)PortalBeanLocatorUtil.locate(name); if (dataSource instanceof Closeable) { try { Closeable closeable = (Closeable)dataSource; closeable.close(); } catch (IOException ioe) { _log.error(ioe, ioe); } } } protected void initListeners(ServletContext servletContext) { if (PropsValues.SESSION_VERIFY_SERIALIZABLE_ATTRIBUTE) { servletContext.addListener( SerializableSessionAttributeListener.class); } servletContext.addListener(PortalSessionListener.class); servletContext.addListener(PortletSessionListenerManager.class); } private static final Field _FILTERED_PROPERTY_DESCRIPTORS_CACHE_FIELD; private static final Log _log = LogFactoryUtil.getLog( PortalContextLoaderListener.class); private static String _portalServletContextName = StringPool.BLANK; private static String _portalServletContextPath = StringPool.SLASH; static { try { _FILTERED_PROPERTY_DESCRIPTORS_CACHE_FIELD = ReflectionUtil.getDeclaredField( AbstractAutowireCapableBeanFactory.class, "filteredPropertyDescriptorsCache"); } catch (Exception e) { throw new LoggedExceptionInInitializerError(e); } } private ArrayApplicationContext _arrayApplicationContext; private ServiceWrapperRegistry _serviceWrapperRegistry; }