Deploying plugins to Liferay

Alot of people seem to have problems deploying custom plugins to liferay. I admit that deployment can be a little tricky.

First off, Liferay has a naming convention which is more than just a naming convention and is actually designed to impose behavior. I think that in the future this should be changed to be based strictly on metadata contained in descriptors.

Anyway, that doesn't help you right now. So, plugins come in 5 types:

  • hooks
  • layout templates
  • portlets
  • themes
  • webs

So, when creating plugins projects the naming of your project dir should be:

project-name-{type-sufix}

where {type-sufix} is one of

  • hook
  • layouttpl
  • portlet
  • theme
  • web

This is done automatically when using the ant tasks or create scripts in the SDK. But if you created your project from scratch but still using the liferay build scripts, then this is where you fall into the mis-naming trap.

If you don't follow this convention one potential side effect is that you end up with a deployed project with a context like:

webapps/project-name-5.1.3.7

instead of just

webapps/project-name

This is because Liferay doesn't recognize the "type" of plugin and assumes it's a plain old webapp and doesn't change the context path.

Now, sometimes your code is already written OR you are including something inside the plugin that WANTs to use a specific context path. How do you deal with that? Liferay jas a little known feature to handle this. Simply add the following in the liferay-plugin-package.properties file.

recommended-deployment-context={desired-context-name}

This value will be used as the context path of the deployed plugin.

Enjoy!

Blogs
If you do not use the plugin sdk and just develop the plugin as a web app which ends with one of the plugin type names e.g. hook liferay will not be able to deploy the plugin.

If the war file ends with a different name it just deployes as expected.
This might be the case if you don't use the build files that are provided by the SDK.

I should have clarified "if you created your project from scratch" with "but still using the liferay build scripts". I this case, you will produce a WAR which might be like project-name-5.1.3.7.war and so it'll be deployed as /project-name-5.1.3.7 which is often not expected.
Recently, using my own patched version of 5.1.1 to fix hook plugins, I built a single 'theme' based plugin, that incorporated the functionality provided by a hook, layout, portlet, and theme. While my plugin worked fine, how does this naming convention apply to what I'd consider a mixed mode plugin?
This is a special case. Any plugin should be able to contain components of other plugin types. This is why I think we should ultimately drop the naming convention and go with pure descriptor configuration. The naming I find is just a source of error and confusion.
Thanks for all these hints. I didnot know these conventions. So i had a problem deploying a plugin package that doesn't match this conventions. They aren't documented outside of this blod, are they?

I found an other way to deploy a plugin package with a custom name (Liferay 5.2.2): the liferay-plugin-package.xml. In this file you have to define the module id like <groupid>/<artifactid>/<plugin version>/<type></module-id>. The artifactid is used for deployment context. I know that this is a workaround. So we use the properties file to configure the required libraries and we use the xml file to configure deployment context. Actually you can configure the recommended-deployment-context in the xml, too (see liferay-plugin-package_5_2_0.dtd).

Perhaps you can explain the differences between these two files needed for compilation and deployment?
Dude [Shakeeb] you are absolutely without a clue that you felt this was the proper forum to SPAM-vertise here.
Thanks Mickey (deleted the previous commentisment),

I was super busy when this comment came in and didn't check it. Thanks for commenting otherwise it might have stayed up indefinitely.
Hi Ray,

Thank you for this interesting blog.
Do you know if it is possible to specify a context path for plugins using the recommended-deployment-context that will use a name such as "/portal_root_context/plugin1". I did a try using tomcat but then plugins are not working properly.

Our customer have a requirement to use a unified context root for their portal where all links (portal and plugins, theme )have to start with the same /portal_root_context.

I Investigated also the <virtual-path> element but does not work either.

I wonder if this is possible to achieve with Liferay ?
Any input on this ?

Thanks


Our
Bonjour Pascale,

I tested with the following property:

recommended-deployment-context=portal/service-builder-portlet

(note that I omitted the starting slash) and this worked fine with one major issue; Tomcat did not itself deploy the application.

Liferay's deployer work perfectly, processed the plugin and exploded it to the correct path. The problem seems to be that the app server must support the subcontexts. Tomcat is supposed to have support for this, but it requires that you manually create a context file something like:

conf/Catalina/[hostname]/portal#service-builder-portlet.xml
(where the # will be replaced with path separator)

I tried this quickly and still tomcat would not initialize the webapp. I stopped there as I didn't not have time to do more.

This type of deployment might work for other app servers (although they may have quirks to get it working as well).

The bottom line is that the app servers must support it. If they support it, then it seems that at least from first glance Liferay has no problem doing it as well.
Thank you for your response. I obtained the same problem as you.

Tomcat seems to support sub context, it works for regular web app. It seems to use "#" to separate context level. As long as you name your web app level1#level2, your web app can be accessed using url /level1/level2

For liferay, I tried the following :

recommended-deployment-context=portal#service-builder-portlet

The plugins deployment is then done properly. All seems ok. However, the plugins does not work anymore and even broke the database (we are not able to remove the portlet anymore, instead liferay renders a blank page).

Do you think this is a deployment compatibility problem between tomcat using "#" caracter for multi level context and Liferay ?

Thanks
FYI: I just confirmed that there is a bug in tomcat 6.0.29 which causes the deployment of web apps using their own context file naming convention to fail.

i.e. when a war is deployed to a subcontext, for example:

/portal/service-builder-portlet

and having a context file:

conf/Catalina/[host]/portal#service-builder-portlet.xml (this file contains only <Context />)

The deployment fails. I also tried many variations of docBase and path with no success. While debugging the code, I replace the runtime value returned from:

org.apache.catalina.core.StandardContext.getBasePath() from an incorrect value (which still includes the #) with a correct one, and the deployment worked perfectly. The plugin was completely usable.
Strange that it works for a normal app. We're not doing anything abnormal with our wars. Could you try to identify what is different between our deployments and a regular war (I mean with respect to tomcat)?
Actually, the deployment is successfull with Liferay and tomcat (version6.0.18) as long as the recommended-deployment-context include "#".

The problem then is that (I guess) , Liferay is using the context path as portlet reference internally and . The "#" seems to mess up everything.

Another issue for us : do you know if that is possible to modify the plugin context path but keep the internal plugin reference as before. The idea here is to be able to modify the plugin context path without having to reconfigure each portlet instance on the portal ( for a portal running on production already with possible portal user customization).