Using Service Trackers on a JSF portlet

4年前 に txapeldot . によって更新されました。 Junior Member 投稿: 91 参加年月日: 15/01/15 最新の投稿

From a non-bean class lying on a JSF portlet, I'm trying to invoke a service defined in a Service Builder-created module. What I've read on the official documentation (Liferay 7.2) is that this task can be accomplished by using Service Trackers.

The thing is that on a Liferay 7.4 Service Builder generated module, the '_serviceTracker' property has not been created within the [Foo]LocalServiceUtil service class, once the 'build service' gradle task has finished. As a consecuence, when from a non-bean class, which defines a [Foo]LocalServiceTracker class, lying on a JSF portlet, I call the method '.getService()', it is always returning a 'null' value.

All I've read about invoking Service Builder based services is intended for the Liferay 7.2 release, but I'm developing with Liferay 7.4. My doubt is whether the info described on Liferay 7.2 docs is valid for Liferay 7.4 or, I'm just doing the things the wrong way.

I'd really appreciate some clarification.

Thanks.

thumbnail
4年前 に Russell Bohl によって更新されました。 Expert 投稿: 308 参加年月日: 13/02/13 最新の投稿

Good catch: I think there was a change made here (removing Service Tracking form the ServiceUtil classes). That said, you should still be able to track the LocalService services in your code. For example, this works from the Server Administration > Script console in my 7.4 U9 portal (but I don't know JSF):

import com.liferay.journal.model.JournalArticle;
import com.liferay.journal.service.JournalArticleLocalService;
import com.liferay.portal.scripting.groovy.internal.GroovyExecutor;

import org.osgi.framework.Bundle;
import org.osgi.framework.FrameworkUtil;
import org.osgi.util.tracker.ServiceTracker;

ServiceTracker<JournalArticleLocalService, JournalArticleLocalService> st;
    Bundle bundle = FrameworkUtil.getBundle(GroovyExecutor.class);

    st = new ServiceTracker(bundle.getBundleContext(), JournalArticleLocalService.class, null);
    st.open();

    JournalArticleLocalService jaService = st.waitForService(500);

    if (jaService == null) {
        out.println("The required service 'JournalArticleLocalService' is not available.");
    }
    else {
        java.util.List<JournalArticle>articles = jaService.getArticles();
        if (articles != null) {
            out.println("Article count: " + articles.size());
        } else {
            out.println("no articles");
        }
    }

    if (st != null) {
        out.println("closing st")
        st.close();
    }

 

4年前 に txapeldot . によって更新されました。 Junior Member 投稿: 91 参加年月日: 15/01/15 最新の投稿

Thanks for your reply, Russel.

I've managed to get rid of that 'null' value when calling the '.getService()' method. Your code is also perfectly valid too.

Thanks.

thumbnail
4年前 に Russell Bohl によって更新されました。 Expert 投稿: 308 参加年月日: 13/02/13 最新の投稿

Did you solve the other problem? I'm curious what was wrong because it wasn't obvious from your service.xml or the service calls you were making.

4年前 に txapeldot . によって更新されました。 Junior Member 投稿: 91 参加年月日: 15/01/15 最新の投稿

Yes, I did. It was due to the fact that on a postgreSQL database (at least the version I'm working with) it's not allowed to use uppercase characters to set column names. Instead of 'numProjects' column name, I changed it to 'numprojects', and then, I changed the content of service.xml to:

<column name="numProjects" type="long" db-name="numprojects" />

After changing it, and rebuilding Service Builder, it worked as expected.

Silly mistake; that's why I prefered deleting the post.

Thanks.