diff --git a/org.springframework.web.portlet/src/main/java/org/springframework/web/portlet/FrameworkPortlet.java b/org.springframework.web.portlet/src/main/java/org/springframework/web/portlet/FrameworkPortlet.java index 1baaeebf22..75cad59c52 100644 --- a/org.springframework.web.portlet/src/main/java/org/springframework/web/portlet/FrameworkPortlet.java +++ b/org.springframework.web.portlet/src/main/java/org/springframework/web/portlet/FrameworkPortlet.java @@ -327,20 +327,30 @@ public abstract class FrameworkPortlet extends GenericPortletBean protected ApplicationContext createPortletApplicationContext(ApplicationContext parent) throws BeansException { + Class contextClass = getContextClass(); if (logger.isDebugEnabled()) { logger.debug("Portlet with name '" + getPortletName() + "' will try to create custom ApplicationContext context of class '" + - getContextClass().getName() + "'" + ", using parent context [" + parent + "]"); + contextClass.getName() + "'" + ", using parent context [" + parent + "]"); } - if (!ConfigurablePortletApplicationContext.class.isAssignableFrom(getContextClass())) { + if (!ConfigurablePortletApplicationContext.class.isAssignableFrom(contextClass)) { throw new ApplicationContextException("Fatal initialization error in portlet with name '" + getPortletName() + - "': custom ApplicationContext class [" + getContextClass().getName() + + "': custom ApplicationContext class [" + contextClass.getName() + "] is not of type ConfigurablePortletApplicationContext"); } ConfigurablePortletApplicationContext pac = - (ConfigurablePortletApplicationContext) BeanUtils.instantiateClass(getContextClass()); - pac.setId(getPortletContext().getPortletContextName() + "." + getPortletName()); + (ConfigurablePortletApplicationContext) BeanUtils.instantiateClass(contextClass); + + // Assign the best possible id value. + String portletContextName = getPortletContext().getPortletContextName(); + if (portletContextName != null) { + pac.setId(ConfigurablePortletApplicationContext.APPLICATION_CONTEXT_ID_PREFIX + portletContextName + "." + getPortletName()); + } + else { + pac.setId(ConfigurablePortletApplicationContext.APPLICATION_CONTEXT_ID_PREFIX + getPortletName()); + } + pac.setParent(parent); pac.setPortletContext(getPortletContext()); pac.setPortletConfig(getPortletConfig()); diff --git a/org.springframework.web.portlet/src/main/java/org/springframework/web/portlet/context/ConfigurablePortletApplicationContext.java b/org.springframework.web.portlet/src/main/java/org/springframework/web/portlet/context/ConfigurablePortletApplicationContext.java index 45452354f1..02d0bff87d 100644 --- a/org.springframework.web.portlet/src/main/java/org/springframework/web/portlet/context/ConfigurablePortletApplicationContext.java +++ b/org.springframework.web.portlet/src/main/java/org/springframework/web/portlet/context/ConfigurablePortletApplicationContext.java @@ -43,6 +43,11 @@ import org.springframework.web.context.WebApplicationContext; public interface ConfigurablePortletApplicationContext extends WebApplicationContext, ConfigurableApplicationContext { + /** + * Prefix for ApplicationContext ids that refer to portlet name. + */ + String APPLICATION_CONTEXT_ID_PREFIX = WebApplicationContext.class.getName() + ":"; + /** * Name of the PortletContext environment bean in the factory. * @see javax.portlet.PortletContext diff --git a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/FrameworkServlet.java b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/FrameworkServlet.java index f2174b378b..820cd0d702 100644 --- a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/FrameworkServlet.java +++ b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/FrameworkServlet.java @@ -18,6 +18,7 @@ package org.springframework.web.servlet; import java.io.IOException; import java.security.Principal; +import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -402,21 +403,39 @@ public abstract class FrameworkServlet extends HttpServletBean protected WebApplicationContext createWebApplicationContext(WebApplicationContext parent) throws BeansException { + Class contextClass = getContextClass(); if (this.logger.isDebugEnabled()) { this.logger.debug("Servlet with name '" + getServletName() + "' will try to create custom WebApplicationContext context of class '" + - getContextClass().getName() + "'" + ", using parent context [" + parent + "]"); + contextClass.getName() + "'" + ", using parent context [" + parent + "]"); } - if (!ConfigurableWebApplicationContext.class.isAssignableFrom(getContextClass())) { + if (!ConfigurableWebApplicationContext.class.isAssignableFrom(contextClass)) { throw new ApplicationContextException( "Fatal initialization error in servlet with name '" + getServletName() + - "': custom WebApplicationContext class [" + getContextClass().getName() + + "': custom WebApplicationContext class [" + contextClass.getName() + "] is not of type ConfigurableWebApplicationContext"); } ConfigurableWebApplicationContext wac = - (ConfigurableWebApplicationContext) BeanUtils.instantiateClass(getContextClass()); - wac.setId(getServletContext().getServletContextName() + "." + getServletName()); + (ConfigurableWebApplicationContext) BeanUtils.instantiateClass(contextClass); + + // Assign the best possible id value. + ServletContext servletContext = getServletContext(); + if (servletContext.getMajorVersion() > 2 || servletContext.getMinorVersion() >= 5) { + // Servlet 2.5's getContextPath available! + wac.setId(ConfigurableWebApplicationContext.APPLICATION_CONTEXT_ID_PREFIX + servletContext.getContextPath() + "/" + getServletName()); + } + else { + // Servlet <= 2.4: resort to name specified in web.xml, if any. + String servletContextName = servletContext.getServletContextName(); + if (servletContextName != null) { + wac.setId(ConfigurableWebApplicationContext.APPLICATION_CONTEXT_ID_PREFIX + servletContextName + "." + getServletName()); + } + else { + wac.setId(ConfigurableWebApplicationContext.APPLICATION_CONTEXT_ID_PREFIX + getServletName()); + } + } + wac.setParent(parent); wac.setServletContext(getServletContext()); wac.setServletConfig(getServletConfig()); diff --git a/org.springframework.web/src/main/java/org/springframework/web/context/ConfigurableWebApplicationContext.java b/org.springframework.web/src/main/java/org/springframework/web/context/ConfigurableWebApplicationContext.java index 9c8ffa4192..6727659a31 100644 --- a/org.springframework.web/src/main/java/org/springframework/web/context/ConfigurableWebApplicationContext.java +++ b/org.springframework.web/src/main/java/org/springframework/web/context/ConfigurableWebApplicationContext.java @@ -39,6 +39,11 @@ import org.springframework.context.ConfigurableApplicationContext; */ public interface ConfigurableWebApplicationContext extends WebApplicationContext, ConfigurableApplicationContext { + /** + * Prefix for ApplicationContext ids that refer to context path and/or servlet name. + */ + String APPLICATION_CONTEXT_ID_PREFIX = WebApplicationContext.class.getName() + ":"; + /** * Name of the ServletConfig environment bean in the factory. * @see javax.servlet.ServletConfig diff --git a/org.springframework.web/src/main/java/org/springframework/web/context/ContextLoader.java b/org.springframework.web/src/main/java/org/springframework/web/context/ContextLoader.java index 83e9845b83..d1336917cc 100644 --- a/org.springframework.web/src/main/java/org/springframework/web/context/ContextLoader.java +++ b/org.springframework.web/src/main/java/org/springframework/web/context/ContextLoader.java @@ -141,8 +141,6 @@ public class ContextLoader { } - private static final Log logger = LogFactory.getLog(ContextLoader.class); - /** * Map from (thread context) ClassLoader to WebApplicationContext. * Often just holding one reference - if the ContextLoader class is @@ -183,6 +181,7 @@ public class ContextLoader { "check whether you have multiple ContextLoader* definitions in your web.xml!"); } + Log logger = LogFactory.getLog(ContextLoader.class); servletContext.log("Initializing Spring root WebApplicationContext"); if (logger.isInfoEnabled()) { logger.info("Root WebApplicationContext: initialization started"); @@ -239,7 +238,7 @@ public class ContextLoader { protected WebApplicationContext createWebApplicationContext( ServletContext servletContext, ApplicationContext parent) throws BeansException { - Class contextClass = determineContextClass(servletContext); + Class contextClass = determineContextClass(servletContext); if (!ConfigurableWebApplicationContext.class.isAssignableFrom(contextClass)) { throw new ApplicationContextException("Custom context class [" + contextClass.getName() + "] is not of type [" + ConfigurableWebApplicationContext.class.getName() + "]"); @@ -247,7 +246,23 @@ public class ContextLoader { ConfigurableWebApplicationContext wac = (ConfigurableWebApplicationContext) BeanUtils.instantiateClass(contextClass); - wac.setId(servletContext.getServletContextName()); + + // Assign the best possible id value. + if (servletContext.getMajorVersion() > 2 || servletContext.getMinorVersion() >= 5) { + // Servlet 2.5's getContextPath available! + wac.setId(ConfigurableWebApplicationContext.APPLICATION_CONTEXT_ID_PREFIX + servletContext.getContextPath()); + } + else { + // Servlet <= 2.4: resort to name specified in web.xml, if any. + String servletContextName = servletContext.getServletContextName(); + if (servletContextName != null) { + wac.setId(ConfigurableWebApplicationContext.APPLICATION_CONTEXT_ID_PREFIX + servletContextName); + } + else { + wac.setId(ConfigurableWebApplicationContext.APPLICATION_CONTEXT_ID_PREFIX); + } + } + wac.setParent(parent); wac.setServletContext(servletContext); wac.setConfigLocation(servletContext.getInitParameter(CONFIG_LOCATION_PARAM)); @@ -334,6 +349,7 @@ public class ContextLoader { if (parentContextKey != null) { // locatorFactorySelector may be null, indicating the default "classpath*:beanRefContext.xml" BeanFactoryLocator locator = ContextSingletonBeanFactoryLocator.getInstance(locatorFactorySelector); + Log logger = LogFactory.getLog(ContextLoader.class); if (logger.isDebugEnabled()) { logger.debug("Getting parent context definition: using parent context key of '" + parentContextKey + "' with BeanFactoryLocator");