Liferay 6使用公共服务生成器层错误-BeanLocatorException-尚未设置BeanLocator

Liferay 6使用公共服务生成器层错误-BeanLocatorException-尚未设置BeanLocator,exception,spring-mvc,liferay,maven-3,liferay-6,Exception,Spring Mvc,Liferay,Maven 3,Liferay 6,我们正在尝试将liferay service builder用作所有Portlet的公共层。我们已经创建了一个单独的公共portlet项目,在该项目中,我们使用service.xml构建服务。这将为我们生成一个service.jar文件。我们正在将这个jar复制到所有portlet WEB-INF/lib-dir 当我们运行portlet时,它会在日志上抛出以下错误,portlet暂时不可用消息会显示在portlet上 14:43:17,447 ERROR [jsp:154] com.lifer

我们正在尝试将liferay service builder用作所有Portlet的公共层。我们已经创建了一个单独的公共portlet项目,在该项目中,我们使用service.xml构建服务。这将为我们生成一个service.jar文件。我们正在将这个jar复制到所有portlet WEB-INF/lib-dir

当我们运行portlet时,它会在日志上抛出以下错误,portlet暂时不可用消息会显示在portlet上

14:43:17,447 ERROR [jsp:154] com.liferay.portal.kernel.bean.BeanLocatorException: BeanLocator has not been set
    at com.liferay.portal.kernel.bean.PortletBeanLocatorUtil.locate(PortletBeanLocatorUtil.java:40)
    at com.cogs.common.service.CourseLocalServiceUtil.getService(CourseLocalServiceUtil.java:223)
    at com.cogs.common.service.CourseLocalServiceUtil.getCoursesCount(CourseLocalServiceUtil.java:187)
    at org.apache.jsp.jsps.course.course_005fview_jsp._jspService(course_005fview_jsp.java:542)
    at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
    at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:377)
    at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:313)
    at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:260)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:646)
    at org.apache.catalina.core.ApplicationDispatcher.doInclude(ApplicationDispatcher.java:551)
    at org.apache.catalina.core.ApplicationDispatcher.include(ApplicationDispatcher.java:488)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:646)
我确信这种方法应该能够无缝地工作。但在liferay论坛上发现一些人对此表示不满,但尚未找到任何解决方案。如果您找到了将ServiceBuilder用作公共层的方法,并且它对您有效,请告知我们

我们正在使用maven构建所有portlet项目

Liferay版本是6.0.5
我们正在使用SpringPortletMVC进行Portlet开发。

BeenLocator与我的SpringPortletforMe的问题是 我的portlet的spring上下文在liferay的spring上下文之前被初始化

我在用
ClassName ClassName=ClassNameLocalServiceUtil.getClassName(JournalArticle.class.getName())在我的构造函数中。未加载LIferay的上下文,因此出现错误。我移动了这段代码,以便在(仅在当时)第一个请求需要时调用它。问题解决了


因此,在portlet初始化过程中不要依赖于lifery,要对依赖项与liferay进行某种“惰性”连接。

Martin Gamulin之前的回答是正确的。如果您有两个单独的web应用程序,一个用于Spring Portlet,另一个用于Service Builder(这似乎是在Liferay中执行操作的正确方式),那么您需要确保Spring Portlet在初始化期间不引用ServiceBuilder类

如果根据应用服务器实例化webapp的顺序(在Tomcat中,您不能指定启动顺序),每次在构建器webapp之前部署portlet webapp时,都会发生BeanLocatorException


在我们的例子中,这意味着将
XxxLocalServiceUtil.createXxx(0)
调用从portlet控制器的构造函数移动到相关方法。

我很难找到此错误的解决方案,因此我将发布我们所做的。portlet的名称已更改,生成了服务,并且在运行portlet时抛出相同的错误:

com.liferay.portal.kernel.bean.BeanLocatorException: BeanLocator has not been set for servlet context

在我们的例子中,我们必须从../docroot/WEB-INF/lib/portlet service.jar中删除jar文件。我们需要使用类似的东西:拥有一个portlet(比如说
源portlet
),其服务将被其他portlet使用

因此,我们将生成的
sourceportlet服务.jar
从源portlet的
WEB-INF/lib
移动到
{tomcat_home}/lib/ext
文件夹,其他jar如
portlet服务.jar

这种方法的缺点是,每当源portlet发生更改时,我们就需要重新启动服务器

如果其他portlet是您的自定义插件portlet,那么另一种方法是将生成的
sourceportlet service.jar
复制到其他portlet的
WEB-INF/lib
。如果您在JSP钩子中使用该服务,则此方法不起作用


希望这会有所帮助。

因为您使用的是maven,所以请确保war名称与portlet项目名称相等。
调试后,我发现
ClpSerializer
定义了
\u servletContextName
,它等于war项目的
。如果您部署名为
artifactId-1.0.0-snapshot.war的工件,则将使用该名称创建上下文,但servicegen生成的代码希望它是
artifactId
。使用
ClpSerializer
进行验证

我也有同样的问题。我将以下代码放在portlet的liferay-plugin-package.properties文件中,该文件使用公共portlet的服务层。这对我有用

required deployment contexts=common portlet


最好将service.jar文件复制到tomcat/lib/ext,而不是所有的Portlet WEB-INF/lib。

您必须构建服务并部署当前Portlet所需的(Portlet挂钩),您可以通过在liferay-plugin-package.properties文件中查看其名称来了解它:

required-deployment-contexts=[Portlet-Hook name]

我在使用maven portlet时遇到了类似的问题。 首先我做了portlet,然后我把service.xml

问题是生成器正在查找不存在的portlet名称 我解决了如何显化我希望生成者查找的portlet名称的问题

特别是,要做到这一点,两个pom节点必须相等

project.artifactId=(liferay为此创建一个bean定位器)

project.build.(liferay plugin).configuration.pluginName=生成器的portlet的内部名称

例如,我的pom.xml中有一个小练习

<modelVersion>4.0.0</modelVersion>
<groupId>io.endeios</groupId>
<artifactId>ShowTheCats-portlet</artifactId><!-- ONE -->
<packaging>war</packaging>
<name>ShowTheCats Portlet</name>
<version>1.0-SNAPSHOT</version>
<build>
    <plugins>
        <plugin>
            <groupId>com.liferay.maven.plugins</groupId>
            <artifactId>liferay-maven-plugin</artifactId>
            <version>${liferay.maven.plugin.version}</version>
            <executions>
                <execution>
                    <phase>generate-sources</phase>
                    <goals>
                        <goal>build-css</goal>
                    </goals>
                </execution>
            </executions>
            <configuration>
                <autoDeployDir>${liferay.auto.deploy.dir}</autoDeployDir>
                <appServerDeployDir>${liferay.app.server.deploy.dir}</appServerDeployDir>
                <appServerLibGlobalDir>${liferay.app.server.lib.global.dir}</appServerLibGlobalDir>
                <appServerPortalDir>${liferay.app.server.portal.dir}</appServerPortalDir>
                <liferayVersion>${liferay.version}</liferayVersion>
                <pluginType>portlet</pluginType>
                <pluginName>ShowTheCats-portlet</pluginName><!-- TWO -->
            </configuration>
        </plugin>
4.0.0
伊奥·恩迪奥斯
showthecatsportlet
战争
showthecatsportlet
1.0-快照
com.liferay.maven.plugins
liferay maven插件
${liferay.maven.plugin.version}
生成源
构建css
${liferay.auto.deploy.dir}
${liferay.app.server.deploy.dir}
${liferay.app.server.lib.global.dir}
${liferay.app.server.portal.dir}
${liferay.version}
门户组件
showthecatsportlet

一和二必须相同

为了解决上述问题,我做了以下操作:

  • 将pom.xml中的插件配置属性pluginName设置为正确的上下文

        <plugin>
            <groupId>com.liferay.maven.plugins</groupId>
            <artifactId>liferay-maven-plugin</artifactId>
            <version>${liferay.version}</version>
            <configuration>
                <autoDeployDir>${liferay.auto.deploy.dir}</autoDeployDir>
                <appServerPortalDir>${liferay.app.server.portal.dir}</appServerPortalDir>
                <liferayVersion>${liferay.version}</liferayVersion>
                <pluginType>portlet</pluginType>
                <pluginName>XXXX-portlet</pluginName>
            </configuration>
        </plugin>
    
  • 部署war,验证war名称和正确co的日志
        synchronized (ClpSerializer.class) {
            if (Validator.isNotNull(_servletContextName)) {
                return _servletContextName;
            }
    
            try {
                ClassLoader classLoader = ClpSerializer.class.getClassLoader();
    
                Class<?> portletPropsClass = classLoader.loadClass(
                        "com.liferay.util.portlet.PortletProps");
    
                Method getMethod = portletPropsClass.getMethod("get",
                        new Class<?>[] { String.class });
    
                String portletPropsServletContextName = (String) getMethod.invoke(null,
                        "XXXX-portlet-deployment-context");
    
                if (Validator.isNotNull(portletPropsServletContextName)) {
                    _servletContextName = portletPropsServletContextName;
                }
            } catch (Throwable t) {
                if (_log.isInfoEnabled()) {
                    _log.info(
                        "Unable to locate deployment context from portlet properties");
                }
            }
    
            if (Validator.isNull(_servletContextName)) {
                try {
                    String propsUtilServletContextName = PropsUtil.get(
                            "XXXX-portlet-deployment-context");
    
                    if (Validator.isNotNull(propsUtilServletContextName)) {
                        _servletContextName = propsUtilServletContextName;
                    }
                } catch (Throwable t) {
                    if (_log.isInfoEnabled()) {
                        _log.info(
                            "Unable to locate deployment context from portal properties");
                    }
                }
            }
    
            if (Validator.isNull(_servletContextName)) {
                _servletContextName = "upay-portlet";
            }
    
            return _servletContextName;
        }
    }`
    
                <configuration>
                    <autoDeployDir>${liferay.auto.deploy.dir}</autoDeployDir>
                    <appServerDeployDir>${liferay.app.server.deploy.dir}</appServerDeployDir>
                    <appServerLibGlobalDir>${liferay.app.server.lib.global.dir}</appServerLibGlobalDir>
                    <appServerPortalDir>${liferay.app.server.portal.dir}</appServerPortalDir>
                    <liferayVersion>${liferay.version}</liferayVersion>
                    <pluginType>portlet</pluginType>
                    <pluginName>${project.artifactId}-${project.version}</pluginName>
                </configuration>
    
       artifactId-version-deployment-context=artifactId-version
    
       portlet-sample-1.0-deployment-context=portlet-sample-1.0
    
    BeanLocator beanLocator = getBeanLocator(servletContextName);