Forums

Home » Liferay Portal » English » 3. Development

Combination View Flat View Tree View
Threads [ Previous | Next ]
toggle
J J G
Two Custom Portlets==>referencing services defined in one into other por
January 11, 2011 5:05 AM
Answer

J J G

Rank: New Member

Posts: 16

Join Date: June 8, 2007

Recent Posts

Liferay version : 6.0.5
Two portlets deployed individually as WAR files.

Portlet structure is as follows
 1test-1-portlet
 2    build.xml
 3    -docroot
 4        -css
 5        -js
 6        -jsp
 7        -WEB-INF
 8           -lib
 9           -sql
10           -tld
11           liferay-display.xml
12           liferay-plugin-package.properties
13           liferay-portlet.xml
14           portlet.xml
15           service.xml
16           web.xml


 1test-2-portlet
 2    build.xml
 3    -docroot
 4        -css
 5        -js
 6        -jsp
 7        -WEB-INF
 8           -lib
 9           -sql
10           -tld
11           liferay-display.xml
12           liferay-plugin-package.properties
13           liferay-portlet.xml
14           portlet.xml
15           service.xml
16           web.xml


Both portlets test-1-portlet and test-2-portlet are deployed on tomcat as individual WAR files like test-1-portlet.WAR and test-2-portlet.WAR


=============================test-1-portlet service.xml
 1
 2<service-builder package-path="com.sample.portlets.services">
 3    <namespace>Sample</namespace>
 4    <entity name="CourseType" local-service="true" remote-service="true">
 5        <!-- PK fields -->
 6        <column name="courseTypeId" type="long" primary="true"/>
 7       
 8        <!-- Group Instance -->
 9        <column name="groupId" type="long" />
10       
11        <!-- Audit fields -->
12        <column name="companyId" type="long" />
13        <column name="modifiedDate" type="Date" />
14        <column name="modifiedBy" type="long" />
15       
16        <!-- Other fields -->
17        <column name="courseTypeName" type="String" />
18       
19        <!-- Order -->
20        <order by="asc">
21            <order-column name="courseTypeName" case-sensitive="false" />
22        </order>
23    </entity>
24   
25    <entity name="StudentType" local-service="true" remote-service="true">
26        <!-- PK fields -->
27        <column name="studentTypeId" type="long" primary="true"/>
28       
29        <!-- Group Instance -->
30        <column name="groupId" type="long" />
31       
32        <!-- Audit fields -->
33        <column name="companyId" type="long" />
34        <column name="modifiedDate" type="Date" />
35        <column name="modifiedBy" type="long" />
36       
37        <!-- Other fields -->
38        <column name="studentTypeName" type="String" />
39       
40        <!-- Order -->
41        <order by="asc">
42            <order-column name="studentTypeName" case-sensitive="false" />
43        </order>
44    </entity>
45</service-builder>


=============================test-2-portlet service.xml

 1<service-builder package-path="com.sample.programs.services">
 2    <namespace>Sample</namespace>
 3    <entity name="Course" local-service="true" remote-service="true">
 4        <!-- PK field -->
 5        <column name="courseId" type="long" primary="true"/>
 6       
 7        <!-- Other fields -->
 8        <column name="courseName" type="String" />
 9        <column name="courseSummary" type="String" />
10       
11       
12        <!-- References -->
13        <reference package-path="com.liferay.portal" entity="WorkflowInstanceLink" />
14       
15        <reference package-path="com.sample.portlets.services" entity="CourseType" />
16        <reference package-path="com.sample.portlets.services" entity="StudentType" />
17   </entity>
18
19</service-builder>



As can be seen in test-2-portlet.xml I need references of CourseType and StudentType services in Course type defined in test-1-portlet.xml.

But when I execute "build-service" target from test-2-portlet I face the following error:

 1Buildfile: E:\Liferay\portlets\sample-programs-portlet\build.xml
 2build-service:
 3     [java] Loading jar:file:/D:/Development/Liferay/ee-6.0/lprtl-ee-tomcat-6.0/tomcat-6.0.29/webapps/ROOT/WEB-INF/lib/portal-impl.jar!/system.properties
 4     [java] Loading jar:file:/D:/Development/Liferay/ee-6.0/lprtl-ee-tomcat-6.0/tomcat-6.0.29/webapps/ROOT/WEB-INF/lib/portal-impl.jar!/portal.properties
 5     [java] Loading file:/D:/Development/Liferay/ee-6.0/lprtl-ee-tomcat-6.0/tomcat-6.0.29/webapps/ROOT/WEB-INF/classes/portal-ext.properties
 6     [java] Loading jar:file:/D:/Development/Liferay/ee-6.0/lprtl-ee-tomcat-6.0/tomcat-6.0.29/webapps/ROOT/WEB-INF/lib/portal-impl.jar!/com/liferay/portal/tools/dependencies/portal-tools.properties
 7     [java] 12:36:40,515 INFO  [PortalImpl:277] Global lib directory /D:/Development/Liferay/ee-6.0/lprtl-ee-tomcat-6.0/tomcat-6.0.29/lib/ext/
 8     [java] 12:36:40,515 INFO  [PortalImpl:297] Portal lib directory /D:/Development/Liferay/ee-6.0/lprtl-ee-tomcat-6.0/tomcat-6.0.29/webapps/ROOT/WEB-INF/lib/
 9     [java] java.io.IOException: Unable to open resource in class loader com/sample/portlets/services/service.xml
10     [java]     at com.liferay.portal.kernel.util.StringUtil.read(StringUtil.java:604)
11     [java]     at com.liferay.portal.kernel.util.StringUtil.read(StringUtil.java:567)
12     [java]     at com.liferay.portal.tools.servicebuilder.ServiceBuilder.getEntity(ServiceBuilder.java:1246)
13     [java]     at com.liferay.portal.tools.servicebuilder.ServiceBuilder.<init>(ServiceBuilder.java:960)
14     [java]     at com.liferay.portal.tools.servicebuilder.ServiceBuilder.<init>(ServiceBuilder.java:396)
15     [java]     at com.liferay.portal.tools.servicebuilder.ServiceBuilder.main(ServiceBuilder.java:176)



How can we achieve the communication of services residing in one custom portlet(in my case it is test-1-portlet) into other custom portlet(in my case it is test-2-portlet) and NOT the communication between the services residing in ROOT webapp of Liferay bundled tomcat and custom portlet services for e.g. shown by having a reference of WorkflowInstanceLink in test-2-portlet service.xml?

Thanks.
Mohammed Azam
RE: Two Custom Portlets==>referencing services defined in one into other
January 11, 2011 6:56 AM
Answer

Mohammed Azam

Rank: Regular Member

Posts: 159

Join Date: November 6, 2009

Recent Posts

I hope this will give u some Idea!
One service.xml
J J G
RE: Two Custom Portlets==>referencing services defined in one into other
January 11, 2011 9:20 PM
Answer

J J G

Rank: New Member

Posts: 16

Join Date: June 8, 2007

Recent Posts

Thanks Mohammed.
That would surely works and have successfully implemented 4 portlets in a single WAR file using that method.
But the scenario mentioned in my earlier post is quite different as per my requirements and I am looking for a solution to make that work, in case it is possible.
In case I am unable to find any I can always switch to the method you suggested.

In the meanwhile if you or anybody in the community has some suggestions on how to make portlets work as per the details mentioned in my earlier post I would really thankful.

Thanks.
Mohammed Azam
RE: Two Custom Portlets==>referencing services defined in one into other
January 12, 2011 8:39 AM
Answer

Mohammed Azam

Rank: Regular Member

Posts: 159

Join Date: November 6, 2009

Recent Posts

J J G:
Thanks Mohammed.
That would surely works and have successfully implemented 4 portlets in a single WAR file using that method.
But the scenario mentioned in my earlier post is quite different as per my requirements and I am looking for a solution to make that work, in case it is possible.
In case I am unable to find any I can always switch to the method you suggested.

In the meanwhile if you or anybody in the community has some suggestions on how to make portlets work as per the details mentioned in my earlier post I would really thankful.

Thanks.

Hi,

The reason of using the workflow... in your portlet 2 is because the .class file is available in the portal level. If you want similar approach then Check this link
A S
RE: Two Custom Portlets==>referencing services defined in one into other
June 12, 2012 2:34 AM
Answer

A S

Rank: New Member

Posts: 19

Join Date: April 30, 2012

Recent Posts

Did you ever find a solution to this? I've got the same issue and I'm pretty sure there's a simple solution, it's just escaping me at the minute. I've tried all the stuff about including the JAR and specifying dependencies in the liferay-plugin-package.properties but that didn't fix it. Not surprising really though as the error says it's looking for the service.xml, so it's after the data definitions for the imported object so far as I can tell, not the classes.

Any advice much appreciated.
A S
RE: Two Custom Portlets==>referencing services defined in one into other
June 21, 2012 5:36 AM
Answer

A S

Rank: New Member

Posts: 19

Join Date: April 30, 2012

Recent Posts

It seems that the solution is to place the "service.xml" from the linked portlet into the Portlet you're developing, at "docroot/WEB-INF/src", matching the folder structure to the package structure, so in the case in the thread "docroot/WEB-INF/src/com/sample/portlets/services/service.xml". Not sure this is a good idea though as it duplicates the "service.xml" file?

Also, service builder then builds code which tries to reference the ".model.impl.***Impl" which it then can't find in the "****-service.jar" in the lib folder. So the auto-generated code won't even compile.

If anyone has any ideas that would be really helpful.

Cheers.
David H Nebinger
RE: Two Custom Portlets==>referencing services defined in one into other
June 21, 2012 6:41 AM
Answer

David H Nebinger

Community Moderator

Rank: Liferay Legend

Posts: 11770

Join Date: September 1, 2006

Recent Posts

A S:
It seems that the solution is to place the "service.xml" from the linked portlet into the Portlet you're developing, at "docroot/WEB-INF/src", matching the folder structure to the package structure, so in the case in the thread "docroot/WEB-INF/src/com/sample/portlets/services/service.xml". Not sure this is a good idea though as it duplicates the "service.xml" file?


This is a bad idea. Even the original responder's idea of putting the jar file into tomcat's lib/ext directory is old school...

Basically any time there would be overlap between two service.xml files, you should only use one.

So from the OP's thing where there is Course in portlet A and CourseType in portlet B, the service.xml file should reside in portlet A and have both types defined in it. Portlet A becomes the host for all of the data services related to Course objects.

Even though the code in portlet A may not reference the CourseType object or services, it still hosts them.

Portlet B will then list portlet A as a required deployment context in the liferay-plugin-package.properties file. The Liferay IDE will ensure that the service jar from portlet A is copied into the WEB-INF/lib folder of portlet B, so it will have no problem accessing the CourseType objects and services from portlet A.

Never ever copy the same service.xml or entities from a service.xml file to other portlets. When other portlets need access to the entities and services, they will list the portlet providing the service as a required deployment context and the IDE will keep things together.

Now if portlet B also needs it's own entities that do not have a connection to portlet A's Course entities, then it should have it's own service.xml file that contains only it's entities, not any of the entities in portlet A's service.xml.

If necessary, once portlet B has portlet A listed as a required deployment context the IDE will copy portlet A's service jar to portlet B's WEB-INF/lib directory and portlet B's service.xml can then reference the entities from the jar. But this should be avoided because it's just going to add a layer of confusion (i.e. portlet C lists portlet B as a required deployment context so it gets portlet B's service jar, but since it doesn't list portlet A as a required deployment context it will get class not found exceptions; is much easier if portlet A hosts all of the entities rather than trying to split them apart).
A S
RE: Two Custom Portlets==>referencing services defined in one into other
June 21, 2012 8:04 AM
Answer

A S

Rank: New Member

Posts: 19

Join Date: April 30, 2012

Recent Posts

Surely this ends up with Portlet A listing a whole load of entities from everywhere though?

So, if Portlet A is a Department, and a Course (Portlet emoticon needs to reference it, we put the Course Data Service into A

Then because a Year references a Course, that goes in there too.

Then a Module references a year, so that then goes in there.

Then a Person (Portlet C) needs a department, so that goes into A as well.

Department has a type, so that'll be in Portlet A too

Along with Institution, as that is linked to department.

Over time that's going to be rather a monolithic service.xml surely? If we only avoid putting something into Portlet A when it's not related to any of the other variety of things now living in Portlet A. I do however take the point that copying the XML is not wise, and ultimately doesn't work anyway because SB generates code that doesn't work, probably best to move off that one.

Is the "official" recommendation to just stick the data services for anything that may reference anything else into a "data service holder" portlet do you know? I don't think I'd call it department in my case, as that may confuse.

Cheers.
David H Nebinger
RE: Two Custom Portlets==>referencing services defined in one into other
June 21, 2012 8:29 AM
Answer

David H Nebinger

Community Moderator

Rank: Liferay Legend

Posts: 11770

Join Date: September 1, 2006

Recent Posts

A S:
Over time that's going to be rather a monolithic service.xml surely?


Certainly does, but the other option is that a new portlet has required deployment context dependencies on many other portlets providing services...

I don't think there is an official position, but if you look at Liferay, for example, they use a monolithic service file to provide services to all portlets, whether the internal or external portlets.

I don't think a monolithic service file is bad thing. It keeps your data needs centralized rather than spreading it out over different portlets, promotes reuse as much as possible, ...

Locally we have a 'data-services' portlet plugin that we keep updating the service.xml in, adding new entities and service methods. The development team knows to use this portlet for the required deployment context and we maximize re-use.