Fórumok

Nyitólap » Liferay Portal » English » 3. Development

Kombinált nézet Egyszerű nézet Fa-nézet
Szálak [ Előző | Következő ]
toggle
Dave Kliczbor
Hooked class does not find superclass from portal-impl.jar
2011. november 22. 5:45
Válasz

Dave Kliczbor

Rangsorolás: Junior Member

Hozzászólások: 55

Csatlakozás dátuma: 2011. július 12.

Legújabb hozzászólások

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
2011. november 22. 6:13
Válasz

Nagendra Kumar Busam

Rangsorolás: Liferay Master

Hozzászólások: 567

Csatlakozás dátuma: 2009. július 7.

Legújabb hozzászólások

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
2011. november 22. 17:49
Válasz

Mika Koivisto

LIFERAY STAFF

Rangsorolás: Liferay Legend

Hozzászólások: 1325

Csatlakozás dátuma: 2006. augusztus 7.

Legújabb hozzászólások

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
2011. november 24. 5:46
Válasz

Dave Kliczbor

Rangsorolás: Junior Member

Hozzászólások: 55

Csatlakozás dátuma: 2011. július 12.

Legújabb hozzászólások

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
2012. november 29. 23:44
Válasz

Vishal Panchal

Rangsorolás: Expert

Hozzászólások: 264

Csatlakozás dátuma: 2012. május 20.

Legújabb hozzászólások

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
2012. december 13. 6:10
Válasz

me liferay

Rangsorolás: New Member

Hozzászólások: 14

Csatlakozás dátuma: 2011. december 14.

Legújabb hozzászólások

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
2012. december 13. 16:17
Válasz

Mika Koivisto

LIFERAY STAFF

Rangsorolás: Liferay Legend

Hozzászólások: 1325

Csatlakozás dátuma: 2006. augusztus 7.

Legújabb hozzászólások

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
2012. december 28. 2:50
Válasz

me liferay

Rangsorolás: New Member

Hozzászólások: 14

Csatlakozás dátuma: 2011. december 14.

Legújabb hozzászólások

thanks Mika