Half a Day Fixing the Liferay Maven Plugin

>> Tuesday, April 5, 2011

I love Maven and I am pretty fond of Liferay and since I am in the business these days of developing Liferay-based solutions, I need to be able to rely on the Maven plugin for Liferay.

Actually, the Liferay-released Maven plugin works generally well and I will someday take the time to document a neat Maven trick to merge two Maven projects into a single Liferay plugin (for example, one project containing the Service Builder interfaces and classes and one containing the presentation stuff). However, what I want to share with you in this article is a bit different.

The Maven Liferay plugin can be used to invoke the ServiceBuilder (i.e. mvn liferay:build-service) and that's great except for one nasty issue that we were running into: every time we regenerate the services using the ServiceBuilder, the portlet-model-hints.xml file gets replaced with a fresh one. Now for those who are familiar with Liferay's ServiceBuilder, this is really annoying since portlet-model-hints is how you tell the ServiceBuilder to use something else than default values for things like SQL types. For example, generated entities have default varchar lengths of 75. If you need, say, a varchar(200) you simply add a hint in the said file and ServiceBuilder will take that into account when generating SQL scripts for example. To my experience, this works well when ServiceBuilder is invoked through the ANT scripts. Not being able to rely on this is a pain you know where and can introduce severe problems when deploying new versions of a plugin including loss of data.

I will spare you the details, but troubleshooting this bug/problem was not so easy. Turns out that the ServiceBuilder uses a ModelHints class which tries to load the load the portlet-model-hints.xml as a resource using the builder's class loading context. Now, when this happens in the context of the Maven Liferay plugin, the path to this file (i.e. the projects compileClasspath) is not in the builder's classpath so the "hints" file is never found much less loaded.

I modified the Liferay Maven plugin (i.e. the com.liferay.maven.plugins.ServiceBuilderMojo class) so that it adds the project's CompileClasspath to the Mojo's classloader and voila! Everything started to work as expected.

Note that I had to use some nasty Java tricks to achieve this since modifying a classloader's classpath is protected but Java provides a backdoor to invoke protected methods. If anybody know a better and more elegant solution to add a project compile classpath to the Mojo's classpath, please let us know.

Interested folks can download the modified Maven plugin (opnworks-LR-service-builder-mojo.zip). This file contains the source and binary code for the patched plugin. Simply unzip it and run a mvn install in the root folder and you can start using this modified Maven plugin in-lieu of the released one.

Have fun in the Liferay lane!

Laurent

6 commentaires:

Laurent Gauthier 19 April, 2011 22:37  

The modified Mojo is also available from our public repository @ http://aws.opnworks.com/nexus/content/repositories/public-releases.

The version number is "6.0.5.OW.01".

Tibor Kiss 16 July, 2012 05:47  

I have tried the 6.1.0.ow2 version with Liferay 6.1.0 CE GA1 and does not seems to work for me. Could you point us the source code for this version?

Laurent Gauthier 16 July, 2012 21:03  

Tibor,

The source for the modified Java classes are in the .zip file referenced in the original article.

Anonymous,  16 December, 2013 05:01  

The zip file is no longer available (The requested resource was not found.) and the public repository (http://aws.opnworks.com) returns a 404 too.

We are currently unable to upgrade to the new plugin version (that apparently fixes the issue) so would like to modify our existing plugin with the fix you have developed. Is it possible to make the zip file available again?

Thanks,

Peter.

Laurent Gauthier 17 December, 2013 08:16  

Sorry about missing zip file. I will have to fix that later when I find some time. The public repository is now available @ http://server01.opnworks.com/nexus/content/repositories/public-releases/

Fabian 04 April, 2014 06:06  

Using Liferay 6.1.20 EE GA2 and the artifactory-maven-plugin 0.0.4, I get a NPE in ServiceBuilder._getJavaClass(ServiceBuilder.java:4390).

Post a Comment

  © Blogger template Webnolia by Ourblogtemplates.com 2009

Back to TOP