Blogs

Blogs

Overriding features from different Hooks - Chapter 2: Struts Actions

Do you remember the article that I wrote in March? It talked about Liferay's limitation to have each overloaded JSP only customizable from one hook. The limitation was not enforced, so deploying multiple hooks that overload the same JSP lead to undefined behaviour, potentially deleting the original JSP.
CC BY 2.0 by David Goehring
Luckily that has been fixed (currently in EE only, feature needs to be enabled), but I still like my version better: It's more verbose in its error messages. And then - there's more: The very same limitation (albeit not as destructive) is in effect for Struts Actions: If you override the same Struts Action from two different plugins, the last deployed plugin wins, the first one's Action will be forgotten. And when we inspect this further, we have some undefined behaviour as well: Let's say Hook A and Hook B override the same Struts Action and are deployed in that order. Now only Hook B's version will ever be executed (as it was deployed last).

In case Hook A is now undeployed, the runtime system will detect that Hook A intended to override the Struts Action and remove the customization. Now, despite the fact that Hook B is still deployed, its Struts Override is no longer deployed. Luckily, this is not destructive like with JSPs, but you might still pull out your hair when you're debugging such a situation. Let me save your hair - I know how it feels to walk around with little hair. Mine is not enough (and too short) to pull it out:

An updated HookDeployer \o/

The hook that I've presented in the old blog article received an update and now is aware of Struts Actions. You can go to github, build the ext plugin and deploy it. Be aware that the code is "Proof of Concept" quality.
CC BY 2.0 by David Goehring and yours truly
Before using it in production you should really validate that it does what you expect.

About the implementation

If you look at the code, you'll see that there's a relatively small class that just does the checking. In case everything is right, it delegates to the original deployer. This is why I expect this code to be compatible with all 6.2 releases (and potentially even 6.1 without checking). One way to write maintainable ext plugins is to add new code in new classes and delegate to the original classes: If the original classes are changed in some future release, the additional code has a good chance to go without changes. It's Liferay's business to change the implementation, thus I've avoided to change the original HookHotDeployListener class.

Check out the code on github - fork and send pullrequests: Again, note the "Proof Of Concept" disclaimer. Please try, test & inspect on it out on your platform & version. I deliberately won't tell you which version I've tested it on to force you to test :)

Like in March (this is the same plugin as back then): I can't make it available on marketplace, as it's an ext-plugin. Sorry.