Understanding ServiceBuilder and JavaScript for Liferay

Introduction #

ServiceBuilder is a tool included with Liferay that can be used to build Java services that can be accessed in a variety of ways. That includes, local access from Java code, remote access using web services, etc. This article explores a new possibility introduced in Liferay 4.3: accessing the services from a browser using JavaScript.

The articles is targeted to developers that want to extend Liferay and thus uses the Liferay development environment in the instructions. To follow them you'll have to download Liferay's sourcecode from the downloads section of www.liferay.com or from Sourceforge's subversion repository. The article will refer the directory with the sources as {Liferay-home}

Getting Started #

Let’s start at the {Liferay-home}/portal-impl directory. As of Liferay Portal 4.3.1, it should look like this:

build.xml is the build file for Ant. Opening this file, you’ll see a section with several targets (do a search for “build-service-portlets”):

You can see that there are several entries of the variation “target=build-service-portlet-”; these are ant targets.

What Are Ant Targets? #

Ant targets are just shortcuts for ant commands. For example, if you wanted to run all of the commands in the block above, you could type:

ant build-service-portlet†

instead of doing each one individually. You can, of course, also run each of the individual ant targets.

†Make sure you’ve opened a terminal / cmd prompt and navigated to {Liferay home}/portal-impl

Running Ant #

We’re going to focus on the tags functionality for now, which will use the build-service-portlet-tags command.


 ant build-service-portlet-tags

and you should get this output:


If you’re successful, you’ll know you’re in the right directory and have ant set up correctly.

Generating Files #

Next we’re going to actually make ServiceBuilder do some work.

Go to your file system and open up


I’ve done this in tree view, so it looks like this:

We’re going to edit the file TagsAssetServiceImpl.java.

For each set of classes in an impl folder, you can think of the ServiceImpl class as the one that’s accessible to the “public,” whether that public means SOAP-based web services, REST style web services, or JSON access via JavaScript. ServiceImpl classes will contain several methods, the signatures of which will form the basis for generated code, including JavaScript calls.

Now go ahead and open TagsAssetServiceImpl.java and add the following method code just below the second method and before the closing brace:

  public TagsAsset editAsset(long assetId)
    throws PortalException, SystemException {
    return new TagsAsset;

Now, don’t be confused by the fact that I’m calling this method “editAsset”; in fact that’s probably a bad example because we generally use “update” for methods that apply edits. Just take it as an example for now.

What we’re doing here is adding a new method to the ServiceImpl class. Right now the method itself doesn’t really do anything but it will have an effect on the ServiceBuilder output.

Now go back to your terminal / cmd prompt and run the ant command again. You should see the output below:

Basically what’s going on at this point is ServiceBuilder is generating new files for various services and adding support for the new method (editAsset) that we added. Notice that JSON is one of the services supported.

What happens if you run the ant command again? Well, now that the new method has already been added, your output will look like our initial output above (without the “Writing…” statements). This is true even if you edit the method contents, because the way you access the method (the method “signature”) has not changed. Of course, if you add more input variables to the method, the files will be re-generated.

Let’s go back to the tree structure and also open up TagsAssetLocalServiceImpl.java. You’ll notice there are a lot of different methods for doing stuff to TagsAsset objects. The idea is to use these methods as much as possible in the methods you write in your publicly-exposed TagsAssetServiceImpl class. For example, you may use the updateAsset() method in TagsAssetLocalServiceImpl in the body of the editAsset() method you added to TagsAssetServiceImpl.java.

JavaScript Access #

There’s something else we can check out at this point. If you open up SmartSVN (or whatever SVN client you use) and do a refresh, you should notice that several files have been changed:

This is what it looks like in my SmartSVN after a fresh update and running the ant build-service-portlet-tags command.

Notice that one of the affected files is service.js. What happens if you open up that file?

In my version of SmartSVN I can see a diff of the modified file against the original file in source control. It shows that a new method has been generated called editAsset, which is the name of the method I added to TagsAssetServiceImpl.java.

For JavaScript, this is what you can use to call the “editAsset” method from the presentation layer.

Another useful thing to read are the comments that are generated into every ServiceJSON.java file:

  This class provides a JSON utility for the 
  service utility. The static methods of this class calls the same methods of the
  service utility. However, the signatures are different because it is difficult
  for JSON to support certain types.
  ServiceBuilder follows certain rules in translating the methods. For example,
  if the method in the service utility returns a java.util.List, that
  is translated to a org.json.JSONArray. If the method in the service
  utility returns a com.liferay.portlet.tags.model.TagsAsset, that
  is translated to a org.json.JSONObject. Methods that JSON cannot
  safely use are skipped. The logic for the translation is encapsulated in 
  This allows you to call the the backend services directly from JavaScript. See
  portal-web/docroot/html/portlet/tags_admin/unpacked.js for a reference
  of how that portlet uses the generated JavaScript in 
  to call the backend services directly from JavaScript.
  The JSON utility is only generated for remote services.

Using This In Actual Practice #

Hopefully the existing methods in the Local class for the functional area you’re working with has enough variations that you can get away with not adding any new methods there. If you need to add a new method to access the database, you'll need to learn how to work with Hibernate queries.

0 Attachments
Average (0 Votes)
The average rating is 0.0 stars out of 5.
Threaded Replies Author Date
The Images didnt get added properly at various... Prasad V June 23, 2009 3:59 PM
yes, would someone please re-attach the images? jeff Leitman February 9, 2010 9:23 AM
This is a little bit outdated or? Would be nice... Jakob Fahrner August 17, 2011 4:27 AM
I agree. There's absolutely no information... Doctor ^2 October 14, 2011 12:25 PM

The Images didnt get added properly at various places..

Instead we see this error message "No InterWiki reference defined in properties for Wiki called "image"! "
Posted on 6/23/09 3:59 PM.
yes, would someone please re-attach the images?
Posted on 2/9/10 9:23 AM in reply to Prasad Velagaleti.
This is a little bit outdated or?
Would be nice to have a similar tutorial for IDE
Posted on 8/17/11 4:27 AM.
I agree. There's absolutely no information online for using the IDE to do these things. In fact, there is very little information on all of this stuff save a few random blog posts by people that took the initiative to try and inform people of how these things work. I still can't get any of this to work on my own machine.
Posted on 10/14/11 12:25 PM in reply to Jakob Fahrner.