Liferay 6 Using Common Service Builder layer Error - BeanLocatorException - BeanLocator has not been set
Asked Answered
D

10

10

We are trying to use liferay service builder as a common layer for all our portlets. We have created a separate common portlet project where we are building the service using service.xml This generates a service.jar file for us. We are copying this jar to all portlets WEB-INF/lib dir.

When we run the portlet it throws following error on the logs and Portlet is temporarily unavailable message is displayed on the 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)

I am sure that this approach should work seamlessly. But found several people complaining about it on liferay forums, but did not find any solution yet. Please let us know if you found a way to use service builder as a common layer and it worked for you.

We are using maven for building all portlet projects.

Liferay Version is 6.0.5 And we are using Spring Portlet MVC for our portlet development.

Devilkin answered 10/6, 2011 at 17:21 Comment(5)
No answers to this yet? I am surprised that nobody uses common service builder at all? If you use servicebuilder, how do you use it?Devilkin
I, for one, use service builder for creating services for only one portlet; if I need more than one portlet to use some service, I put all portlets in just one project/WAR. However, I think it is not impossible to do what you want. I hoje you got an answer because I am curious about it too :)Barca
we are upgrading from liferay 5.2.3 to 6.0.6GA, we've used service builder extensively in the ext/ environment til now. We're trying to convert our ext/ to an ext-plugin, and in the process i'm trying to find a good way to address this exact issue around a common service layer between portlets, because it looks like they will deprecate service builder within ext-plugins in future versions. I, too, am surprised that there is no good answer to this problem yet.Impanation
We tried several options and finally settled down to not use common service builder layer since it was getting just too complicated. If you are trying some options this may help. We tried keeping service builder as a seperate portlet itself and did work either. Bean Locator may also be related to the spring versions.Devilkin
in tomcat configured in eclipse,try clean and then publish on the configured server.Liberality
S
3

You have to build-service AND deploy the (Portlet-Hook) that is required for your current portlet, you can know it by see its name in liferay-plugin-package.properties file as:

required-deployment-contexts=[Portlet-Hook name]
Somehow answered 11/12, 2013 at 13:47 Comment(0)
C
3

I tryed anything written on that page, but nothing worked for me, until i added the project's version

to maven-pluginname in pom:

            <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>

and in liferay-plugin-package.properties:

   artifactId-version-deployment-context=artifactId-version

for example:

   portlet-sample-1.0-deployment-context=portlet-sample-1.0

where artifactId = portlet-sample

and version = 1.0

After all I i built services, and redeployed my war.

I came to the solution because I debugged:

com.liferay.portal.kernel.bean.PortletBeanLocatorUtil

where

BeanLocator beanLocator = getBeanLocator(servletContextName);

is called which always returned null without versionnumber...

I hope someone helps this.

Candidacandidacy answered 19/1, 2016 at 11:53 Comment(0)
M
2

I had a hard time finding a solution to this error so I will post what we did. The name of the portlet changed, built the service and when running the portlet throws the same error:

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

In our case we had to remove the jar file from ../docroot/WEB-INF/lib/portlet-service.jar

Martinmas answered 16/1, 2012 at 11:36 Comment(0)
S
2

We had a requirement to use something similar: Have a portlet (lets say Source-portlet) whose services will be used by other portlets.

So we moved the generated sourceportlet-service.jar from the Source-portlet's WEB-INF/lib to {tomcat_home}/lib/ext folder were other jars like portlet-service.jar etc reside.

The down side of this approach is whenever there is a change in the Source-portlet we would need to restart the server.

If the other portlet's are your custom plugin portlets than another approach would be to copy the generated sourceportlet-service.jar to other portlet's WEB-INF/lib. This approach does not work if you are using the service in a JSP hook.

Hope this would help.

Seeger answered 14/3, 2012 at 10:52 Comment(0)
I
1

The previous answer by Martin Gamulin is correct. If you have two separate web apps, one for Spring portlets and another with your Service Builder (which seems to be the correct way to do things in Liferay), then you need to ensure that your Spring portlets do not reference your ServiceBuilder classes during initialization.

If they do then depending on the order in which your app server instantiates your webapps (and in Tomcat you can't specify a startup order), the BeanLocatorException will happen every time the portlets webapp deploys before the builder webapp.

In our case this meant moving a XxxLocalServiceUtil.createXxx(0) call from the constructor of the portlet Controller to the relevant methods.

Impersonal answered 24/11, 2011 at 16:47 Comment(0)
A
1

I had a a similar problem doing a maven portlet. First i did the portlet and then i put the service.xml

The issue was that the generator was looking for a portlet name that was not there i solved making expliciting the portlet name i wanteed the genrator to look for

in particular, to do this two pom nodes must be equal

project.artifatctId = (liferay creates a bean locator for this)

and

project.build.(liferay plugin).configuration.pluginName = the internal name of the portlet for the generator

as an example, a small exerpt from my 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>

ONE and TWo must be the same

Antilepton answered 24/10, 2014 at 17:27 Comment(1)
You finally brought two days of refactoring efforts to an end. Thank you very much. In my case the service generation is done in a different module than the portlet, so setting the pluginName is crucial. Here, take my upvote.Nadda
A
0

Problem with BeenLocator with my spring portlet for me was that my portlet's spring context was getting initialized before liferay's spring context did.

I was using ClassName className = ClassNameLocalServiceUtil.getClassName(JournalArticle.class.getName()); in my constructor. LIferay's context was not loaded hence the error. I moved that piece of code to be called when (only that time) first request needed it. Problem was solved.

So do not depend on lifery during initialization of your portlet, do some kind of "lazy" wiring of dependencies to liferay.

Avowal answered 18/11, 2011 at 8:54 Comment(0)
N
0

Since you are using maven, try to make sure your war name equals to your portlet project name. After debug i've found that ClpSerializer defines _servletContextName which is equal to <artifactId> of war project. If you deploy artifact named artifactId-1.0.0-snapshot.war the context will be created with that name, but code, generated by servicegen expects it to be artifactId. Verify with your ClpSerializer.

Noctule answered 30/5, 2013 at 10:23 Comment(0)
W
0

I also had the same problem. I placed the following code in liferay-plugin-package.properties file of portlets which uses the service layer of common portlet. It worked for me.

required-deployment-contexts=common-portlet

It's better to copy the service.jar file to tomcat/lib/ext instead of all portlets WEB-INF/lib.

Weep answered 10/10, 2013 at 5:53 Comment(0)
C
0

I did the following to solve the above problem:

  1. Set the plugin config property pluginName in pom.xml to the correct context

        <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>
    
  2. Optionally set the XXXX-portlet-deployment-context property in liferay plugin properties file or portlet.properties file

XXXX-portlet-deployment-context=XXXX-portlet

  1. Re-Build the services
  2. Verify if the generated ClpSerializer.java contains the correct contexts

` public static String getServletContextName() { if (Validator.isNotNull(_servletContextName)) { return _servletContextName; }

    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;
    }
}`
  1. Deploy the war, verify the war name and the logs for the correct context name.
Colwen answered 26/10, 2015 at 10:51 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.