« 返回到 Development

Portal Hook Plugins

Alternative Languages: 日本語

Warning #

The DTD has been updated in Liferay 5.2.

Original Article #

Lately, Liferay has been following a trend toward externalizing extensibility features as much as possible. The traditional EXT model, while powerful, often proves too complex for many situations, or too intrusive to the product to retrain a high level of maintainability and a comfortable upgrade path because by it's very nature it inadvertently promotes bad programming practices which can easily introduce difficult migration issues.

There are still use cases for using the EXT extension model (some less component friendly app servers for example), but the plan is to minimize the need and outright eliminate it wherever possible.

That in mind, the external extensibility features of Liferay have been very un-trendily dubbed "plugins". Liferay supports 5 different types of plugins out-of-the-box. They are:

  • Portlets
  • Themes
  • Layout Templates
  • Webs
  • Hooks

Today I'd like to focus on the newest addition, "Hooks". Hooks have been Brian Chan's own personal pet project for the last several months. As the name implies they allow "hooking" into Liferay. Specifically they allow you to hook into the eventing system, model listeners, jsps and portal properties. We'll begin by creating a bare hook config file where we will define some hooks as we review the different types

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hook PUBLIC "-//Liferay//DTD Hook 5.1.0//EN" "http://www.liferay.com/dtd/liferay-hook_5_1_0.dtd">

<hook>
</hook>

Event Handlers #

Liferay has a few event handler connection points throughout its lifecycle, designed to allow SI's to conveniently hook-in custom logic. The available events are:

  • Application Startup Events (application.startup.events)
  • Login Events (login.events.pre, login.events.post)
  • Service Events (servlet.service.events.pre, servlet.service.events.post)

Generally speaking your event implementations should extend com.liferay.portal.kernel.events.Action.

For example, presuming we have a custom event handler which should fire when the portal is starting to process any request called me.auge.ray.ServicePreAction, this class placed in the plugin work dir of <sdk_root>/hooks/rays-hook/docroot/WEB-INF/src/me/auge/ray/ServicePreAction.java, I would place the following element in the config file:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hook PUBLIC "-//Liferay//DTD Hook 5.1.0//EN" "http://www.liferay.com/dtd/liferay-hook_5_1_0.dtd">

<hook>
	<event>
		<event-class>me.auge.ray.ServicePreAction</event-class>
		<event-type>servlet.service.events.pre</event-type>
	</event>
</hook>

A couple points to make about events are that an application.startup.events can only extend com.liferay.portal.kernel.events.SimpleAction as that one expects an array of companyIds for which it should be invoked. The second is that you can define as many implementations as you like for each event type. Simply repeat the event element for each one.

Language Bundles #

You can install new translations or override few words in existing translations. Point to where your properties files is located, the filename must follow this pattern: Language_$[localeId].properties, where $localeId is the id of the Locale (e.g. en_US, pt_BR, etc). You can add as many <language-properties> as you want:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hook PUBLIC "-//Liferay//DTD Hook 5.1.0//EN" "http://www.liferay.com/dtd/liferay-hook_5_1_0.dtd">

<hook>
	<language-properties>com/liferay/samplelocalized/resources/Language_en_US.properties</language-properties>
</hook>

Model Listeners #

Model listeners are similar in behavior to portal event handlers except that these handle events with respect to models built using ServiceBuilder. These listeners implement the com.liferay.portal.model.ModelListener interface.

If you wanted to listen for new Blog posts, you might have a class called me.auge.ray.NewBlogEntryListener which looked like this:

package me.auge.ray;
import com.liferay.portal.ModelListenerException;
import com.liferay.portal.model.BaseModel;
import com.liferay.portal.model.ModelListener;
import com.liferay.portlet.blogs.model.BlogsEntry;
public class NewBlogEntryListener implements ModelListener {
	public void onAfterCreate(BaseModel arg0) throws ModelListenerException {
		BlogsEntry entry = (BlogsEntry)arg0;
		System.out.println("Woohoo! We got an new one called: " + entry.getTitle());
	}
	public void onAfterRemove(BaseModel arg0) throws ModelListenerException {
	}
	public void onAfterUpdate(BaseModel arg0) throws ModelListenerException {
	}
	public void onBeforeCreate(BaseModel arg0) throws ModelListenerException {
	}
	public void onBeforeRemove(BaseModel arg0) throws ModelListenerException {
	}
	public void onBeforeUpdate(BaseModel arg0) throws ModelListenerException {
	}
}

You'd configure it like so:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hook PUBLIC "-//Liferay//DTD Hook 5.1.0//EN" "http://www.liferay.com/dtd/liferay-hook_5_1_0.dtd">

<hook>
	<event>
		<event-class>me.auge.ray.ServicePreAction</event-class>
		<event-type>servlet.service.events.pre</event-type>
	</event>
	<model-listener>
		<model-listener-class>me.auge.ray.NewBlogEntryListener</model-listener-class>
		<model-name>com.liferay.portlet.blogs.model.BlogsEntry</model-name>
	</model-listener>
</hook>

As with events, add as many as you like even per model.

JSPs #

One of the biggest aspects of implementing the portal is of course customization of the user experience. This largely involves modifying portal jsps. The problem is of course migration from version to version where you may end up with code squew, code management, version management, and many other issues. JSP hooks are designed to aleviate some of those issues by providing a way for SI's to easily modify jsps without having to alter the core. Simply specify a folder in the hook plugin from which to obtain jsp files and the portal will automatically use those in place of existing ones in the portal. This works for any jsps in the portal, portlets, servlets, and tags. All you need to do is make sure that you follow the same folder structure off your specified folder.

For example if you specify the folder /WEB-INF/src, the changing the view for the blogs portlet would require a file in /WEB-INF/src/html/portlet/blogs/view.jsp. Configuration would look like this:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hook PUBLIC "-//Liferay//DTD Hook 5.1.0//EN" "http://www.liferay.com/dtd/liferay-hook_5_1_0.dtd">

<hook>
	<event>
		<event-class>me.auge.ray.ServicePreAction</event-class>
		<event-type>servlet.service.events.pre</event-type>
	</event>
	<model-listener>
		<model-listener-class>me.auge.ray.NewBlogEntryListener</model-listener-class>
		<model-name>com.liferay.portlet.blogs.model.BlogsEntry</model-name>
	</model-listener>
	<custom-jsp-dir>/WEB-INF/jsps</custom-jsp-dir>
</hook>

Portal Properties #

We can alter the portal's configuration properties by specifying an override file. The properties in this file will immediately take effect when deployed thus allowing runtime re-configuration of the portal.

If you had a file /WEB-INF/src/portal.properties, the configuration would look like:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hook PUBLIC "-//Liferay//DTD Hook 5.1.0//EN" "http://www.liferay.com/dtd/liferay-hook_5_1_0.dtd">

<hook>
	<event>
		<event-class>me.auge.ray.ServicePreAction</event-class>
		<event-type>servlet.service.events.pre</event-type>
	</event>
	<model-listener>
		<model-listener-class>me.auge.ray.NewBlogEntryListener</model-listener-class>
		<model-name>com.liferay.portlet.blogs.model.BlogsEntry</model-name>
	</model-listener>
	<portal-properties>portal.properties</portal-properties>
	<custom-jsp-dir>/WEB-INF/jsps</custom-jsp-dir>
</hook>

Overriding Services #

Starting with Liferay 6.0 and 5.2 EE SP4, you can override services using hooks as opposed to doing so in the EXT. An example would be:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hook PUBLIC "-//Liferay//DTD Hook 5.1.0//EN" "http://www.liferay.com/dtd/liferay-hook_5_1_0.dtd">

<hook>
	<event>
		<event-class>me.auge.ray.ServicePreAction</event-class>
		<event-type>servlet.service.events.pre</event-type>
	</event>
	<model-listener>
		<model-listener-class>me.auge.ray.NewBlogEntryListener</model-listener-class>
		<model-name>com.liferay.portlet.blogs.model.BlogsEntry</model-name>
	</model-listener>
	<portal-properties>portal.properties</portal-properties>
	<custom-jsp-dir>/WEB-INF/jsps</custom-jsp-dir>
        <service>
                <service-type>com.liferay.portal.service.RoleLocalService</service-type>
                <service-impl>me.michael.han.NewRoleLocalServiceImpl</service-impl>
        </service>
        <service>
                <service-type>com.liferay.portal.service.UserLocalService</service-type>
                <service-impl>me.michael.han.NewUserLocalServiceImpl</service-impl>
        </service>
</hook>

Finally, all of the above hooks will immediately revert their targetted functionality as soon as they are undeployed from the portal. Also, each type of hook can easily be disabled via portal.properties (Note that if properties hook is disabled, a hook cannot be used to re-enable it). Hooks can be built, packaged, and deployed, like other plugins, using the Liferay plugins SDK.

Application adapters #

Application Adapters are hooks that can be used just for certains Sites and can chosen from the UI when creating new sites. They were introduced in Liferay 6.1

0 附件
151144 查看
平均 (5 票)
满分为 5,平均得分为 4.2。
评论
讨论主题回复 作者 日期
There isn't any <language-properties> element ... Van Hoai Pham 2008年10月11日 上午8:56
should be liferay-hook_5_2_0.dtd Arcko Duan 2008年10月12日 下午7:34
Yes, in 5.2, there are only two elements: ... Jonas Yuan 2008年12月29日 下午5:43
So how does one put something like [code] ... Eugene Rachitskiy 2009年4月27日 下午4:16
Nevermind on my last comment, it appears one... Eugene Rachitskiy 2009年4月27日 下午4:39
Hi, I am trying to implement A... Faisal K 2009年5月24日 下午11:06
I tried something similar on the lines of the... Amarjeet Singh 2009年6月18日 上午5:31
Hi Amarjeet, were you able to solve your... Jessica Thrasher 2009年7月14日 上午11:20
isn't it portal-ext.properties if i am using... Suresh Nimmakayala 2009年8月27日 下午6:05
I'm using webspace. Dont have ext environment... Faris Abdulla 2010年1月20日 上午7:57
Faris, Forgive me if i lead you down the... Mathew Crocker 2010年1月26日 下午3:17
It is not clear to me, where I would need to... Thomas Kellerer 2008年10月22日 上午12:23
I guess your confusion is like mine,... Alex Wallace 2008年10月31日 下午12:55
So this only works with the ext-enviroment, right? Thomas Kellerer 2008年11月10日 上午3:38
It works in both Plugins SDK and Ext. The... Jonas Yuan 2008年12月29日 下午5:38
Please, what about Webs plugins? Thank you in... Ivano Carrara 2008年11月5日 上午2:33
I tried to create my own JSP hook. I downloaded... Thomas Kellerer 2009年7月14日 上午2:28
"Content is not allowed in prolog is an xml... whyBish valid 2009年7月29日 下午1:25
Thomas, How did you resolve this issue? I want... Markus Khouri 2009年9月11日 下午12:38
See my forum message for a solution:... Thomas Kellerer 2009年10月5日 上午6:24
I'm trying to implement a language hook, but as... Thomas Kellerer 2009年10月22日 上午6:11
Hi I hate to see that I am the only one who... Armaz Mellati 2009年11月5日 上午3:57
Answering my own question :) Found the answer... Armaz Mellati 2009年11月5日 上午4:22
I like the idea of using model listeners and... Stefaan Ternier 2010年3月25日 上午3:17
the document has an error. Change this line ... Rahul Bhattacharya 2010年12月19日 下午3:49
Ray, Can we add new properties to... Smilelws2010 lwz 2011年2月10日 上午11:55
Hello Stefaan, du you found solution for this... Mark Stein 2011年4月7日 上午3:59
I have created hook for service classes ... Archi Madhu 2011年6月21日 上午1:24
*I want that class to EXTEND... Archi Madhu 2011年6月21日 上午1:25
@Archi Madhu: Instead of extending... Stefan Brötz 2012年9月21日 上午2:05
For Model Listeners the hook configuration... Jim Somerville 2013年10月29日 上午6:18

There isn't any <language-properties> element in the DTD. There should be another version of DTD???
在 08-10-11 上午8:56 发帖。
should be liferay-hook_5_2_0.dtd
在 08-10-12 下午7:34 发帖以回复 Van Hoai
It is not clear to me, where I would need to place the hook config file?
Especially in an installation where the ext-environment is not used.
在 08-10-22 上午12:23 发帖。
I guess your confusion is like mine, originally... I looked at https://lportal.svn.sourceforge.net/svnroot/lportal/plugins/trunk/hooks/ to figure it out...

There is no create.sh in the hooks folder like other plugins.

Seems to me that:

1- you create a folder in hooks, with an arbitrary name
2- your hooks config goes in yourFolder/docroot/WEB-INF/liferay-hook.xml
3- your overrides go in /docroot/WEB-INF/src and need to be referenced by your hook config
4- you should have a yourFolder/docroot/WEB-INF/liferay-plugin-package.properties
5- you probably want to add a yourFolder/build.xml for ant
在 08-10-31 下午12:55 发帖以回复 Thomas Kellerer
Please, what about Webs plugins?

Thank you in advance!

Ivano Carrara
在 08-11-5 上午2:33 发帖。
So this only works with the ext-enviroment, right?
在 08-11-10 上午3:38 发帖以回复 Alex Wallace
It works in both Plugins SDK and Ext.

The development of hooks should be merged with that of portlets. That is, we should develop portlets in plugins SDK with hooking feature. Right?

Thanks

Jonas Yuan
在 08-12-29 下午5:38 发帖以回复 Thomas Kellerer
Yes, in 5.2, there are only two elements:

<portal-properties>portal.properties</portal-properties>
<custom-jsp-dir­>/META-INF/custom_jsps</custom-jsp-dir>

place all other values (including language properties) as properties in:

<portal-properties>portal.properties</portal-properties>
在 08-12-29 下午5:43 发帖以回复 Arcko Duan
So how does one put something like
1
2    <event>
3        <event-class>com.mycompany.liferay.ActionClass</event-class>
4        <event-type>application.startup.events</event-type>
5    </event>   

which is valid in the 5.1 dtd into portal.properties? That doesn't seem right..
在 09-4-27 下午4:16 发帖以回复 Jonas Yuan
Nevermind on my last comment, it appears one can specify
application.startup.events=com.mycompany.liferay.ActionClass
to emulate
1
2<event>
3        <event-class>com.mycompany.liferay.ActionClass</event-class>
4        <event-type>application.startup.events</event-type>
5</event>   

but now the question is how can I have multiple plugins that have callbacks for the same hook? For example, I assumed that previously I could have two separate hook plugins declaring two separate event-class values for the same hook and have both execute; was I wrong on that? Will something like:
1
2application.startup.events=${application.startup.events},com.mycompany.li­feray.ActionClass

work?
在 09-4-27 下午4:39 发帖以回复 Eugene Rachitskiy
Hi,

I am trying to implement A listener class for Journal Article, in ext when I am using this properies 'value.object.listener.com.liferay.portlet.journal.model.JournalArticle=com.life­ray.portlet.journal.model.JournalArticleListener' I am able to do it. Can you help me how can i achieve this using a hook, I am using 5.2.2 version of Liferay(model-listener tag is no more 5.2 hook dtd).

Thanks in Advance!
在 09-5-24 下午11:06 发帖以回复 Jonas Yuan
I tried something similar on the lines of the above and in portal.properties, added the following key-value pair:

value.object.listener.com.liferay.wol.model.WallEntry=org.inexistent.wolpor­tlet.listeners.WallEntryListener

Server startup clearly shows that the property file has been successfully read, but the listener still does not appear to fire up. Also, I noted that in the DTD at http://www.liferay.com/dtd/liferay-hook_5_2_0.dtd, the comments section say that:

"Not all portal properties can be overridden via a hook."

What were the steps that you had taken to create and deploy the listener correctly? I am trying to create a listener for WallEntry.

Thanks!
在 09-6-18 上午5:31 发帖以回复 Faisal K
I tried to create my own JSP hook. I downloaded the Plugins-SDK and made a copy of the custom-jsphook directory.

I then added the file WEB-INF/jsps/html/portlet/document_library/view.jsp and left the other files from the example unchanged (especially liferay-hook.xml)

But when I deploy the hook, I see an error message on the Tomcat console window:

 1
 211:00:59,635 ERROR [HotDeployUtil:111] com.liferay.portal.kernel.deploy.hot.HotDeployException: Error registering hook f
 3or my-jsphook-5.2.3.1
 4com.liferay.portal.kernel.deploy.hot.HotDeployException: Error registering hook for my-jsphook-5.2.3.1
 5        at com.liferay.portal.deploy.hot.BaseHotDeployListener.throwHotDeployException(Base­HotDeployListener.java:58)
 6        at com.liferay.portal.deploy.hot.HookHotDeployListener.invokeDeploy(HookHotDeployLi­stener.java:101)
 7        at com.liferay.portal.kernel.deploy.hot.HotDeployUtil._doFireDeployEvent(HotDeployU­til.java:108)
 8        at com.liferay.portal.kernel.deploy.hot.HotDeployUtil._fireDeployEvent(HotDeployUti­l.java:153)
 9        at com.liferay.portal.kernel.deploy.hot.HotDeployUtil.fireDeployEvent(HotDeployUtil­.java:43)
10        at com.liferay.portal.kernel.servlet.PortletContextListener.portalInit(PortletConte­xtListener.java:113)
11        at com.liferay.portal.kernel.util.PortalInitableUtil.init(PortalInitableUtil.java:4­8)
12        at com.liferay.portal.kernel.servlet.PortletContextListener.contextInitialized(Port­letContextListener.java:109)
13        at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:3843­)
14        at org.apache.catalina.core.StandardContext.start(StandardContext.java:4342)
15        at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:791)
1­6        at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:771)
17        at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:525)
18        at org.apache.catalina.startup.HostConfig.deployDirectory(HostConfig.java:926)
19        at org.apache.catalina.startup.HostConfig.deployDirectories(HostConfig.java:889)
20 ­       at org.apache.catalina.startup.HostConfig.deployApps(HostConfig.java:492)
21        at org.apache.catalina.startup.HostConfig.check(HostConfig.java:1217)
22        at org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java:293)
23        at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.ja­va:117)
24        at org.apache.catalina.core.ContainerBase.backgroundProcess(ContainerBase.java:1337­)
25        at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChild­ren(ContainerBase.java:1601)
26        at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChild­ren(ContainerBase.java:1610)
27        at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.run(Containe­rBase.java:1590)
28        at java.lang.Thread.run(Thread.java:619)
29Caused by: com.liferay.portal.kernel.xml.DocumentException: Error on line 2 of document  : Content is not allowed in pro
30log. Nested exception: Content is not allowed in prolog.
31        at com.liferay.portal.xml.SAXReaderImpl.read(SAXReaderImpl.java:377)
32        at com.liferay.portal.xml.SAXReaderImpl.read(SAXReaderImpl.java:388)

As the liferay-hook.xml is the only xml file involved I assume that is the problem, but when looking at the file I cannot see any error in there (and it is an unchanged copy of the file from the SDK)

Even though the hot deployer claims "ready to use" the hook is not working (I added an additional label to the jsp to see if it's working) and in the control panel the hook is not listed as well.

What am I missing?
在 09-7-14 上午2:28 发帖。
Hi Amarjeet, were you able to solve your problem? I'm having this same problem with a different portlet.
在 09-7-14 上午11:20 发帖以回复 Amarjeet Singh
"Content is not allowed in prolog is an xml exception. I think it occurs when you have some text in the <? ... ?> header.
在 09-7-29 下午1:25 发帖以回复 Thomas Kellerer
isn't it portal-ext.properties if i am using ext environment
在 09-8-27 下午6:05 发帖以回复 Jonas Yuan
Thomas, How did you resolve this issue? I want to do modify the same file to stop the teasing in the Document Library, as detailed here: http://www.liferay.com/web/guest/community/forums/-/message_boards/message/33701­22
在 09-9-11 下午12:38 发帖以回复 Thomas Kellerer
See my forum message for a solution:
http://www.liferay.com/web/guest/community/forums/-/message_boards/mess­age/3552876
在 09-10-5 上午6:24 发帖以回复 Markus Khouri
I'm trying to implement a language hook, but as soon as I deploy it (with just three keys) I cannot' switch the language in the portal anymore. When I change the user's language, the whole portal stays in the same language. Only web-content and the navigation changes to the new language (but all Liferay dialogs, stick with e.g. with english)
在 09-10-22 上午6:11 发帖。
Hi

I hate to see that I am the only one who seem to have problem with deploying.
Nobody mentions anything about how to deploy.
I presumed I must run "ant deploy", but it only gives me :
liferay_sdk/hooks/my-hooks/build.xml (No such file or directory)
Alex Wallace, mentions :
"you probably want to add a yourFolder/build.xml for ant " but, where or how to I get the proper build.xml ??!!!

Armaz
在 09-11-5 上午3:57 发帖。
Answering my own question emoticon

Found the answer on this link:
http://kamalkantrajput.blogspot.com/2009/05/using-hooks-in-liferay-for-cust­omizing.html
A nice step by step walk-through.
在 09-11-5 上午4:22 发帖以回复 Armaz Mellati
I'm using webspace. Dont have ext environment for developing.
I need to customize the login portlet by changing the struts action path..

Is it achievable through hooks plugin and how..

Can anyone plz guide me ..
在 10-1-20 上午7:57 发帖以回复 Jonas Yuan
Faris,

Forgive me if i lead you down the wrong path since i haven't tried this specifically with the struts-config.xml.

If you look at the structure of a hook, it looks something like :

<hook name>
|-docroot
|- WEB-INF
|- classes
|- various xml files

i believe you want to copy the struts-config.xml from the liferay-portal source to here, and add/modify your changes inside the file.

hope this helps.
在 10-1-26 下午3:17 发帖以回复 Faris Abdulla
I like the idea of using model listeners and have written a hook that performs actions on blogs, wikis and other models. Most of the information that you usually need to do more advance things seems not to be available from within such a model listener.

For instance I would like to use the permissions checker to check whether a guest can read the blog entry. Or, I would like to get the URL path the leads to the blog entry.

Any idea how to get to the ServiceContext, themeDisplay or request from within classes that implement ModelListener?
在 10-3-25 上午3:17 发帖。
the document has an error. Change this line
""For example if you specify the folder /WEB-INF/src, the changing the view for the blogs portlet would require a file in /WEB-INF/src/html/portlet/blogs/view.jsp. Configuration would look like this"

to

"For example if you specify the folder /WEB-INF/jsps, the changing the view for the blogs portlet would require a file in /WEB-INF/jsps/html/portlet/blogs/view.jsp. Configuration would look like this".

The configuration example you gave assumes the jsps kept in a folder called jsps and not src
在 10-12-19 下午3:49 发帖以回复 Stefaan Ternier
Ray,

Can we add new properties to portal.properties and put it under hook\docroot\web-inf\src\portal.properties.

And in the jsp do a PortletProps.get("Link1") where link1 is my key in the properties file.

Or can you help me with reading a property file inside a hook irrespective of it's path.

I dont want to hard code the path to my property file inside the jsp as it is gonna change very often. and so I can reuse it in others

Thanks,
Ann
在 11-2-10 上午11:55 发帖以回复 Rahul Bhattacharya
Hello Stefaan,

du you found solution for this issue: geting ServiceContext, ThemeDisplay from a listener?
在 11-4-7 上午3:59 发帖以回复 Stefaan Ternier
I have created hook for service classes

<service>
<service-type>com.liferay.portal.service.UserLocalService</service-type>
<service-impl>com.myproj.portal.service.NewUserLocalServiceImpl</service-impl>
</service>

and java class NewUserLocalServiceImpl .

I want that class to UserLocalServiceImpl , so that in LR upgrade we don't need to bother about other methods for API change.

But UserLocalServiceImpl can not be available in hook.

Is there a better approach for same?
在 11-6-21 上午1:24 发帖。
*I want that class to EXTEND UserLocalServiceImpl ,
在 11-6-21 上午1:25 发帖以回复 Archi Madhu
@Archi Madhu:
Instead of extending UserLocalServiceImpl, you should extend UserLocalServiceWrapper. As the name suggests, it is a wrapper class that delegates all UserLocalService methods to an injected implementation. By default Liferay injects UserLocalServiceImpl.
在 12-9-21 上午2:05 发帖以回复 Archi Madhu
For Model Listeners the hook configuration markup is out of date for Liferay 6.x. See one of these blogs for how to do it: http://www.emforge.net/web/akakunin/blogs/-/blogs/model-listener-in-liferay-6 or http://informatik-hub.blogspot.com/2012/05/liferay-working-with-model-listeners.­html
在 13-10-29 上午6:18 发帖。