The Long and Winding Road – Creating a Model Listener in Liferay 6

I had Liferay, I had Web Content, I had Tags and I had a problem.
Tags were supposed to be automatically added and removed when creating or updating a Web Content article.

A quick browse through the source code did not give gave me a direct solution – therefore – as so often – Google came to the rescue.

The search for “web content”, “liferay” and “listener” did not bring me very far either until I got a hint: Web Content articles have not been called Web Content forever, they used to be Journal Articles instead.

Finally success was granted – on Liferay’s wiki page there is a nice article about hooks, which was exactly what i needed. Or so i thought. After some unsuccessful attempts to create a basic hook following the description in the article, I finally dug a little deeper – meaning I undertook the effort to look at the hook.dtd for Liferay 6.
There it showed – all the pretty and understandable XML used in this article was not valid anymore – since version 5.2 of liferay things work a bit different.

So the search went on, and finally, combining the bits and pieces about module hooks I found all over the net, I had a base structure for building hooks in Liferay.

The solution:

First of all a hook is a portlet or better said, a web application, just like everything else you plug into Liferay. So what you want in the end is a WAR file with the following structure:

  /WEB-INF/web.xml – there is no WAR without a web.xml
  /WEB-INF/liferay-plugin-package.properties – after all it IS a liferay plugin
  /WEB-INF/liferay-hook.xml – the magic file – explanation further down
  /WEB-INF/classes/ – all your source code, resources and the like
  /WEB-INF/classes/your-own-properties.properties – an explanation follows

1. The web.xml
Just there to stop Liferay from complaining – Put an empty webapp tag in it and you’ll be fine.

2. The liferay-plugin-package.properties
Describes your plugin, i.e. liferay version, author, etc. You can even configure dependencies to Liferay libraries here instead of putting them manually in your WEB-INF/lib. A bit more information about that you can find here.

3. The liferay-hook.xml
This is where Liferay connects to our application. Since version 5.2 it is not filled with all the sexy XML anymore but instead, when implementing a module hook, you tell Liferay which properties file you use to define your own listener classes.

  <hook>
    <portal-properties>your-own-properties.properties</portal-properties>
  </hook>

4. The properties
Now you need to create that file, obviously. In order for Liferay to find it later on it should be placed in the WEB-INF/classes folder.
Looking into the file it gets a bit complicated. This is how Liferay thinks:

You want to create a listener to a model.
Therefore the name of the property you need to point to your listener implementation needs to start with value.object.listener.

On that part of the name you append the full class name of the model you want to listen to, so in our case this would be com.liferay.portlet.journal.model.JournalArticle.

What do you get?

  value.object.listener.com.liferay.portlet.journal.model.JournalArticle =
  com.jayway.liferay.hook.OurBeautifulListener

5. The class
Implement the class you just pointed at and be ready to go. This class needs to implement the interface ModelListener or extend the class BaseModelListener.

You can now deploy the hook in your Liferay installation as you do with any other portlet.
You can download the code of a maven project for a base model hook here, feel free to install and test it yourself.

This Post Has 9 Comments

  1. Thank you, was exactly the article and example i needed, i.e. how to use Maven to create Liferay hook :-).
    By the way you can put also the util-bridges, util-taglib and util-java into provided scope in pom.xml.

  2. Thank you for this informative article. I’m just starting out with Lidferay 6 but will be picking up development later.

  3. A good solution but if I want to pass a value from a jsp to my listener Do you know if this is posible?

  4. Great job! Works!

  5. Hi Karin, thank you for your clear article ! The only very good that I found about Liferay’s hook!!

    After I followed your article, I got an error….

    In my portal.properties I have “value.object.listener.o2.base.model.OMUserDitta = o2.base.portlet.NewUserDitta”

    Deploying my hook plugin I get the error:

    21:13:38,337 ERROR [HotDeployUtil:112] com.liferay.portal.kernel.deploy.hot.HotDeployException: Error registering hook for o2-base-portlet
    ……..
    …..

    Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named ‘o2.base.service.persistence.OMUserDittaPersistence’ is defined

    In fact my service Jar is ok and I use it from all my portlet plugins…

    Please, could you help me ?

    Thank you in advance!

  6. Thanks so much for this article…100x better than anything else available. Why is the documentation so bad for Liferay?

  7. Muchas gracias funciona super bien al fin una publicacion super buena.

  8. Excellent information,
    using steps follows,I have deploy the hook in liferay installation,
    Thanks for sharing.

  9. I am also getting same error as posted by Ivano Carrara like com.liferay.portal.kernel.bean.BeanLocatorException: org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named ‘com.infosys.bizp.procureedge.service.persistence.SupplierOffboardingPersistence’ is defined.

    my portal.properties file contains
    value.object.listener.com.infosys.bizp.procureedge.model.SupplierOffboarding = com.infosys.bizp.procureedge.service.MyModelListner

    Can you help me for resolve this issue.

Leave a Reply

Close Menu