Foren

Hooked class does not find superclass from portal-impl.jar

thumbnail
Dave Kliczbor, geändert vor 12 Jahren.

Hooked class does not find superclass from portal-impl.jar

Junior Member Beiträge: 77 Beitrittsdatum: 12.07.11 Neueste Beiträge
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:
	<struts-action>
		<struts-action-path>requests</struts-action-path>
		<struts-action-impl>com.liferay.portlet.requests.action.ViewAction</struts-action-impl>
	</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:
13:02:30,115 ERROR [HotDeployUtil:114] com.liferay.portal.kernel.deploy.hot.HotDeployException: Error registering hook for CustomRequest-hook-0.2
com.liferay.portal.kernel.deploy.hot.HotDeployException: Error registering hook for CustomRequest-hook-0.2
        at com.liferay.portal.kernel.deploy.hot.BaseHotDeployListener.throwHotDeployException(BaseHotDeployListener.java:46)
        at com.liferay.portal.deploy.hot.HookHotDeployListener.invokeDeploy(HookHotDeployListener.java:288)
        at com.liferay.portal.kernel.deploy.hot.HotDeployUtil._doFireDeployEvent(HotDeployUtil.java:111)
        at com.liferay.portal.kernel.deploy.hot.HotDeployUtil._fireDeployEvent(HotDeployUtil.java:188)
        at com.liferay.portal.kernel.deploy.hot.HotDeployUtil.fireDeployEvent(HotDeployUtil.java:40)
        at com.liferay.portal.kernel.servlet.PortletContextListener.doPortalInit(PortletContextListener.java:101)
        at com.liferay.portal.kernel.util.BasePortalLifecycle.portalInit(BasePortalLifecycle.java:42)
        at com.liferay.portal.kernel.util.PortalLifecycleUtil.register(PortalLifecycleUtil.java:61)
        at com.liferay.portal.kernel.util.PortalLifecycleUtil.register(PortalLifecycleUtil.java:53)
        at com.liferay.portal.kernel.util.BasePortalLifecycle.registerPortalLifecycle(BasePortalLifecycle.java:50)
        at com.liferay.portal.kernel.servlet.PortletContextListener.contextInitialized(PortletContextListener.java:55)
        at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4723)
        at org.apache.catalina.core.StandardContext$1.call(StandardContext.java:5226)
        at org.apache.catalina.core.StandardContext$1.call(StandardContext.java:5221)
        at java.util.concurrent.FutureTask$Sync.innerRun(Unknown Source)
        at java.util.concurrent.FutureTask.run(Unknown Source)
        at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
        at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.NoClassDefFoundError: com/liferay/portal/struts/PortletAction
        at java.lang.ClassLoader.defineClass1(Native Method)
        at java.lang.ClassLoader.defineClassCond(Unknown Source)
        at java.lang.ClassLoader.defineClass(Unknown Source)
        at java.security.SecureClassLoader.defineClass(Unknown Source)
        at org.apache.catalina.loader.WebappClassLoader.findClassInternal(WebappClassLoader.java:2820)
        at org.apache.catalina.loader.WebappClassLoader.findClass(WebappClassLoader.java:1150)
        at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1645)
        at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1523)
        at com.liferay.portal.kernel.util.InstanceFactory.newInstance(InstanceFactory.java:52)
        at com.liferay.portal.kernel.util.InstanceFactory.newInstance(InstanceFactory.java:27)
        at com.liferay.portal.deploy.hot.HookHotDeployListener.initStrutsAction(HookHotDeployListener.java:1852)
        at com.liferay.portal.deploy.hot.HookHotDeployListener.doInvokeDeploy(HookHotDeployListener.java:881)
        at com.liferay.portal.deploy.hot.HookHotDeployListener.invokeDeploy(HookHotDeployListener.java:285)
        ... 17 more
Caused by: java.lang.ClassNotFoundException: com.liferay.portal.struts.PortletAction
        at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1678)
        at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1523)
        ... 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?
thumbnail
Nagendra Kumar Busam, geändert vor 12 Jahren.

RE: Hooked class does not find superclass from portal-impl.jar (Antwort)

Liferay Master Beiträge: 678 Beitrittsdatum: 07.07.09 Neueste Beiträge
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
thumbnail
Mika Koivisto, geändert vor 12 Jahren.

RE: Hooked class does not find superclass from portal-impl.jar (Antwort)

Liferay Legend Beiträge: 1519 Beitrittsdatum: 07.08.06 Neueste Beiträge
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.
thumbnail
Dave Kliczbor, geändert vor 12 Jahren.

RE: How to make a wrapper around a struts action from portal-impl.jar (Antwort)

Junior Member Beiträge: 77 Beitrittsdatum: 12.07.11 Neueste Beiträge
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
<!--?xml version="1.0" encoding="UTF-8"?-->


<hook>
	<custom-jsp-dir>/custom_jsps</custom-jsp-dir>
	<struts-action>
		<struts-action-path>/requests/view</struts-action-path>
		<struts-action-impl>com.liferay.portlet.customrequests.action.ViewAction</struts-action-impl>
	</struts-action>
</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)

package com.liferay.portlet.customrequests.action;

import com.liferay.portal.kernel.struts.BaseStrutsPortletAction;
import com.liferay.portal.kernel.struts.StrutsPortletAction;

import javax.portlet.ActionRequest;
import javax.portlet.ActionResponse;
import javax.portlet.PortletConfig;
import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;
import javax.portlet.ResourceRequest;
import javax.portlet.ResourceResponse;

import com.liferay.portal.util.WebKeys;

public class ViewAction extends BaseStrutsPortletAction {

	public void processAction(
			StrutsPortletAction originalStrutsPortletAction,
			PortletConfig portletConfig, ActionRequest actionRequest,
			ActionResponse actionResponse)
		throws Exception {
			originalStrutsPortletAction.processAction(
				originalStrutsPortletAction, portletConfig, actionRequest,
				actionResponse);
	}
	
	public String render(
			StrutsPortletAction originalStrutsPortletAction,
			PortletConfig portletConfig, RenderRequest renderRequest,
			RenderResponse renderResponse)
		throws Exception {
			String ret = originalStrutsPortletAction.render(
					null, portletConfig, renderRequest, renderResponse);
			renderRequest.setAttribute(WebKeys.PORTLET_DECORATE, Boolean.TRUE);
			return ret;
	}
	
	public void serveResource(
			StrutsPortletAction originalStrutsPortletAction,
			PortletConfig portletConfig, ResourceRequest resourceRequest,
			ResourceResponse resourceResponse)
		throws Exception {
			originalStrutsPortletAction.serveResource(
				originalStrutsPortletAction, portletConfig, resourceRequest,
				resourceResponse);
	}
}

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

Export to WAR file, deploy -- works!
thumbnail
Vishal Panchal, geändert vor 11 Jahren.

RE: How to make a wrapper around a struts action from portal-impl.jar

Expert Beiträge: 289 Beitrittsdatum: 20.05.12 Neueste Beiträge
Thank you for your contribution.
It worked for me.!

Regrads,
Vishal
thumbnail
Mittal Patoliya, geändert vor 11 Jahren.

RE: How to make a wrapper around a struts action from portal-impl.jar

Junior Member Beiträge: 25 Beitrittsdatum: 14.12.11 Neueste Beiträge
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.
thumbnail
Mika Koivisto, geändert vor 11 Jahren.

RE: Hooked class does not find superclass from portal-impl.jar

Liferay Legend Beiträge: 1519 Beitrittsdatum: 07.08.06 Neueste Beiträge
Liferay 6.0.6 does not support Struts action hooks it's only available to 6.1 and newer.
thumbnail
me liferay, geändert vor 11 Jahren.

RE: Hooked class does not find superclass from portal-impl.jar

Junior Member Beiträge: 25 Beitrittsdatum: 14.12.11 Neueste Beiträge
thanks Mika