call service from one portlet to another portlet in liferay

Liferay service can be created by service builder. we can share liferay service across multiple plugins by sharing service jar file in global class path.
 share liferay service across multiple plugins in liferay
Before understanding how to share liferay service, you may like to understand how to create service builder in liferay, we have seen how we can create service and persistence layer in liferay with the help of Service builder.

You might have observed that after running the service builder (by ant build-service command), liferay generates the service jar under /WEB-INF/lib folder of plugin project..


In many business scenario, we need to share liferay service across multiple liferay plugins (ex. portlet, hooks etc).

Share liferay service


If both of these portlets are in same liferay plugin project then the service classes (created by service builder) defined in one portlet are directly available and accessible to all other plugins(portlets,hooks etc) in same plugin project. Please refer my blog on How to create two portlets in single liferay plugin project.

Some times its not possible to have all portlets in same plugin project which wants to share the service builder class. 
In this case, the generated service JAR needs to place at common place from where all the plugins (portlet, hooks etc) can access it. The common place for liferay-tomcat  server is 

<<Tomcat-Liferay-Bundle>>tomcat-x.x.x / lib / ext 


So we need to place the generated service JAR under above location. For example, we have created following two portlet

  • student-portlet.
  • fee-portlet.

We have created the service in student-portlet. So that all the generated classes and JAR files  reside inside student-portlet. We want to access student service class inside fee-portlet. So we need to

  • Move the generated JAR (student-portlet-service.jar) from /WEB-INF/lib (of student-portlet) to <<Tomcat-Liferay-Bundle>>tomcat-x.x.xlibext  
  • Restart the tomcat server. After restart, we can able to access service classes inside fee-portlet.
Note:- I have used Move word so we must have to remove the service JAR at /WEB-INF/lib after its shifted to  <<Tomcat-Liferay-Bundle>>tomcat-x.x.xlibext  
 
And its done. Try to create more than 2 portlet and create the service layer in one portlet and move the service JAR to <<Tomcat-Liferay-Bundle>>tomcat-x.x.xlibext  folder and check if its accessible to all plugins (Portlets, hooks etc).
 

Summing Up

  • Liferay service jar is entry point to access liferay service. It is created by service builder in plugin project.
  • In many business scenario, we need to share liferay service across multiple plugins.
  • The easiest way is to place service jar in global class path (tomcat/lib/ext).

Share This Post

14 Comments - Write a Comment

  1. I am sorry for lacks in the last comment, the bellow are step what I did:

    1. Add libraries to class path. In Eclipse, go to Project > Properties > Java Build Path > Libraries > Add External JARs, then add the sfdc-wsc JAR to this list
    2. Copy external lib to <>tomcat-x.x.x / lib / ext
    3. start server

    Execute gradle task -> build -> package does not found error

    Reply
    1. Hello Hung Tran,

      Welcome to Techblog. Staring from Liferay 7, the underlying architecture of the sever is changed. Now it’s OSGI so everything you deploy must be a osgi compatible module.

      There are two ways to build your custom modules with third party dependency.
      1) Resole and give dependency your third party jar in way they are compatible with OSGI.
      2) Put them in tomcat global class path (lib/ext) folder

      The second option is there for backward compatibility. However it’s not recommended way.

      You said, you need just two external JAR. but there are chances, those 2 jars are dependent on some other jars. This is called transitive dependency.
      To make sure all transitive dependency are resolved properly with option 1, you need to follow below things.

      1) First build your module Maven (by giving the maven dependency for those two external jars). Maven will make sure to include all transitive dependency in generated WARs.(put WAR as target for maven)

      2) Extract the generated WAR and see how many jars are there in WEB-INF/lib folder (along with your two external JARs)

      3) Now create Module in Liferay 7.

      4) Open build.gradle and give following entry for each jar that you found in WAR generated by Maven in step 2. (Below are just example)
      compile group: “net.sf.jasperreports”, name: “jasperreports”, version: “6.4.0”
      compile group: ‘aopalliance’, name: ‘aopalliance’, version: ‘1.0’
      compile group: ‘org.bouncycastle’, name: ‘bctsp-jdk14’, version: ‘1.38’
      5) Open bnd.bnd file and give class path for each of your jar as below (Below are just example)
      Bundle-ClassPath:\
      .,\
      lib/stax-api.jar,\
      lib/stax-api-1.0.jar,\
      lib/stax.jar,\
      6) In bnd.bnd file once you define class path of your jars, You need to define include resource as below. This basically defined which version of jar to be incldued (Below is just for example)
      -includeresource:\
      lib/stax-api.jar=stax-api-1.0.1.jar,\
      lib/stax-api-1.0.jar=stax-api-1.0-2.jar,\
      lib/stax.jar=stax-1.2.0.jar,\

      7) At the end, in case if you find any error for package, you need to exclude it if they are options as below (This is just for example)
      Import-Package: \
      !antlr,\
      !antlr.*,\
      !com.apple.mrj,\

      Hope this help your problem. Feel free to ask questions / Give suggestions.

      Regards
      Nilang

      Reply
      1. Hello Nilang,

        Thank you very much for your detail suggestion, but I think there are some problem with my my issue, let’s me tell more detail about it.
        1. The first library I need to import to MVC portlet is salesforce Web Service Connector, it is available in the maven:
        https://mvnrepository.com/artifact/com.force.api/force-wsc/40.1.1
        I just need to add below line to build.gradle in my mvc portlet, is it right?
        compile group: ‘com.force.api’, name: ‘force-wsc’, version: ‘40.1.1’

        2. The second one is WSDL Enterprise library that I need to generate from salesforce library and XML instruction by command line:
        java -jar target/force-wsc-40.1.1-uber.jar
        – inputwsdlfile is the name of the WSDL to generate stubs for.
        -outputjarfile is the name of the jar file to create from the WSDL.

        So I think I need to import 2 above libraries locally so that nothing change with it, moreover these libraries is provided by our partner, so I cannot share them.

        I tried to copy them into lib/ext, add some lines into bnd.bnd (as in question I mentioned) but nothing change, the issue still not resolved, please give me some suggestion to solve them.

        Thank you and best regards,
        Hung Tran

        Reply
        1. Hello Nilang,

          I am sorry but the command line to generate library is changed, I dont know the reason.

          The correct one is java -jar target/force-wsc-40.1.1-uber.jar inputwsdlfile outputjarfile
          with:
          -inputwsdlfile is the name of the WSDL to generate stubs for.
          -outputjarfile is the name of the jar file to create from the WSDL.

          Sorry for this inconvenience!

          Best regards,
          Hung Tran

          Reply
  2. Hello Nilang,

    I have a problem with import external library to use in my MVC portlet, the used version is liferay 7 GA4 .

    I have 2 external private jar library that is not part of any repository, and i want to use that library in my function, the following steps are what I did but still not success, can you please give me some suggestion?

    The java source code is ok until i use gradle build to build project, the following error occur:
    error: package does not exist import

    I also set the bnd file as follow according to blog post of DAVID H NEBINGER: https://web.liferay.com/web/user.26526/blog/-/blogs/osgi-module-dependencies But nothing is improved

    I also tried with other options, but still fail.

    Please give some suggestion.

    Thank you and best regards,
    Hung Tran

    Reply
  3. PROBLEM
    in using service of student in fee-portlet is not working, i have done all the steps what have you mentioned above but in fee-porlets java class there is no coming entity’s(studen)studentImpl() then how i will create object of interface of the sudent’s,if i do,t create obejct then how i wll set data for database,i used (student h= (student)studentUtil()) but in conse come error can cast,kindly give solution plzzz

    Reply
    1. Hi Niraj,

      Welcome to Tech blog and thanks for writing here. I have few questions.
      1) What do you mean by fee-portlet. What code you are using ?
      2) did you created service.xml in fee-portlet ? For you information, the class will be only generated in portlet where you have service.xml. They will only generate once you build the service.
      3) for performing CRUD operation, I am writing separate blog so will inform you once that is finish.

      Feel free to ask questions / give suggestions.

      Regards
      Nilang

      Reply

Post Comment