Forums de discussion

Problem to cosume Liferay 7 service in JSF portlet

Karel Bělunek, modifié il y a 6 années.

Problem to cosume Liferay 7 service in JSF portlet

New Member Publications: 8 Date d'inscription: 23/06/17 Publications récentes
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.
thumbnail
Neil Griffin, modifié il y a 6 années.

RE: Problem to cosume Liferay 7 service in JSF portlet

Liferay Legend Publications: 2655 Date d'inscription: 27/07/05 Publications récentes
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 liferayfaces.org)
2. Your ServiceBuilder generated Project Source

Then we can try and reproduce the problem for you.

Kind Regards,

Neil
Karel Bělunek, modifié il y a 6 années.

RE: Problem to cosume Liferay 7 service in JSF portlet

New Member Publications: 8 Date d'inscription: 23/06/17 Publications récentes
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
thumbnail
Neil Griffin, modifié il y a 6 années.

RE: Problem to cosume Liferay 7 service in JSF portlet (Réponse)

Liferay Legend Publications: 2655 Date d'inscription: 27/07/05 Publications récentes
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:
compileOnly 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:
providedCompile project (":modules:testsvc:testsvc-api")

And then rebuild+redeploy the PrimeFaces portlet WAR module.

Kind Regards,

Neil
Karel Bělunek, modifié il y a 6 années.

RE: Problem to cosume Liferay 7 service in JSF portlet

New Member Publications: 8 Date d'inscription: 23/06/17 Publications récentes
Hi Neil,

I followed your advice and everything works fine.

Thank you very much!

Kind Regards
Karel Belunek
thumbnail
Neil Griffin, modifié il y a 6 années.

RE: Problem to cosume Liferay 7 service in JSF portlet

Liferay Legend Publications: 2655 Date d'inscription: 27/07/05 Publications récentes
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
thumbnail
Kyle Joseph Stiemann, modifié il y a 6 années.

Thread Split

Liferay Master Publications: 760 Date d'inscription: 14/01/13 Publications récentes