Sharing Liferay Service Layer between two plugin portlet contexts

Sharing Liferay Service Layer between two plugin portlet contexts

 
 
Objective:
 
Using one plug-in portlet services in other plug-in portlet.
 
In liferay we develop portlets in plug-in portlet environment. Here some time we may develop group of portlets in single plug-in context or sometimes we develop in multiple plug-in contexts.
 
When we get requirement like we want use one plug-in context liferay services in other plug-in context, we need to follow the some sequence of steps when we share service layer between two different liferay plug-in portlet contexts.
 
Download  Sharing service layer Example  portlets from following location
 
You can find source and war file
 
 
Note: 
 
This portlet developed in  Liferay6.1GA2 EE you can change source based on your liferay version, please go through my previous articles to know more information about this.
 
Procedure for deploy portlet:
 
You can use war file and directly place in your portal deploy folder and test or you can also use source to deploy portlet.
 
First deploy the  Child-portlet make sure deployment should be successful.
 
Second deploy  Parent-portlet.
 
Drag and Drop Parent portlet which in sample category then you can see the child table row data.
 
Note:
 
Before use this portlet read entire article and then test the portlet
 
 
Frits we need to identify required dependent plug-in context
 
We need to specify the required plug-in context name in liferay-plugin-package.properties file as follows 


 
required-deploymentcontexts=
PluginPortletContextName1,PluginPortletContextName2
 
Example:
 
required-deployment-contexts=Child-portlet
 
 
 
Note: if multiple contexts then speared by comma
 
First deploy the liferay plug-in portlet context which we mention in  liferay-plugin-package.properties as a property  required-deployment-contexts.
 
Next deploy the second portlet
 
Example:
 
Assume we have two plug-in contexts  Parent-portlet and  Child-portlet
 
In  Parent-portlet I have one entity called  Parent and in  Child-portlet I have entity called  Child.
 
Now I create service builder for both plug-in portlets and run the service builder. Here both are two different plug-in contexts
 
Now we will get two service jar files in each plug-in portlet WEB-INF/lib directory ( Parent-portlet.war/WEB-INF/lib/Parent-portlet-service.jar and Childt-portlet.war/WEB-INF/lib/Child-portlet-service.jar).
 
Now we want use  Child-portlet services in  Parent-portlet for this need to specify the  Child-portlet context information in  Parent-portlet. This information we need provided by  liferay-plugin-package.properties of Parent-portlet as follows
 
 
required-deployment-contexts=Child-portlet
 
 
Once we mention above property then  Child-portlet services will be available in  Paretn-portlet means we can use  ChildLocalServieUtil, ChildSeriveceUtil and ChildUtil classes in Parent-portlet(As we know our entity in child portlet is  child)
 
Now simple get child information in parent portlet JSP page as follows
 
 
<%@ taglib uri="http://java.sun.com/portlet_2_0" prefix="portlet" %>
<%@page import="com.meer.db.service.ChildLocalServiceUtil"%>
<portlet:defineObjects />
<h1>This is parent portlet</h1>
<%=ChildLocalServiceUtil.getChild(1)%>
 
 
Now deploy the  Child-portlet first
 
Next and finally we have to deploy the  Parent-portlet.
 
Note:
 
In the development in Liferay IDE/Eclipse when we use child services it will show compile time errors but don’t worry you can deploy the portlet.
 
If you really don’t want see such compile time errors you can add services jar file in portlet build path.
 
In above example you can add  Child-portlet-service.jar file in  Parent-portlet build path. Simple right click on Parent-portlet in eclipse and select build path option add Child-portlet-service.jar before do this you need to run service builder for Child-portlet then only  Child-portlet-service.jar file available.
 
Observations:
 
When we want share service layer between two plug-in contexts the services jar file should be available in other portlet plug-in context class path i.e. WEB-INF/lib.
 
In above example we are sharing Child-portlet services in Parent-portlet so we need to make available  Child-portlet-service.jar file in  Parent-portlet/WEB-INF/lib so that we can use  Child-portlet service classes.
 
To do above task we need to mention the child context information in parent portlet as I mention above property.
 
After deployment of two portlet if you see the  Parent-portlet/WEB-INF/lib(in server deployment directory) you can find the  Child-portlet-service.jarfile. Because of this only we able access the child portlet services.
 
The following is Parent-portlet lib after deployment in the server
 
 
 
 
Screens:
 
Child-portlet with service.xml file
 
 
 
 
Parent-portlet and we mentioned child deployment context.
 
 
 
 
The following is Parent-portlet which is accessing Child-portlet services.
 
 
 
 
Author
Meera Prince
www.liferaysavvy.com
Blogs
Hi Meera,
nice example, keep doing good job!

Just wanted to suggest you two things. It is more natural that dependent plugin (one that declares dependencies via required-deployment-contexts) is called child. Also it would be easier for audience if you format your source-code statements with code formatting.

Best regards!
thank you Igor Beslic i will follows your suggestion...
Things I found out in at least Liferay 6.2 EE:

1. Do not let your entity end with "Service" (e.g. MyJournalService). It will break the generator for the <Entity>LocalService-Interface. It will not generate the method to get the entity by primary key/composit key. So the service builder will generate broken code as the LocalServiceBaseImpl will override the method not existing in the interface.

2. The package-paths for the two services must be different! Otherwise you will only be able to call one service. Calling the second service will result in a "NoSuchBeanDefinitionException". Try calling the ParentLocalServiceUtil.getParent(1) in your example Parent-Portlet's view.jsp. It will throw this exception.

Those two things took me half a day to find out :-/ So I thought I should share.
I have two portlets and I want to share a service between them. They are created in their own liferay project folder/path. So I think they are in different package-paths. And the service that I want to share is placed in the tomcat\lib\ext folder. But I get the "NoSuchBeanDefinitionException" error. I am using 6.2 CE. I think I got the service to be shared when I was using 6.1 CE. But I am having a hard time with 6.2. CE. Any help provided is greatly appreciated.
I guess remove jar from the tomcat/lib/ext folder.
Make sure two things.
1. Add your service jar into ROOT/WEB-INF/lib folder.
2. In your consumer portlet's liferay-plugin-package.xml file under "Portal Dependency Jars" click on Add and select the custom service jar. And under "Required Deployment Context" select your custom service project.

Redeploy custom portlets and hopefully that should work.
I got NoSuchBeanDefinitionException when place services at the same package path.

Thank you! Helpful reply.
Hi,

How many child portlets we can add in one parent portlet.
for example:
required-deployment-contexts=Child-portlet1,Child-portlet2

we can add like above example?
But if you try this:

Child-portlet requires Parent-portlet services
and Parent-portlet requires Child-portlet services

then the deployment will block forever
both portlets will wait each other in queue till one of them be deployed.

This is my problem.