Milen Dyankov

Software Engineer, Consultant, Developer Advocate

Creating Liferay portlet with liferay-maven-sdk

October 09, 2009 | 6 Minute Read

This post will demonstrate how liferay-maven-sdk can be employed to build a Liferay portlet using Liferay’s Service Builder feature. For this purpose we will create service-builder-portlet which is capable of displaying a list of players and adding a new player to this list. The model, persistence layer and data access services will be generated by Service Builder.

But first things first. Download and install liferay-maven-sdk if you haven’t done so already (have a look at Download and Install page for instructions). Once liferay-maven-sdk is installed in your local repository, you can create the portlet.

So enter the folder (or create one) where you keep your portlets and execute mvn archetype:generate you should see a list of available archetypes starting with

Choose archetype:
1: local -> liferay-portlet-archetype (Liferay portlet archetype)
2: local -> liferay-theme-archetype (Liferay theme archetype)
3: internal -> appfuse-basic-jsf (AppFuse archetype for creating a web application with Hibernate, Spring and JSF)
4: internal -> appfuse-basic-spring (AppFuse archetype for creating a web application with Hibernate, Spring and Spring MVC)
...
Choose a number: (1/2/3/4/...) :1

Type 1 and press enter to choose liferay-portlet-archetype. Then provide groupId, artifactID, package and version. For example:

Define value for groupId: : com.commsen.liferay.examples.portlet.servicebuilder
Define value for artifactId: : service-builder-portlet
Define value for version: 1.0-SNAPSHOT: : 1.0
Define value for package: com.commsen.liferay.examples.portlet.servicebuilder: :

Additionally you may execute mvn eclipse:eclipse to setup Eclipse IDE if, that is what you are using! At this time your portlet skeleton is ready and you may compile it and even create WAR, but it of course does nothing special.

Let’s now add data model and services. Create file service-builder-portlet/src/main/webapp/WEB-INF/service.xml:

<?xml version="1.0"?>
<!DOCTYPE service-builder PUBLIC "-//Liferay//DTD Service Builder 5.2.0//EN" "http://www.liferay.com/dtd/liferay-service-builder_5_2_0.dtd">
<service-builder package-path="com.commsen.liferay.examples.portlet.servicebuilder">
  <namespace>SB</namespace>
  <entity
    name="Player"
    local-service="true"
    remote-service="true">

    <!-- PK fields -->
    <column name="playerId" type="long" primary="true" />

    <!-- Other fields -->
    <column name="name" type="String" />
    <column name="active" type="boolean" />
    <column name="score" type="int" />
    <column name="birthday" type="Date" />
    <column name="description" type="String" />

    <!-- Order -->
    <order by="asc">
      <order-column name="name" />
    </order>

    <!-- Finder methods -->
    <finder name="ActivePlayers" return-type="Collection">
      <finder-column name="active" />
    </finder>
  </entity>
</service-builder>

The portlet projects created by liferay-portlet-archetype contain maven profile with lifray-maven-plugin’s build-service goal attached to generate-sources phase. To run ServiceBuilder you need to activate the profile:

mvn -P build-service package

If you read carefully the messages you will realize that service and persistence classes were generated in service-builder-portlet/src/main/java-service-api/ folder. Also there should be a few implementation files in service-builder-portlet/src/main/java/.

Now we’ll add custom methods. Open the following file service-builder-portlet/src/main/java/com/commsen/liferay/examples/portlet/servicebuilder/service/impl/PlayerLocalServiceImpl.java and paste this code:

public void addPlayer(String name, boolean active, int score, Date birthday, String desc) throws PortalException, SystemException {    
  long playerId = CounterLocalServiceUtil.increment();    
  Player player = PlayerUtil.create(playerId);    
  player.setName(name);   
  player.setActive(active);   
  player.setScore(score);   
  player.setBirthday(birthday);   
  player.setDescription(desc);    
  PlayerUtil.update(player, false);  
}
public List<Player> getAllPlayers() throws PortalException, SystemException {   
  return PlayerUtil.findAll();  
}

We added methods to the implementation class. The next time we compile the code we need to activate the build-service profile again in order for Service Builder to react on the change and regenerate the API and interfaces. If you want to try it now simply execute

mvn -P build-service compile

Now we can start using these services in our portlet. Open service-builder-portlet/src/main/java/com/commsen/liferay/examples/portlet/servicebuilder/JSPPortlet.java and add this method

@ProcessAction(name = Constants.ADD)  
public void addPlayer(ActionRequest actionRequest, ActionResponse actionResponse) throws PortletException, IOException {   
  String name = ParamUtil.getString(actionRequest, "name");   
  boolean active = ParamUtil.getBoolean(actionRequest, "active");   
  int score = ParamUtil.getInteger(actionRequest, "score");   
  String description = ParamUtil.getString(actionRequest, "description");   
  int year = ParamUtil.getInteger(actionRequest, "birthday_year");   
  int month = ParamUtil.getInteger(actionRequest, "birthday_month");   
  int day = ParamUtil.getInteger(actionRequest, "birthday_day");    
  Calendar calendar = Calendar.getInstance();   
  calendar.set(Calendar.YEAR, year);   
  calendar.set(Calendar.MONTH, month);   
  calendar.set(Calendar.DAY_OF_MONTH, day);    
  try {    
    PlayerLocalServiceUtil.addPlayer(name, active, score, calendar.getTime(), description);   
  } catch (Exception e) {    
    throw new PortletException("Failed to add player", e);   
  }  
}

This method handles adding players to database by calling the method we created earlier. To complete the portlet we only need the JSP page which displays the list and render HTML form to add users. The page source code is available here.

That’s all! We can now create WAR file (mvn package) deploy it and add some players to our database! For more details have a look at portlet’s source code available in examples/service-builder-portlet folder of liferay-maven-sdk.