Liferay Developer Cookbook


The intent of this page is to be a starting point for any one who wants to contribute to the Liferay code.

Building and Installing Liferay on Glassfish v2 and MySQL#

See this wiki on how to do build and install glassfish.

Raising LEP#

When ever you want to add a new feature / fix a bug, you start by raising a LEP. To do this,
1. Log on to with your JIRA login and password.
2. Make sure you select "Liferay Portal" as the project while creating a new LEP. The default is "Liferay IDE".
3. After raising LEP, assign it to your self or the concerned person. You need permissions to do this. Contact LR Administrator for this.
4. You would get an e-mail as a confirmation.


For any new files that you add, make sure that you use the appropriate license file.

Adding new Entity / Service / Persistence Class #

If your fix / feature requires you to add/modify a service or a persistence class

1. When you add an entry in the service.xml, make sure that it is in alphabetical order.
2. In service.xml, make ensure that all the entity names have the same number of words. For eg. You cant have an entity named Bookmark (one word) and an entity named BookmarkFolder (2 words). All the entities in the file should have the same number of words.This becomes very useful as you have more and more objects. One good example to look at is bookmarks/service.xml.
3. For more information on how to use the ServiceBuilder, refer to this|
4. For information on the attributes of service.xml, refer to this

Adding a new JSP#

If your fix / feature requires you to add/modify a jsp in portal-web.

  • make sure to run __ant compile-tomcat__ under portal-web module. Please note that, you need to set server type as tomcat (in before executing compile-tomcat target.

JSP/HTML Coding Guidelines#

Here are some guidelines to be followed while coding JSPs or HTML files for Liferay.This is intended to serve as a starting point for developers and is not the complete list. It is recommended to compare the new files with the existing JSPs and infer patterns of coding and formatting.

Tabs and Linebreaks

1. There should be one linebreak (not the <br> tag, but the newline '\n')between (before and after)scriplet and html code snippet;


<% Java code %>

<html resume>

2. There should be no tab spacing between the <form> tag and the enclosed form elements.

3. The hidden form fields should immediately follow the <form> tag, followed by the other form elements.

4. Between the <form> tag and the input elements, there should be no line breaks, but between <form> tag and any form table, there should be a linebreak.

5. There should be a linebreak between the typical save and the cancel buttons at the end of the form.


<input type="submit" value="<liferay-ui:message key="save" />" />

<input type="button" value="<liferay-ui:message key="cancel" />"


6. There should be no tab spacing between <table> and <tr> element, but a tab spacing is required between <tr> and <td>. There should be a tab spacing betwen <td> and the elements inside the <td>, even if it is a scriplet that goes inside.

7. There should be a blankspace after the starting tag of the JSP expression ( <%=) and before the closing tag (%>)

<%= expression %>

8. For if and for loops in scriplets, there should be a space after for/if and '(' and before the starting paranthesis '{'

for (int i = 0; i< results.size(); i++) {

9. Last, but not the least, it is recommended to check every line of the file for formatting and patterns.

10. Dual license (Liferay + Sun CDDL) is to be included in all JSPs within a scriplet.

Suggestions for using Liferay Tags#

1. For tables displaying data, it is recommended to use the SearchContainer object:


2. For forms that require inputs from the users, it is best recommended to enclose the form elements inside a two-column lfr-table class (a table), with one input per row: the label being the first column and the input element being the second column. (For examples, refer to an existing Liferay JSP)

3. To obtain request parameters, ParamUtil.getString(request, paramName) is recommended.

4. All JSPs are to include an init.jsp - which imports the required java classes in alphabetical order.

5. For actions to be performed on entities - (edit, delete, manage), it is recommended to use an alternate JSP - entity_action.jsp and include it as the last element in the SearchContainer object.

6. Use of jQuery is preferred to Javascript on the client side.

7. The names of forms are patternized :

<form action="<portlet:actionURL />" method="post" name="<portlet:namespace />fm">

is the recommended pattern.

8. For new additions to Liferay's, add the message key as in <liferay-ui:message key="key" />

and add the consolidated keys and the recommended values to the LEP. They would be added after grammatical and linguistic check

9. An input parameter - redirect that has <%= currentURL %> as value should be passed in all the forms along with the other input parameters, This points to the current URL and should be the redirect URL for cancel buttons typically.

10. If the JSP has multiple view elements, based on conditions (read as actions), use of <c:choose> and <c:when> is recommended.

Adding a new Jar#

If your fix / feature requires you to add/modify a jar,

1. Copy the jar into Liferay_code_dir/lib/portal.
2. Modify Liferay_code_dir/lib/versions.xml and add the jar info (in alphabetical order).
3. Run "ant build-lib-versions" from portal-impl. This will modify the Liferay_code_dir/lib/versions.html.
4. Check-in the jar, versions.xml and versions.html.


  • All the jars that we add, would ultimately go the liferay-portal.war/WEB-INF/lib. Jars can be added to the server classpath only if they contain no implementations. It should have only interfaces. Try to avoid adding jars in the server classpath.
  • When you add a new jar, make sure that you update the <trunk>/.classpath file, <trunk>/tools/ext-tmpl/ and <trunk>/nbproject/project.xml file with the new jars.These are the Eclipse and NB project files. Remember to check them in also.
  • Jar names should __NOT__ have version numbers in them. Eg. apache-commons-loggin-2.0.jar

Adding DB Script Files#

If your fix / feature requires you to add/modify sql script files, Lets say you want to add jbm-tables.sql. Here are the steps that you need to follow,

  • Put the jbpm-tables.sql file in <trunk>\sql directory.
  • Add @include jbpm-tables.sql to update-5.0.1-5.1.0.sql, portal-minimal.sql, portal.sql in alphabetical order.
  • In"compile-dependencies" target of <trunk>\portal-impl\build.xml, search for quartz-tables.sql and add jbpm-tables.sql (alphabetically). This would add jbpm-tables.sql to the portal-impl.jar.
  • Add dbUtil.runSQLTemplate("jbpm-tables.sql", false); to createTablesAndPopulate() in ReleaseLocalServiceImpl class.
  • Run "ant jar" on the portal-impl directory to make the portal-impl.jar.
  • Ensure that the .sql file is properly formatted. You can use [SQLInForm|] tool to do the formatting.They have the online / desktop version.
  • Follow quartz-tables.sql pattern and ensure that the scripts are aligned properly and in alphabetical format.
  • All these steps would ensure that the jbpm tables would be created (if they dont exist) while the server is started.

Adding Custom Query#

Assume that you want to add custom queries for the workflow portlet. This is what you should be using
1. If you want to add any custom queries, then add the workflow.xml in <trunk>\portal-impl\src\custom-sql directly and add a corresponding entry in portal-impl\src\custom-sql\default.xml.
2.See on how to load and execute the query.

Adding Property Files#

1. To add new property files to <trunk>\portal-impl\src
2. Add new property file only if you need to. Use for most requirements.

Adding Code in Plugins Directory #

1. You can check-out the LR-Plugins from here
2. If you are adding a portlet keep it under portlets directory.
3. If you are adding a service keep it under webs directory.

  • Add themes to the themes directory. For info on how to create themes see here

4. follow the conventions in naming the directories.
If your directory is under webs it should be <your-file-name>-web and in themes it should be -theme for every directory.
5. Source files will be under WEB_INF .Just refer to any other plugin structure and follow the same rules.
6. If one plugin (web or portlet) wants to talk to another plugin (web or portlet), then they must talk through the ClassLoader Proxy. See how workflowPortlet talks to saw-web. Dont use the Messaging Bus in this case, use only ClassLoaderProxy.
7. If some component from the core, wants to talk to a plugin (web or portlet), then they should talk through the MessagingBus.
8. Other than the above mentioned use case (pt:7), use the Messaging bus only when you want to send an asynchronous message.
9. The MessagingBus is a light weight messaging bus that is like the observer. It is not a JMS implementation.
10. If there are any jar files which are already present in portal\WEB-INF\lib and you also want to use them in your plugin.
Don't package those jars again instead just add the reference in docroot\WEB-INF\
Here is an extract from the properties file where some jars were referenced.


Adding Startup Actions #

If your fix / feature requires you to add/modify a startup action,

1. Any hooks for your code(portlet,web,theme) which are needed to be done at the startup can be added to StartupAction.Java.
2 This is a struts action similar to and

Coding Guidelines and Source Formatting Guidelines #

1. The coding guidelines can be found [here|]. This page has links to the coding, UI and Subversion guidelines.
2. Run "ant format-source" in <trunk>\portal-impl directory. It will do a format check and show you the violations
3. It is highly imperative that we follow the guidelines, other wise the check-ins would be reverted.
4. If you are changing an existing liferay file. "Don't" run ant format-source as it will format the whole file .
5. Don't leave any empty life at the end of any xml or properties files.
6. Always have a empty line before the ending brace of the class.
7. Never leave more than one empty line in any code, whether it is a java file or jsp scriptlet.
8. Always arrange methods and imports alphabetically with an exception for getters and setters.

Coding Nuances to remember#

  1. When to add empty lines?
    1. Right after the class definition statement
    2. Right after an if statement which has spanned 2 lines. This is inside the if block. Same holds good for other conditional blocks.
    3. At the end of every code block, like, after an if-else, switch, try-catch etc.
    4. After every line of code unless they are related. See below for examples. In the first code block, you need to have an empty line between the statements. In the second code block, you don't need to have empty lines between related statements.

First code block:

             String testing = something.getString();


Second code block:

             List<String> names = nameStore.getNames();



Selenium Tests#

If the Selenium tests are available, then run those tests before committing the code.
For instructions on how to run Selenium Tests see here

Running JUNIT Tests#

Before check-in, its a good practice to run the JUNIT Tests to ensure that you have not broken any piece of code.
For instructions on how to run JUNITS, see here

i18n Things to remember#

See this blog on how to internationlize.

Checking In the Artifacts#

1. Use your userId/password for checking-in code.
2. The svn commit comment, should start with LEP-xxxx Fix for...

  • __Note:__ There should not be any space between LEP and xxxx. The extra space means that the SVN commits won't be picked up by JIRA.

3. Make only an atomic check-in for a LEP.
4. After check-in, change the status of the LEP to Commit.
5. You would receive mails when anyone raises\modifies a LEP.
6 In case you have a big enough feature that has lots of checkins to do, then there is an option of creating a shelf and then making commits there. You could at a later point of time, merge it with the trunk. For information on how to create a shelve in Subversion, see here

Working with Glassfish #

To debug, open the <glassfish>\domains\domain1\config\domain.xml, search for "debug-enabled", and set this property to true.

Working with Tomcat#

If you guys are working on tomcat 6. Especially for guys who started with glassfish tomcat is a little bit different please see the FAQ's for more details.

If you get out of heap memory exception as soon as you deploy liferay ,
1. create a file in the "bin" directory and name it setENV.bat
2. Here are the contents of the file
set JAVA_OPTS=%JAVA_OPTS% -Xms128m -Xmx1024m -XX:MaxPermSize=128m -Dfile.encoding=UTF8 -Duser.timezone=GMT"%CATALINA_HOME%/conf/jaas.config"

To attach a debugger,
Make the following changes to these two files in bin directory.
in startup.bat
call "%EXECUTABLE%" jpda start %CMD_LINE_ARGS%
in catalina.bat
if not "%JPDA_TRANSPORT%" == "" goto gotJpdaTransport set JPDA_TRANSPORT=dt_socket :gotJpdaTransport if not "%JPDA_ADDRESS%" == "" goto gotJpdaAddress set JPDA_ADDRESS=9009
To undeploy the LR webapp,
1.Just delete the directory you want to undeploy from webapps directory.


See here

0 Attachments
Average (0 Votes)
The average rating is 0.0 stars out of 5.