As told in my previous entry our objective relies on creating "a HookHotDeployer that feeds our new methods in Liferay's Main Servlet so that this can load all the necessary stuff". So, first of all, we'll need to:
- Extend Liferay's Main Servlet class (com.liferay.portal.servlet.MainServlet), wich we will call HotdeployMainServlet from now on
- Create a HookHotDeployListener, extending com.liferay.portal.kernel.deploy.hot.BaseHotDeployListener
Both of them will have three main methods: one to load struts configurations, one to load tiles configurations, and one to load hook's classes and libraries into Liferay's classloader. Three of them will work the same way:
- The HookHotDeployer will check if there are any of these three elements to loaaddClassLoaderRepositoryd
- If so, it will retrieve the necessary information (the content of the corresponding files) and inform HotdeployMainServlet through some static methods
- In each request, HotdeployMainServlet will check if there are any configurations/classes to load, if so, it will do it before calling its parent class service method.
Adding classes to Liferay's classloader
To add hook's classes and libraries to Liferay's classloader we will create a method in HookHotDeployListener, wich I will call "addClassLoader", receiving the hook's servlet context, wich we can get from the event passad to HookHotDeployListener's invokeDeploy method.
In addClassloader, we will need to check if there are some class files under the WEB-INF/classes directory, and/or some jar files under the WEB-INF/lib directory. If so, we will add the classes dir as a new repository to the corresponding classloader (Liferay's one), and add those jar files, individually, as new repositories to that classloader too.
And that's it!
Let's put some code on those words...
Let's put some code on those words...
You can put that code in the HookHotDeployer and call it whenever a hook is deployed.
As you've seen, we have'nt, already, extended Liferay's Main Servlet, it is beacuse that is only needed for the Struts and Tiles part of this module.
Adding and overwriting Struts configurations
To load and/or overwrite Liferays Struts configurations, we will let the new hotdeployer read those new configurations found in the deployed hook, and tell Main Servlet to apply them.
So the sequence is:
- A hook is hotdeployed and our HookHotdeployer reads that hook's struts-config file
- The HookHotdeployer extracts those configurations from the file, and sends them to our Main Servlet
- The new main servlet stores thos configurations and writes down that there are configurations to be loaded, through a static class variable called addStrutsConfigs, and what are those configurations, through a static variable called xmlStrutsConfigs.
- On the next request to the Main Servlet, it will check wheter there are new configurations to be loaded, and, if so, loads them using a method called addStrutsConfigFile
Before showing the code, I'll explain one important thing you should know:
When Liferay ends loading its struts configurations, those are freezed, so that they can not be changed later. To avoid this, we will implement our own Struts module config factory, and our own ModuleConfig. The new factory will only have to overwrite the method "createModuleConfig(String prefix)"
so that this returns our ModuleConfig. On the other hand, the new ModuleConfig will just override the method freeze so that it does just nothing.
Here is the code that reads the Hook's Struts configurations:
As you can see, a static method addStrutsConfig is called on HotdeployMainServlet (our extension of Liferay's Main Servlet), this method is, actually, the responsible for loading those configs on Liferay's Struts contex:
The condition "HotdeployMainServlet.addStrutsConfigs" wil be explained further on. By the moment, just let you know that it is read from a properties file that let's you tell the module wich configurations should be loaded or not, so that we can keep some control over zeep o'Tron.
Adding/overriding Tiles configurations
Following the same strategy as with Struts configurations the Hook Hotdeployer will send to our Main Servlet what is to be loaded.
So, in our hotdeployer we can add:
And in our Main Servlet:
And that's it! Following those headlines you will be able to modify/add classes, struts and spring configurations, and tiles definitions to Liferay Portal Server just by using hook, that can be hot deployed!
If you don't feel like getting those clues and pieces, and building up the code yourself, in the next and final entry for these series, you'll find the full code and deployment instructions.
Keep reading about this in Part 3!