2013-07-31 28 views
0

我正在将我的webapp的liferay版本从6.1.0迁移到6.1.1(使用来自liferay patchers community的6.1.1-ga2版本并且有一点点问题与我的web服务是以前在那里工作。liferay中的DispatcherServlet上下文实例化错误6.1.1

我用PortalDelegateServlet实例化的Spring DispatcherServlet。

我的问题是,我的servlet(myWS-servlet.xml中)的Spring上下文是之前的实例PortletContextLoaderListener的应用上下文(也试过来自spring的ContextLoaderListener,同样的问题) 和作为我的控制器u se服务从主应用程序上下文(在DispatcherServlet实例化时未加载),spring不能自动装配它们。

奇怪的是,如果我重新部署我的portlet,问题就解决了。

你有什么想法我可以解决这个问题吗?


我的web.xml

<?xml version="1.0" encoding="UTF-8"?> 
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5"> 
<display-name>banner-portlet</display-name> 
<jsp-config> 
    <taglib> 
     <taglib-uri>http://java.sun.com/portlet_2_0</taglib-uri> 
     <taglib-location>/WEB-INF/tlds/liferay-portlet.tld</taglib-location> 
    </taglib> 
    <taglib> 
     <taglib-uri>http://liferay.com/tld/theme</taglib-uri> 
     <taglib-location>/WEB-INF/tlds/liferay-theme.tld</taglib-location> 
    </taglib> 
    <taglib> 
     <taglib-uri>http://liferay.com/tld/portlet</taglib-uri> 
     <taglib-location>/WEB-INF/tlds/liferay-portlet-ext.tld</taglib-location> 
    </taglib> 
</jsp-config> 

<servlet> 
    <servlet-name>liferayWSdispatcher</servlet-name> 
    <servlet-class>com.liferay.portal.kernel.servlet.PortalDelegateServlet</servlet-class> 
    <init-param> 
     <param-name>servlet-class</param-name> 
     <param-value>org.springframework.web.servlet.DispatcherServlet</param-value> 
    </init-param> 
    <init-param> 
     <param-name>sub-context</param-name> 
     <param-value>rest-api</param-value> 
    </init-param> 
    <load-on-startup>1</load-on-startup> 
</servlet> 

<servlet-mapping> 
    <servlet-name>liferayWSdispatcher</servlet-name> 
    <url-pattern>/</url-pattern> 
</servlet-mapping> 

<listener> 
    <listener-class>com.liferay.portal.spring.context.PortletContextLoaderListener</listener-class> 
</listener> 
<context-param> 
    <param-name>contextConfigLocation</param-name> 
    <param-value>classpath*:applicationContext.xml</param-value> 
</context-param> 

<context-param> 
    <param-name>javax.faces.PROJECT_STAGE</param-name> 
    <param-value>Development</param-value> 
</context-param> 
<context-param> 
    <param-name>javax.faces.FACELETS_SKIP_COMMENTS</param-name> 
    <param-value>true</param-value> 
</context-param> 
<!-- Instruct Mojarra to utilize JBoss-EL instead of the EL implementation 
    provided by the servlet container. --> 
<!-- was used only for admin portlets but make calendar portlet crash 
<context-param> 
    <param-name>com.sun.faces.expressionFactory</param-name> 
    <param-value>org.jboss.el.ExpressionFactoryImpl</param-value> 
</context-param> 
--> 
<servlet> 
    <servlet-name>Faces Servlet</servlet-name> 
    <servlet-class>javax.faces.webapp.FacesServlet</servlet-class> 
    <load-on-startup>1</load-on-startup> 
</servlet> 

<filter> 
    <filter-name>PrimeFaces FileUpload Filter</filter-name> 
    <filter-class>org.primefaces.webapp.filter.FileUploadFilter</filter-class> 
</filter> 
<filter-mapping> 
    <filter-name>PrimeFaces FileUpload Filter</filter-name> 
    <servlet-name>Faces Servlet</servlet-name> 
</filter-mapping> 

<listener> 
    <listener-class>com.liferay.faces.portal.listener.StartupListener</listener-class> 
</listener> 


<!-- MyFaces will not initialize unless a servlet-mapping to the Faces Servlet 
    is present. --> 
<servlet-mapping> 
    <servlet-name>Faces Servlet</servlet-name> 
    <url-pattern>*.xhtml</url-pattern> 
</servlet-mapping> 



<context-param> 
    <param-name>portalContextConfigLocation</param-name> 
    <param-value>/WEB-INF/applicationContext-velocity-tool.xml</param-value> 
</context-param> 

我的applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://www.springframework.org/schema/beans" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:mvc="http://www.springframework.org/schema/mvc" 
    xmlns:context="http://www.springframework.org/schema/context" 
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 
    http://www.springframework.org/schema/context 
    http://www.springframework.org/schema/context/spring-context-3.0.xsd 
    http://www.springframework.org/schema/mvc 
    http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd"> 

<context:component-scan base-package="be.maximede"> 
    <context:exclude-filter type="regex" expression="be.maximede.webservice.*"/> 
</context:component-scan> 

我myWS-servlet.xml中

<beans xmlns="http://www.springframework.org/schema/beans" 
xmlns:context="http://www.springframework.org/schema/context" 
xmlns:mvc="http://www.springframework.org/schema/mvc" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd 
    http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd"> 

<context:component-scan base-package="be.maximede.webservice"/> 

<mvc:annotation-driven /> 

回答

3

我知道这个线程是一岁多。但我想帮助拯救人们一些麻烦。我的同事和我花了一个星期的时间试图弄清楚为什么我们无法在使用spring和PortalDelegateServlet + DispatcherServlet的portlet控制器之前加载spring服务。

与其他海报发表的评论一样,它与问题http://issues.liferay.com/browse/LPS-29103有点但并不直接相关。它的确与Servlet在Liferay中初始化的方式以及Liferay如何处理web.xml重写有关。

Liferay的重写的web.xml中定义的所有听众,并将它们放入一个上下文PARAM喜欢这样的:

<context-param> 
    <param-name>portalListenerClasses</param-name> 
    <param-value>com.liferay.portal.kernel.servlet.SerializableSessionAttributeListener,org.springframework.web.context.ContextLoaderListener</param-value> 
</context-param> 

,然后创建自己的监听器(或没有显示,PluginContextListener):

<listener> 
    <listener-class>com.liferay.portal.kernel.servlet.SecurePluginContextListener</listener-class> 
</listener> 

此SecurePluginContextListener然后加载上下文并将其连接起来。问题是,有时候,SecurePluginContextListener将首先使用Web应用程序上下文初始化PortalDelegateServlet,然后它将转到portalListenerClass中的init方法。因此,Portlet控制器中的任何AutoWired内容都缺少所有依赖项(来自应用程序上下文的服务)。

为了解决这个问题,我们在web.xml中声明了PortalDelegateServlet并创建了一个自定义的ServletContextListener,它将创建一个PortalDelagateServlet和ServletConfig,并将相同的参数传递给Spring的DispatcherServlet。之所以这样做,是因为我们让Liferay在portalListenerClass中完成所有的加载。重写的web.xml如下所示:

<context-param> 
    <param-name>portalListenerClasses</param-name> 
    <param-value>com.liferay.portal.kernel.servlet.SerializableSessionAttributeListener,org.springframework.web.context.ContextLoaderListener, com.domain.CustomContextListener</param-value> 
</context-param> 

而CustomContextListener会在ServletContextListener中实现这些方法。 在CustomContextListener的contextInitialized(...)方法中,我们只是以编程方式创建了web.xml中的同一个ServletConfig(一个实现了ServletConfig的内部类)。然后我们创建一个pds = new PortalDelegateServlet()并调用pds.init(customServletConfig)

+0

谢谢!它解决了我的问题!在生产中没有更多的双重部署;) – maximede

+0

你好,你可以发布CustomContextListener和CustomServletConfig类实现吗?我没有运气实现这些。谢谢。 – jbub