Liferay Portal 6.2 Extension Plugins

Overview

Liferay Ext Plugins are often considered a last resort in the Liferay Plugin world due to the complexity and the lack of hot deploy as well as the inability to remove them once they are deployed.  These difficulties come from the fact that they are as close as you can get to customizing the core Liferay code without actually doing it.  The difference being it keep's your customizations separate from the Liferay code which helps at upgrade time or when the customization can be removed which is often the case when modifying the upgrade process.

I would like to cover two scenarios where Ext plugins were very useful for me and provide examples that can be of use to other people.  The first is customizing the Liferay upgrade process and the other is customizing the LDAP import process.

Customizing the Liferay Upgrade Process

This section covers how to customize the Liferay Upgrade Process.  I ran into a problem during my upgrade process with the following error showing up 1000's of times.  Its trying to add new Social Activity for each of my Wiki Pages.  However it says that more than one Wiki page was updated at exactly the same time/day/second which according to the SocialActivity table (and reality) is not possible.  

UpgradeSocial:79] Unable to add activity 3072565     [java] com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: 
Duplicate entry '542302-16697-1276032958000-10129-561166-2-0' for key 'IX_8F32DEC9'

So how do we fix it?  By customizing the upgrade process!

  1. Create a new Liferay Extension plugin and copy com.custom.portal.upgrade.UpgradeProcess_6_2_0 and com.liferay.portal.upgrade.v6_2_0.UpgradeSocial to ext-impl in the new plugin.  Rename both classes so they start with Custom.
  2. Modify CustomUpgradeProcess_6_2_0 to include your new CustomUpgradeSocial.  Change upgrade(UpgradeSocial.class); to upgrade(CustomUpgradeSocial.class);
  3. Modify CustomUpgradeSocial to check for the existence of duplicate time stamps to avoid the problem from above.
  4. Modify the portal-ext.properties file to include the custom upgrade process as opposed to the default one:
    upgrade.processes.master=\
        com.liferay.portal.upgrade.UpgradeProcess_6_0_0\,\
        com.liferay.portal.upgrade.UpgradeProcess_6_0_1\,\
        com.liferay.portal.upgrade.UpgradeProcess_6_0_2\,\
        com.liferay.portal.upgrade.UpgradeProcess_6_0_3\,\
        com.liferay.portal.upgrade.UpgradeProcess_6_0_5\,\
        com.liferay.portal.upgrade.UpgradeProcess_6_0_6\,\
        com.liferay.portal.upgrade.UpgradeProcess_6_1_0\,\
        com.liferay.portal.upgrade.UpgradeProcess_6_1_1\,\
        com.custom.portal.upgrade.CustomUpgradeProcess_6_2_0

During the upgrade process the log should display the custom upgrade process being ran: 

Upgrading com.custom.portal.upgrade.v6_2_0.CustomUpgradeSocial

The source for this project can be found here.

There is also example for customizing the verify process with a fix for LPS-42839 included.  

Make sure to add the following to the portal-ext.properties file:

verify.processes=com.custom.portal.verify.CustomVerifyProcessSuite

If all goes well the upgrade process should show:

Verifying com.custom.portal.verify.CustomVerifyDocumentLibrary

Customizing the LDAP Import Process

I wanted to customize the LDAP import process to import the Address and Phone number from LDAP.  I know that you can import them as custom attributes today but I wanted them to actually show up in the Phone and Address section in the user profile.  That way I could populate the Contacts Center in Social Office with data that was already in LDAP.

A while back Michael Han wrote a nice article explaining that the LDAP export/import process could be overridden using Spring.  I went ahead and implemented a custom LDAP import process using the ext-spring.xml file found in an extension plugin and was able to customize the LDAP import process.  

The source for the project can be found here

Make sure to add the following to the portal-ext.properties file to enable import for the custom attributes:

ldap.contact.mappings.0=phone=telephoneNumber\ncity=city\nzip=postalCode\nstreet1=street

 

Blogs
Jamie, echoing Wes's comment - thank you for sharing our project. It helped us to see a working example, as well. -daniel