Places to hook into Liferay from OSGi

We've been doing a lot of work to improve modularity of Liferay the past while. Liferay 6.2 has experimental support for OSGi but there's not much in the way of integration points. You can certainly do some cool things, but it's not integrated to the point of making the developers life much simpler than before.

However, in Liferay 7.0, one of the things we're working on is making it possible to reach many more integration points as OSGi services deployed into Liferay's module framework.

If you know anything about OSGi, if you've built Eclipse plugins, if you've worked on any OSGi framework at any time, you can use that knowledge to speed you down the path of writing Liferay plugins.

OSGi plugins are deployed into Liferay just like any other legacy plugins (by placing them into the deploy folder). The deployment framework will recognize if an artifact is an OSGi bundle and hand it over to the module framework.

What follows is a list of current integration points.

Each lists the Java interface as well as any service properties which need to be set in order for those to be properly connected with their target. If no properties are mentioned then none are required but the interface.

FQPN: a fully qualified portlet name (e.g. a plugin portlet "1_WAR_chatportlet", a core portlet "52")
 

Current Integration Points

  • com.liferay.portal.kernel.search.IndexerPostProcessor (in review)
    "indexer.class.name" : a indexer or entity class name
  • com.liferay.portal.service.ServiceWrapper (a.k.a. service hooks) (in review)
  • com.liferay.portal.kernel.poller.PollerProcessor
    "javax.portlet.name" : a FQPN
  • com.liferay.portal.security.auth.AuthFailure
    "key" : "auth.failure" | "auth.max.failures"
  • com.liferay.portal.security.auth.Authenticator
    "key" : "auth.pipeline.post" | "auth.pipeline.post"
  • com.liferay.portal.kernel.struts.StrutsAction
    "path" : a struts path (starting with "/portal")
  • com.liferay.portal.kernel.struts.StrutsPortletAction
    "path" : a portlet struts path
  • com.liferay.portlet.social.model.SocialActivityInterpreter
    "javax.portlet.name" : a FQPN
  • com.liferay.portlet.social.model.SocialRequestInterpreter
    "javax.portlet.name" : a FQPN
  • java.util.ResourceBundle
    "javax.portlet.name" : a FQPN
  • com.liferay.util.bridges.mvc.ActionCommand
    "action.command.name" : an MVCPortlet action command name
    "javax.portlet.name" : a FQPN
  • com.liferay.portlet.asset.model.AssetRendererFactory
    "javax.portlet.name" : a FQPN
  • com.liferay.portal.kernel.atom.AtomCollectionAdapter<?>
    "javax.portlet.name" : a FQPN
  • com.liferay.portal.kernel.portlet.ConfigurationAction
    "javax.portlet.name" : a FQPN
  • com.liferay.portlet.ControlPanelEntry
    "javax.portlet.name" : a FQPN
  • com.liferay.portlet.expando.model.CustomAttributesDisplay
    "javax.portlet.name" : a FQPN
  • com.liferay.portlet.dynamicdatamapping.util.DDMDisplay
    "javax.portlet.name" : a FQPN
  • com.liferay.portal.kernel.portlet.FriendlyURLMapper
    "javax.portlet.name" : a FQPN
  • com.liferay.portal.kernel.search.Indexer
    "javax.portlet.name" : a FQPN
  • com.liferay.portal.kernel.search.OpenSearch
    "javax.portlet.name" : a FQPN
  • com.liferay.portal.security.permission.PermissionPropagator
    "javax.portlet.name" : a FQPN
  • com.liferay.portal.kernel.pop.MessageListener
    "javax.portlet.name" : a FQPN
  • com.liferay.portal.kernel.lar.PortletDataHandler
    "javax.portlet.name" : a FQPN
  • com.liferay.portal.kernel.portlet.PortletLayoutListener
    "javax.portlet.name" : a FQPN
  • javax.portlet.PreferencesValidator
    "javax.portlet.name" : a FQPN
  • com.liferay.portal.kernel.lar.StagedModelDataHandler
    "javax.portlet.name" : a FQPN
  • com.liferay.portal.kernel.template.TemplateHandler
    "javax.portlet.name" : a FQPN
  • com.liferay.portal.kernel.trash.TrashHandler
    "javax.portlet.name" : a FQPN
  • com.liferay.portal.kernel.servlet.URLEncoder
    "javax.portlet.name" : a FQPN
  • com.liferay.portal.kernel.notifications.UserNotificationHandler
    "javax.portlet.name" : a FQPN
  • com.liferay.portal.kernel.webdav.WebDAVStorage
    "javax.portlet.name" : a FQPN
  • com.liferay.portal.kernel.workflow.WorkflowHandler
    "javax.portlet.name" : a FQPN
  • com.liferay.portal.kernel.xmlrpc.Method
    "javax.portlet.name" : a FQPN
  • javax.portlet.filter.ActionFilter
    "javax.portlet.name" : a FQPN
  • javax.portlet.filter.EventFilter
    "javax.portlet.name" : a FQPN
  • javax.portlet.filter.RenderFilter
    "javax.portlet.name" : a FQPN
  • javax.portlet.filter.ResourceFilter
    "javax.portlet.name" : a FQPN
  • com.liferay.portal.kernel.events.LifecycleAction
    "key" : a key for a lifecycle event (e.g. "servlet.service.events.pre", "login.events.pre", etc.)


Finally, we're not done yet! 

There should be many more integration points before long and that should include every one available previously by other means, as well as many more not previously reachable.

One significant observation to be made is that it's now possible to collaborate with other plugins without modifying their code.

For instance, if you have a third party portlet, let's call it 1_WAR_coolportlet, and you wish to collaborate with it by giving it a custom URLEncoder, given it's FQPN, you could create an OSGi service which has the service property javax.portlet.name=1_WAR_coolportlet and that's it.

Compile the impl against the API, assemble it as an OSGi bundle (using whatever build technology suites you) and deploy it to the deploy folder.

As I said, there's still lots of work to be done. But more is on the way. 

Blogues
Hi Ray,

Good to Know the progress with respect to OSGI. Keep up the good work.

Ahamed Hasan
Author, Liferay Cookbook
when you mean registering the service you mean to say from my OSGi bundle i do context.registerService(IP,Impl,properties), where IP is the integration points mentioned above, Impl is my custom implementation of IP and properties will have the ones listed above for each IP.
Also does these integration points work on 6.2.CE.GA2? or i have to fork your OSGi liferay portal to do the experiment?