Forums

Home » Liferay Portal » English » 3. Development

Combination View Flat View Tree View
Threads [ Previous | Next ]
Dave Kliczbor
Hooked class does not find superclass from portal-impl.jar
November 22, 2011 5:45 AM
Answer

Dave Kliczbor

Rank: Junior Member

Posts: 55

Join Date: July 12, 2011

Recent Posts

Hello out there,

I'm trying to customize the behaviour of the Request Portlet (for Liferay 6.1.0 beta 3). Replacing the JSP files was easy via a hook plugin, but one issue was left over: Whenever there are no requests, the portlet's decoration disappears. Finally, I found the culprit: the com.liferay.portlet.requests.action.ViewAction class. Okay, to override this class, I assumed I could follow this blog post.

I added this code to liferay-hook.xml, assuming I should use the struts action path for portlet 121 from ROOT/WEB-INF/liferay-portlet.xml:
1    <struts-action>
2        <struts-action-path>requests</struts-action-path>
3        <struts-action-impl>com.liferay.portlet.requests.action.ViewAction</struts-action-impl>
4    </struts-action>

Then I added a new class in Eclipse, using the same package path as the original ViewAction class (com.liferay.portlet.requests.action.ViewAction extends com.liferay.portal.struts.PortletAction) and commented out a few lines so that the portlet's decoration won't be switched off.

Compiling and exporting to a WAR file works well, only on deploy I get the following error:
 113:02:30,115 ERROR [HotDeployUtil:114] com.liferay.portal.kernel.deploy.hot.HotDeployException: Error registering hook for CustomRequest-hook-0.2
 2com.liferay.portal.kernel.deploy.hot.HotDeployException: Error registering hook for CustomRequest-hook-0.2
 3        at com.liferay.portal.kernel.deploy.hot.BaseHotDeployListener.throwHotDeployException(BaseHotDeployListener.java:46)
 4        at com.liferay.portal.deploy.hot.HookHotDeployListener.invokeDeploy(HookHotDeployListener.java:288)
 5        at com.liferay.portal.kernel.deploy.hot.HotDeployUtil._doFireDeployEvent(HotDeployUtil.java:111)
 6        at com.liferay.portal.kernel.deploy.hot.HotDeployUtil._fireDeployEvent(HotDeployUtil.java:188)
 7        at com.liferay.portal.kernel.deploy.hot.HotDeployUtil.fireDeployEvent(HotDeployUtil.java:40)
 8        at com.liferay.portal.kernel.servlet.PortletContextListener.doPortalInit(PortletContextListener.java:101)
 9        at com.liferay.portal.kernel.util.BasePortalLifecycle.portalInit(BasePortalLifecycle.java:42)
10        at com.liferay.portal.kernel.util.PortalLifecycleUtil.register(PortalLifecycleUtil.java:61)
11        at com.liferay.portal.kernel.util.PortalLifecycleUtil.register(PortalLifecycleUtil.java:53)
12        at com.liferay.portal.kernel.util.BasePortalLifecycle.registerPortalLifecycle(BasePortalLifecycle.java:50)
13        at com.liferay.portal.kernel.servlet.PortletContextListener.contextInitialized(PortletContextListener.java:55)
14        at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4723)
15        at org.apache.catalina.core.StandardContext$1.call(StandardContext.java:5226)
16        at org.apache.catalina.core.StandardContext$1.call(StandardContext.java:5221)
17        at java.util.concurrent.FutureTask$Sync.innerRun(Unknown Source)
18        at java.util.concurrent.FutureTask.run(Unknown Source)
19        at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source)
20        at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
21        at java.lang.Thread.run(Unknown Source)
22Caused by: java.lang.NoClassDefFoundError: com/liferay/portal/struts/PortletAction
23        at java.lang.ClassLoader.defineClass1(Native Method)
24        at java.lang.ClassLoader.defineClassCond(Unknown Source)
25        at java.lang.ClassLoader.defineClass(Unknown Source)
26        at java.security.SecureClassLoader.defineClass(Unknown Source)
27        at org.apache.catalina.loader.WebappClassLoader.findClassInternal(WebappClassLoader.java:2820)
28        at org.apache.catalina.loader.WebappClassLoader.findClass(WebappClassLoader.java:1150)
29        at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1645)
30        at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1523)
31        at com.liferay.portal.kernel.util.InstanceFactory.newInstance(InstanceFactory.java:52)
32        at com.liferay.portal.kernel.util.InstanceFactory.newInstance(InstanceFactory.java:27)
33        at com.liferay.portal.deploy.hot.HookHotDeployListener.initStrutsAction(HookHotDeployListener.java:1852)
34        at com.liferay.portal.deploy.hot.HookHotDeployListener.doInvokeDeploy(HookHotDeployListener.java:881)
35        at com.liferay.portal.deploy.hot.HookHotDeployListener.invokeDeploy(HookHotDeployListener.java:285)
36        ... 17 more
37Caused by: java.lang.ClassNotFoundException: com.liferay.portal.struts.PortletAction
38        at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1678)
39        at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1523)
40        ... 30 more

What puzzles me is the NoClassDefFoundError... Is it normal that this one reports the package path with slashes instead of dots? Additionally vexing: the class stated as "not found" is also the superclass of the original class.

One way or the other: How can I override the ViewAction class using a hook plugin, as suggested in the mentioned blog post?
Nagendra Kumar Busam
RE: Hooked class does not find superclass from portal-impl.jar
November 22, 2011 6:13 AM
Answer

Nagendra Kumar Busam

Rank: Liferay Master

Posts: 637

Join Date: July 7, 2009

Recent Posts

Hi Dave,

Quick things i noticed by seeing log are

> PortletAction - is class from portal-impl.jar which you cannot access from hooks directly


Instead of ViewAction extending from PortletAction - try to extend from BaseStrutsPortletAction (this is from portal-service.jar - which you have access > global class path)

From the blog link you have given

There are two interfaces com.liferay.portal.kernel.struts.StrutsAction and com.liferay.portal.kernel.struts.StrutsPortletAction. The StrutsAction is used for regular struts actions like /c/portal/update_password and StrutsPortletAction is used for those that are used from portlets.


Please let us know about your status

If you can, can you add source code -we can check directly even

Thanks,
- Nagendra Kumar
Mika Koivisto
RE: Hooked class does not find superclass from portal-impl.jar
November 22, 2011 5:49 PM
Answer

Mika Koivisto

LIFERAY STAFF

Rank: Liferay Legend

Posts: 1501

Join Date: August 7, 2006

Recent Posts

Like Nagendra suggested you should extend BaseStrutsPortletAction or implement com.liferay.portal.kernel.struts.StrutsPortletAction. Also you should need to copy the full ViewAction class because you get a handle to it so that you can wrap it with your own logic. You can think of your hook struts action as Aspect that can wrap the original action and do any pre/post logic or even skip executing the original action. It's not like Service hook where you can actually extend the service wrapper.
Dave Kliczbor
RE: How to make a wrapper around a struts action from portal-impl.jar
November 24, 2011 5:46 AM
Answer

Dave Kliczbor

Rank: Junior Member

Posts: 55

Join Date: July 12, 2011

Recent Posts

Thanks for the answers! At first, I was more confused than before, but I managed to code it. Actually, instead of overriding a class, this approach puts a wrapper around the method call in question and reverts some of the attributes to it's original (desired) value. It's okay for my goals, but it's not as flexible as my original idea (By now, I think I'd actually need a EXT plugin for that ... or not?).

For the record: I created a hook plugin in Eclipse/Liferay IDE and replaced a few JSPs (see standard tutorials) from the requests portlet. As soon as that worked, I had to do the following steps:

WEB-INF/liferay-hook.xml
 1<?xml version="1.0" encoding="UTF-8"?>
 2<!DOCTYPE hook PUBLIC "-//Liferay//DTD Hook 6.1.0//EN" "http://www.liferay.com/dtd/liferay-hook_6_1_0.dtd">
 3
 4<hook>
 5    <custom-jsp-dir>/custom_jsps</custom-jsp-dir>
 6    <struts-action>
 7        <struts-action-path>/requests/view</struts-action-path>
 8        <struts-action-impl>com.liferay.portlet.customrequests.action.ViewAction</struts-action-impl>
 9    </struts-action>
10</hook>

I found the relevant struts-action-path in ROOT/WEB-INF/struts-config.xml by looking for "requests" and "ViewAction".

Then I created a new class in my hook:
ViewAction.java (in package com.liferay.portlet.customrequests.action)
 1
 2package com.liferay.portlet.customrequests.action;
 3
 4import com.liferay.portal.kernel.struts.BaseStrutsPortletAction;
 5import com.liferay.portal.kernel.struts.StrutsPortletAction;
 6
 7import javax.portlet.ActionRequest;
 8import javax.portlet.ActionResponse;
 9import javax.portlet.PortletConfig;
10import javax.portlet.RenderRequest;
11import javax.portlet.RenderResponse;
12import javax.portlet.ResourceRequest;
13import javax.portlet.ResourceResponse;
14
15import com.liferay.portal.util.WebKeys;
16
17public class ViewAction extends BaseStrutsPortletAction {
18
19    public void processAction(
20            StrutsPortletAction originalStrutsPortletAction,
21            PortletConfig portletConfig, ActionRequest actionRequest,
22            ActionResponse actionResponse)
23        throws Exception {
24            originalStrutsPortletAction.processAction(
25                originalStrutsPortletAction, portletConfig, actionRequest,
26                actionResponse);
27    }
28   
29    public String render(
30            StrutsPortletAction originalStrutsPortletAction,
31            PortletConfig portletConfig, RenderRequest renderRequest,
32            RenderResponse renderResponse)
33        throws Exception {
34            String ret = originalStrutsPortletAction.render(
35                    null, portletConfig, renderRequest, renderResponse);
36            renderRequest.setAttribute(WebKeys.PORTLET_DECORATE, Boolean.TRUE);
37            return ret;
38    }
39   
40    public void serveResource(
41            StrutsPortletAction originalStrutsPortletAction,
42            PortletConfig portletConfig, ResourceRequest resourceRequest,
43            ResourceResponse resourceResponse)
44        throws Exception {
45            originalStrutsPortletAction.serveResource(
46                originalStrutsPortletAction, portletConfig, resourceRequest,
47                resourceResponse);
48    }
49}

The only relevant line that changed behaviour actually is the renderRequest.setAttribute(...) line...

Export to WAR file, deploy -- works!
Vishal Panchal
RE: How to make a wrapper around a struts action from portal-impl.jar
November 29, 2012 11:44 PM
Answer

Vishal Panchal

Rank: Expert

Posts: 277

Join Date: May 20, 2012

Recent Posts

Thank you for your contribution.
It worked for me.!

Regrads,
Vishal
me liferay
RE: How to make a wrapper around a struts action from portal-impl.jar
December 13, 2012 6:10 AM
Answer

me liferay

Rank: New Member

Posts: 23

Join Date: December 14, 2011

Recent Posts

Is there any one who have tried with the new version6.0.6.
As the action class has been changed to com.liferay.portal.struts.PortletAction old class no longer exist.
Mika Koivisto
RE: Hooked class does not find superclass from portal-impl.jar
December 13, 2012 4:17 PM
Answer

Mika Koivisto

LIFERAY STAFF

Rank: Liferay Legend

Posts: 1501

Join Date: August 7, 2006

Recent Posts

Liferay 6.0.6 does not support Struts action hooks it's only available to 6.1 and newer.
me liferay
RE: Hooked class does not find superclass from portal-impl.jar
December 28, 2012 2:50 AM
Answer

me liferay

Rank: New Member

Posts: 23

Join Date: December 14, 2011

Recent Posts

thanks Mika