Combination View Flat View Tree View
Threads [ Previous | Next ]
toggle
Karel Bělunek
Problem to cosume Liferay 7 service in JSF portlet
June 23, 2017 9:24 AM
Answer

Karel Bělunek

Rank: New Member

Posts: 8

Join Date: June 23, 2017

Recent Posts

I am learning Liferay 7 and I am using Liferay 7 ga3.

I have problem with accessing OSGi service from JSF backing bean.
I followed documentation from page https://dev.liferay.com/develop/tutorials/-/knowledge_base/7-0/services-in-jsf but all that I was able to achieve was exception:

java.lang.ClassCastException: com.sun.proxy.$Proxy688 cannot be cast to cz.test.service.EmployeeLocalService
at cz.kbe.liferay.primefaces.bean.TestBean.getTestStr(TestBean.java:37)

There is my attepmts:
First of all I have generated simple service using serviceBuilder that reads content of "Employee" MySQL table.
After that I have generated simple MVCportlet (standard "Hello from JSP page" portlet and I modified portlet class doView() method to print out information taken from service:

-------------
public class TestwebmvcportletPortlet extends MVCPortlet {

private EmployeeLocalService employeeLocalService = null;

@Reference
public void setEmployeeLocalService(EmployeeLocalService employeeLocalService) {
this.employeeLocalService = employeeLocalService;
}

@Override
public void doView(RenderRequest renderRequest, RenderResponse renderResponse)
throws IOException, PortletException {

// TODO Auto-generated method stub
int empCnt = employeeLocalService.getEmployeesCount();
System.out.println("INJECTED SERVICE:" + empCnt + " from object:"+employeeLocalService);

Bundle bundle = FrameworkUtil.getBundle(this.getClass());
BundleContext bundleContext = bundle.getBundleContext();
ServiceTracker<EmployeeLocalService, EmployeeLocalService> serviceTracker = new ServiceTracker<>(bundleContext,
EmployeeLocalService.class, null);
serviceTracker.open();
EmployeeLocalService svc2 = serviceTracker.getService();
int empCnt2 = svc2.getEmployeesCount();
System.out.println("SERVICE TRACKER:" + empCnt2 + " from object:"+svc2);
serviceTracker.close();

super.doView(renderRequest, renderResponse);
}

}
--------------

Everything works flawless, the output in log was:
INJECTED SERVICE:3 from object:cz.test.service.impl.EmployeeLocalServiceImpl@2fd0b37b
SERVICE TRACKER:3 from object:cz.test.service.impl.EmployeeLocalServiceImpl@2fd0b37b

So the injected and service tracker gives me the same object.


After that I generated JSF project using wizard on liferayfaces.org, I selected Liferay 7, JSF2.2, Primefaces an gradle.
Generated JSF primefaces portlet works well.
The documented approach https://dev.liferay.com/develop/tutorials/-/knowledge_base/7-0/services-in-jsf does not work, the portlet throws exception described above.

So I simplified the thing to basic - I created primefaces backing bead that holds one string attribute and I modified getter for this attribute to give me service using service tracker:
------
public String getTestStr() {
Bundle bundle = FrameworkUtil.getBundle(this.getClass());
BundleContext bundleContext = bundle.getBundleContext();
ServiceTracker<EmployeeLocalService, EmployeeLocalService> employeeLocalServiceTracker = new ServiceTracker<>(bundleContext,
EmployeeLocalService.class, null);
employeeLocalServiceTracker.open();
if (employeeLocalServiceTracker.isEmpty()) {
System.out.println("employeeLocalServiceTracker IS EMPTY");
} else {
System.out.println("employeeLocalServiceTracker IS NOT EMPTY");
System.out.println("SERVICE OBJECT: " + employeeLocalServiceTracker.getService());
EmployeeLocalService employeeLocalService = employeeLocalServiceTracker.getService();
testStr = "Count: " + employeeLocalService.getEmployeesCount();
}
employeeLocalServiceTracker.close();

// employeeLocalService.findByEmpid(1);
return testStr;
}
-------

The result has been the same - the exception cannot cast Proxy displayed directly on the primefaces portlet

I created page that contains both MVC and JSFportlet and there is logs:

employeeLocalServiceTracker IS NOT EMPTY
SERVICE OBJECT: cz.test.service.impl.EmployeeLocalServiceImpl@2fd0b37b
INJECTED SERVICE:3 from object:cz.test.service.impl.EmployeeLocalServiceImpl@2fd0b37b
SERVICE TRACKER:3 from object:cz.test.service.impl.EmployeeLocalServiceImpl@2fd0b37b

So I am bale to cass service toString() method, but when I am trying to cast the object to Interface - exception is thrown.

So the MVCportlet injected service, MVCportle service tracker provided service and the JSF protlet service tracker provided service ARE THE SAME OBJECT!

Now I am out of options, please any ideas why I am not able to consume OSGi service from JSF bean?
Thanks for any ideas, current situation is showstopper for me.
Neil Griffin
RE: Problem to cosume Liferay 7 service in JSF portlet
June 23, 2017 9:44 AM
Answer

Neil Griffin

LIFERAY STAFF

Rank: Liferay Legend

Posts: 2511

Join Date: July 26, 2005

Recent Posts

Hi Karel,

Thanks for posting this question -- we are here to help.

Are you using methods annotated with @PostConstruct and @PreDestroy as the tutorial recommends?

Also, if you attach an SSCCE that contains:
1. Your JSF WAR-based project source (generated from the archetype instructions at www.liferayfaces.org)
2. Your ServiceBuilder generated Project Source

Then we can try and reproduce the problem for you.

Kind Regards,

Neil
Karel Bělunek
RE: Problem to cosume Liferay 7 service in JSF portlet
June 28, 2017 9:42 AM
Answer

Karel Bělunek

Rank: New Member

Posts: 8

Join Date: June 23, 2017

Recent Posts

Hi Neil,

I am Liferay beginner so I just doublecheck everything to prevent bothering you with something obvious.
I have created 4 liferay osgi modules that demonstrates the problem:
- service
- service API
- working MVC portlet consuming the service
- failing Primefaces portlet consuming the service

The ZIP file with complete Liferay Workspace with 4 modules listed above is attached to this message.
I have also attached the screenshot

Many thanks for your support.

Kind regards

Karel Belunek
Attachment

Attachments: LrWSpace.zip (294.3k), liferay-exception.png (58.9k)
Neil Griffin
RE: Problem to cosume Liferay 7 service in JSF portlet
June 28, 2017 12:54 PM
Answer

Neil Griffin

LIFERAY STAFF

Rank: Liferay Legend

Posts: 2511

Join Date: July 26, 2005

Recent Posts

Hi Karel,

Thank you very much for attaching the code -- I was able to reproduce the issue.

It is caused by the following line in com.mycompany.my.primefaces.portlet/build.gradle:
1compileOnly project (":modules:testsvc:testsvc-api")


The problem is that this will include testsvc-api.jar inside of WEB-INF/lib which leads to ClassCastException being thrown.

In order to fix the problem, change the line to:
1providedCompile project (":modules:testsvc:testsvc-api")

And then rebuild+redeploy the PrimeFaces portlet WAR module.

Kind Regards,

Neil
Karel Bělunek
RE: Problem to cosume Liferay 7 service in JSF portlet
June 28, 2017 1:47 PM
Answer

Karel Bělunek

Rank: New Member

Posts: 8

Join Date: June 23, 2017

Recent Posts

Hi Neil,

I followed your advice and everything works fine.

Thank you very much!

Kind Regards
Karel Belunek
Neil Griffin
RE: Problem to cosume Liferay 7 service in JSF portlet
June 28, 2017 1:55 PM
Answer

Neil Griffin

LIFERAY STAFF

Rank: Liferay Legend

Posts: 2511

Join Date: July 26, 2005

Recent Posts

Hi Karel,

Thanks for letting me know that it is working for you, and thanks so much for choosing JSF/PrimeFaces for the UI tier of your portlet application.

Kind Regards,

Neil
Kyle Joseph Stiemann
Thread Split
October 7, 2017 8:51 AM
Answer

Kyle Joseph Stiemann

LIFERAY STAFF

Rank: Liferay Master

Posts: 578

Join Date: January 14, 2013

Recent Posts

Participate in the State of Liferay Community 2017. Help the community and even win some prizes!