Liferay Hook vs OSGi Decision Tree
Answer a few questions to find the right Liferay 7.x/DXP OSGi extension point for any old 6.x hook, with a copy-ready code stub.
Step 1
What do you want to customize in Liferay?
Pick the closest match. In Liferay 7.x / DXP almost every old "hook" maps to a specific OSGi extension point.
From 6.x Hooks to 7.x OSGi
The single biggest conceptual shift when upgrading to Liferay 7.x / DXP is that the old catch-all hook plugin is gone. Instead, each kind of customization has its own OSGi extension point — a service interface you implement and register with @Component. The decision tree above asks what you want to do and points you at the exact one; the table below is the full mapping for reference.
Hook → OSGi Mapping Reference
| Goal | Liferay 6.x hook | Liferay 7.x / DXP OSGi |
|---|---|---|
| Override a JSP with an OSGi Fragment | JSP hook — <custom-jsp-dir> in liferay-hook.xml | OSGi Fragment bundle (Fragment-Host) |
| Inject markup with a DynamicInclude | JSP hook with <liferay-util:include> tweaks | DynamicInclude component |
| Use a typed OSGi Configuration | portal.properties / portlet.properties hook | Configuration interface with @Meta.OCD |
| Provide a language resource bundle | Language hook — <language-properties> in liferay-hook.xml | liferay.resource.bundle capability (Language.properties module) |
| Listen to startup / instance lifecycle | application.startup.events / servlet events in a properties hook | PortalInstanceLifecycleListener (or @Activate for module startup) |
| Implement a ModelListener | value.object.listener.* in a properties hook | ModelListener<T> component |
| Wrap a service with a ServiceWrapper | Service wrapper hook — <service> in liferay-hook.xml | ServiceWrapper<T> component |
| Register an MVCActionCommand | Struts action hook — <struts-action> in liferay-hook.xml | MVCActionCommand / MVCRenderCommand / MVCResourceCommand |
| Add an IndexerPostProcessor | Indexer post processor hook | IndexerPostProcessor component |
Frequently Asked Questions
- What replaced hooks in Liferay 7?
- There is no single replacement — hooks were split into many targeted OSGi extension points. A JSP hook becomes an OSGi fragment or a DynamicInclude; a properties hook becomes a typed OSGi Configuration; a service wrapper hook becomes a ServiceWrapper component; a model listener becomes a ModelListener component; a struts-action hook becomes an MVCActionCommand, and so on. This tool maps each goal to its specific replacement.
- Are hooks completely gone?
- The old WAR-style hook plugins from 6.x are not the way you build for 7.x / DXP. Everything is now an OSGi module that registers components. Some legacy hook WARs can still be deployed via the WAB (Web Application Bundle) compatibility layer, but new customizations should use the OSGi extension points.
- Why is overriding a JSP discouraged?
- JSP overrides via fragment bundles are tightly coupled to the exact markup and host bundle version of the module you override, so they break easily on upgrade. When possible prefer a DynamicInclude (to inject markup at a defined point) or a proper extension point, which are far more upgrade-safe.
- How do I override an existing component instead of just adding one?
- Register your component with a higher service.ranking than the default. Liferay resolves the highest-ranked service, so a ranking like service.ranking:Integer=100 makes your MVCActionCommand, ServiceWrapper, or other component win over the built-in one.
- Does this cover every customization?
- It covers the most common ones that used to be hooks. Liferay exposes hundreds of OSGi extension points; if your need is not listed, the same principle applies — find the *-er or *Listener / *Provider interface for that subsystem and register a @Component for it.