001
014
015 package com.liferay.portal.spring.context;
016
017 import com.liferay.portal.bean.BeanLocatorImpl;
018 import com.liferay.portal.dao.orm.hibernate.FieldInterceptionHelperUtil;
019 import com.liferay.portal.deploy.hot.CustomJspBagRegistryUtil;
020 import com.liferay.portal.deploy.hot.ServiceWrapperRegistry;
021 import com.liferay.portal.kernel.bean.PortalBeanLocatorUtil;
022 import com.liferay.portal.kernel.cache.CacheRegistryUtil;
023 import com.liferay.portal.kernel.cache.MultiVMPoolUtil;
024 import com.liferay.portal.kernel.cache.SingleVMPoolUtil;
025 import com.liferay.portal.kernel.cache.thread.local.ThreadLocalCacheManager;
026 import com.liferay.portal.kernel.dao.db.DBManagerUtil;
027 import com.liferay.portal.kernel.deploy.DeployManagerUtil;
028 import com.liferay.portal.kernel.deploy.hot.HotDeployUtil;
029 import com.liferay.portal.kernel.exception.LoggedExceptionInInitializerError;
030 import com.liferay.portal.kernel.executor.PortalExecutorManager;
031 import com.liferay.portal.kernel.log.Log;
032 import com.liferay.portal.kernel.log.LogFactoryUtil;
033 import com.liferay.portal.kernel.messaging.MessageBus;
034 import com.liferay.portal.kernel.messaging.sender.SingleDestinationMessageSenderFactory;
035 import com.liferay.portal.kernel.portlet.PortletBagPool;
036 import com.liferay.portal.kernel.process.ClassPathUtil;
037 import com.liferay.portal.kernel.scheduler.SchedulerEngineHelper;
038 import com.liferay.portal.kernel.servlet.DirectServletRegistryUtil;
039 import com.liferay.portal.kernel.servlet.SerializableSessionAttributeListener;
040 import com.liferay.portal.kernel.servlet.ServletContextPool;
041 import com.liferay.portal.kernel.template.TemplateResourceLoaderUtil;
042 import com.liferay.portal.kernel.util.CharPool;
043 import com.liferay.portal.kernel.util.ClassLoaderPool;
044 import com.liferay.portal.kernel.util.ClassLoaderUtil;
045 import com.liferay.portal.kernel.util.ClearThreadLocalUtil;
046 import com.liferay.portal.kernel.util.ClearTimerThreadUtil;
047 import com.liferay.portal.kernel.util.InstancePool;
048 import com.liferay.portal.kernel.util.JavaConstants;
049 import com.liferay.portal.kernel.util.MethodCache;
050 import com.liferay.portal.kernel.util.PortalLifecycleUtil;
051 import com.liferay.portal.kernel.util.PropsKeys;
052 import com.liferay.portal.kernel.util.ReferenceRegistry;
053 import com.liferay.portal.kernel.util.ReflectionUtil;
054 import com.liferay.portal.kernel.util.ServerDetector;
055 import com.liferay.portal.kernel.util.StringPool;
056 import com.liferay.portal.kernel.util.StringUtil;
057 import com.liferay.portal.kernel.util.SystemProperties;
058 import com.liferay.portal.kernel.util.Validator;
059 import com.liferay.portal.module.framework.ModuleFrameworkUtilAdapter;
060 import com.liferay.portal.security.lang.SecurityManagerUtil;
061 import com.liferay.portal.spring.bean.BeanReferenceRefreshUtil;
062 import com.liferay.portal.util.InitUtil;
063 import com.liferay.portal.util.PropsValues;
064 import com.liferay.portal.util.WebAppPool;
065 import com.liferay.portlet.PortletContextBagPool;
066 import com.liferay.registry.dependency.ServiceDependencyListener;
067 import com.liferay.registry.dependency.ServiceDependencyManager;
068
069 import java.beans.PropertyDescriptor;
070
071 import java.io.Closeable;
072 import java.io.File;
073 import java.io.IOException;
074
075 import java.lang.reflect.Field;
076
077 import java.util.Map;
078
079 import javax.servlet.ServletContext;
080 import javax.servlet.ServletContextEvent;
081
082 import javax.sql.DataSource;
083
084 import org.springframework.beans.CachedIntrospectionResults;
085 import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
086 import org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory;
087 import org.springframework.context.ApplicationContext;
088 import org.springframework.web.context.ContextLoader;
089 import org.springframework.web.context.ContextLoaderListener;
090
091
096 public class PortalContextLoaderListener extends ContextLoaderListener {
097
098 public static String getPortalServletContextName() {
099 return _portalServletContextName;
100 }
101
102 public static String getPortalServletContextPath() {
103 return _portalServletContextPath;
104 }
105
106 @Override
107 public void contextDestroyed(ServletContextEvent servletContextEvent) {
108 PortalContextLoaderLifecycleThreadLocal.setDestroying(true);
109
110 ThreadLocalCacheManager.destroy();
111
112 if (_serviceWrapperRegistry != null) {
113 _serviceWrapperRegistry.close();
114 }
115
116 try {
117 ClearThreadLocalUtil.clearThreadLocal();
118 }
119 catch (Exception e) {
120 _log.error(e, e);
121 }
122
123 try {
124 ClearTimerThreadUtil.clearTimerThread();
125 }
126 catch (Exception e) {
127 _log.error(e, e);
128 }
129
130 try {
131 DirectServletRegistryUtil.clearServlets();
132 }
133 catch (Exception e) {
134 _log.error(e, e);
135 }
136
137 try {
138 HotDeployUtil.reset();
139 }
140 catch (Exception e) {
141 _log.error(e, e);
142 }
143
144 try {
145 ModuleFrameworkUtilAdapter.stopRuntime();
146 }
147 catch (Exception e) {
148 _log.error(e, e);
149 }
150
151 try {
152 PortalLifecycleUtil.reset();
153 }
154 catch (Exception e) {
155 _log.error(e, e);
156 }
157
158 closeDataSource("counterDataSourceImpl");
159
160 closeDataSource("liferayDataSourceImpl");
161
162 try {
163 super.contextDestroyed(servletContextEvent);
164
165 try {
166 ModuleFrameworkUtilAdapter.stopFramework(
167 PropsValues.MODULE_FRAMEWORK_STOP_WAIT_TIMEOUT);
168 }
169 catch (Exception e) {
170 _log.error(e, e);
171 }
172
173 _arrayApplicationContext.close();
174 }
175 finally {
176 PortalContextLoaderLifecycleThreadLocal.setDestroying(false);
177
178 SecurityManagerUtil.destroy();
179 }
180 }
181
182 @Override
183 public void contextInitialized(ServletContextEvent servletContextEvent) {
184 Thread currentThread = Thread.currentThread();
185
186 SystemProperties.load(currentThread.getContextClassLoader());
187
188 DBManagerUtil.reset();
189 DeployManagerUtil.reset();
190 InstancePool.reset();
191 MethodCache.reset();
192 PortalBeanLocatorUtil.reset();
193 PortletBagPool.reset();
194
195 ReferenceRegistry.releaseReferences();
196
197 FieldInterceptionHelperUtil.initialize();
198
199 final ServletContext servletContext =
200 servletContextEvent.getServletContext();
201
202 String portalLibDir = servletContext.getRealPath("/WEB-INF/lib");
203
204 portalLibDir = StringUtil.replace(
205 portalLibDir, CharPool.BACK_SLASH, CharPool.FORWARD_SLASH);
206
207 if (Validator.isNotNull(portalLibDir)) {
208 SystemProperties.set(
209 PropsKeys.LIFERAY_LIB_PORTAL_DIR, portalLibDir);
210 }
211
212 InitUtil.init();
213
214 _portalServletContextName = servletContext.getServletContextName();
215
216 if (_portalServletContextName == null) {
217 _portalServletContextName = StringPool.BLANK;
218 }
219
220 if (ServerDetector.isJetty() &&
221 _portalServletContextName.equals(StringPool.SLASH)) {
222
223 _portalServletContextName = StringPool.BLANK;
224 }
225
226 _portalServletContextPath = servletContext.getContextPath();
227
228 if (ServerDetector.isWebSphere() &&
229 _portalServletContextPath.isEmpty()) {
230
231 _portalServletContextName = StringPool.BLANK;
232 }
233
234 ClassPathUtil.initializeClassPaths(servletContext);
235
236 File tempDir = (File)servletContext.getAttribute(
237 JavaConstants.JAVAX_SERVLET_CONTEXT_TEMPDIR);
238
239 PropsValues.LIFERAY_WEB_PORTAL_CONTEXT_TEMPDIR =
240 tempDir.getAbsolutePath();
241
242 try {
243 ModuleFrameworkUtilAdapter.initFramework();
244
245 _arrayApplicationContext = new ArrayApplicationContext(
246 PropsValues.SPRING_INFRASTRUCTURE_CONFIGS);
247
248 servletContext.setAttribute(
249 PortalApplicationContext.PARENT_APPLICATION_CONTEXT,
250 _arrayApplicationContext);
251
252 ModuleFrameworkUtilAdapter.registerContext(
253 _arrayApplicationContext);
254
255 ModuleFrameworkUtilAdapter.startFramework();
256 }
257 catch (Exception e) {
258 throw new RuntimeException(e);
259 }
260
261 ServiceDependencyManager serviceDependencyManager =
262 new ServiceDependencyManager();
263
264 serviceDependencyManager.addServiceDependencyListener(
265 new ServiceDependencyListener() {
266
267 @Override
268 public void destroy() {
269 }
270
271 @Override
272 public void dependenciesFulfilled() {
273 _serviceWrapperRegistry = new ServiceWrapperRegistry();
274 }
275
276 });
277
278 serviceDependencyManager.registerDependencies(
279 MessageBus.class, PortalExecutorManager.class,
280 SchedulerEngineHelper.class,
281 SingleDestinationMessageSenderFactory.class);
282
283 ClassLoader portalClassLoader = ClassLoaderUtil.getPortalClassLoader();
284
285 ClassLoaderPool.register(_portalServletContextName, portalClassLoader);
286
287 PortalContextLoaderLifecycleThreadLocal.setInitializing(true);
288
289 try {
290 super.contextInitialized(servletContextEvent);
291 }
292 finally {
293 PortalContextLoaderLifecycleThreadLocal.setInitializing(false);
294 }
295
296 ApplicationContext applicationContext =
297 ContextLoader.getCurrentWebApplicationContext();
298
299 try {
300 BeanReferenceRefreshUtil.refresh(
301 applicationContext.getAutowireCapableBeanFactory());
302 }
303 catch (Exception e) {
304 _log.error(e, e);
305 }
306
307 if (PropsValues.CACHE_CLEAR_ON_CONTEXT_INITIALIZATION) {
308 CacheRegistryUtil.clear();
309 PortletContextBagPool.clear();
310 WebAppPool.clear();
311
312 TemplateResourceLoaderUtil.clearCache();
313
314 ServletContextPool.clear();
315
316 MultiVMPoolUtil.clear();
317 SingleVMPoolUtil.clear();
318 }
319
320 ServletContextPool.put(_portalServletContextName, servletContext);
321
322 BeanLocatorImpl beanLocatorImpl = new BeanLocatorImpl(
323 portalClassLoader, applicationContext);
324
325 PortalBeanLocatorUtil.setBeanLocator(beanLocatorImpl);
326
327 ClassLoader classLoader = portalClassLoader;
328
329 while (classLoader != null) {
330 CachedIntrospectionResults.clearClassLoader(classLoader);
331
332 classLoader = classLoader.getParent();
333 }
334
335 AutowireCapableBeanFactory autowireCapableBeanFactory =
336 applicationContext.getAutowireCapableBeanFactory();
337
338 clearFilteredPropertyDescriptorsCache(autowireCapableBeanFactory);
339
340 try {
341 ModuleFrameworkUtilAdapter.registerContext(applicationContext);
342
343 ModuleFrameworkUtilAdapter.startRuntime();
344 }
345 catch (Exception e) {
346 throw new RuntimeException(e);
347 }
348
349 CustomJspBagRegistryUtil.getCustomJspBags();
350
351 initListeners(servletContext);
352 }
353
354 protected void clearFilteredPropertyDescriptorsCache(
355 AutowireCapableBeanFactory autowireCapableBeanFactory) {
356
357 try {
358 Map<Class<?>, PropertyDescriptor[]>
359 filteredPropertyDescriptorsCache =
360 (Map<Class<?>, PropertyDescriptor[]>)
361 _FILTERED_PROPERTY_DESCRIPTORS_CACHE_FIELD.get(
362 autowireCapableBeanFactory);
363
364 filteredPropertyDescriptorsCache.clear();
365 }
366 catch (Exception e) {
367 _log.error(e, e);
368 }
369 }
370
371 protected void closeDataSource(String name) {
372 DataSource dataSource = (DataSource)PortalBeanLocatorUtil.locate(name);
373
374 if (dataSource instanceof Closeable) {
375 try {
376 Closeable closeable = (Closeable)dataSource;
377
378 closeable.close();
379 }
380 catch (IOException e) {
381 _log.error(e, e);
382 }
383 }
384 }
385
386 protected void initListeners(ServletContext servletContext) {
387 if (PropsValues.SESSION_VERIFY_SERIALIZABLE_ATTRIBUTE) {
388 servletContext.addListener(
389 SerializableSessionAttributeListener.class);
390 }
391 }
392
393 private static final Field _FILTERED_PROPERTY_DESCRIPTORS_CACHE_FIELD;
394
395 private static final Log _log = LogFactoryUtil.getLog(
396 PortalContextLoaderListener.class);
397
398 private static String _portalServletContextName = StringPool.BLANK;
399 private static String _portalServletContextPath = StringPool.SLASH;
400
401 static {
402 try {
403 _FILTERED_PROPERTY_DESCRIPTORS_CACHE_FIELD =
404 ReflectionUtil.getDeclaredField(
405 AbstractAutowireCapableBeanFactory.class,
406 "filteredPropertyDescriptorsCache");
407 }
408 catch (Exception e) {
409 throw new LoggedExceptionInInitializerError(e);
410 }
411 }
412
413 private ArrayApplicationContext _arrayApplicationContext;
414 private ServiceWrapperRegistry _serviceWrapperRegistry;
415
416 }