Tip of the Day - Application Startup Events

One of Liferay's more commonly used extension points is the application startup event. You can define custom code to run whenever your plugin is deployed. This is a powerful feature. In this blog post I'm going to describe a common use-case here at Ambientia, where we use these events to make sure that the custom fields the plugin is dealing with are always up to date.
 
Liferay’s Expando API can be leveraged in countless ways. You can add custom fields and edit their values on different Liferay models. You can also use these attributes in your own application and base your actions on some attributes that might not be there by default.
 
Minor problem, however, comes with configuring the custom fields. When creating a new environment or upgrading to a newer version of your application, you should always be sure that the custom attributes needed are added to your portal instance. You could do it manually, but keeping track of the changes and attributes needed is a task that is both tedious and error prone.
 
You can add the custom field programmatically as well, as I described in my previous blog post. It is easy to do. Now we're left with just one question: when should the code creating the data be run? As always, we have a few alternatives, but by combining the code needed with Liferay’s application start up events you can be sure that your environment will always be up to date after you've deployed your plugin. This is a simple task to accomplish.
 
Define your own application start up event in hooked portal.properties
 
You need to create a portal properties hook to your plugin and add an application start up event. The Action class required should extend the SimpleAction class, which defines just one method, which is called run. The parameter should contain the String array of portal instance ids, though in Liferay’s HookHotDeployListener they loop through the company id list and call the run method with only a one company id at a time. You can get the companyId also from CompanyThreadLocal where it is set just before your start up action is ran.
 
Custom class, which adds expando fields if they are needed by calling our custom services
 
Anyways, now you can call the code that creates your custom fields either to every portal instance there is, or apply custom logic to add them only where they are necessary. And adding the expando data is just the tip of the iceberg here. You can use the application start up events everywhere, for example, to fix user rights or to make sure the roles needed by the plugin are guaranteed to be there when you need them. The possibilities are endless, here's another great tool for your Liferay toolbox!
Blogs
Caveat: Use Startup Actions wisely, mainly for constructive work, never for destructive work, because they will run again on next startup. In case you need something running truly once and never again, it's safer to implement an Upgrade Action. Liferay will take care of it never to run a second time. For Startup Actions you'll have to pay attention yourself. Creating an Expando Field is no problem - you automatically won't create them again. But if you reset your portal to a baseline (potentially deleting existing content), you rather want that to be done once and never again when someone deploys the plugin again. Fun fact: The ancient SevenCogs implementation was first implemented as Startup Action. As it could be quite destructive, it was quickly migrated into an Upgrade Action
Thank you for your input, Olaf, you're correct! Creating expando fields with the start up action is a good feature because it enables you to easily update and also add new expando fields (or roles for instance) when necessary. With upgrade actions you have to make sure it runs again (or create a new one) if something more is added. Though maybe I'll write something about the upgrade action in the near future as well.
Hi Olaf,

Do you know a solution for DXP? How does one create start-up hook within OSGI?
Hooks are deprecated in DXP.
https://github.com/liferay/liferay-blade-samples (look for: "Extension point description:" and "application.startup.events")

Where does it say that these events ( startup action discussed here) are deprecated?

Both search terms don't yield helpful insights for me...

On the other hand Portal Properties documentation for 7.1 here https://docs.liferay.com/ce/portal/7.1-latest/propertiesdoc/portal.properties.html#Startup%20Events still refers to class SimpleAction (though in wrong, old 'struts' package).

And class SimpleAction on Github https://github.com/liferay/liferay-portal/blob/master/portal-kernel/src/com/liferay/portal/kernel/events/SimpleAction.java has no deprecation marker (and sadly no documentation at all, as so many other classes... But that's another topic).

Hm - I didn't get the earlier discussion. But I believe that LifecycleAction is the new kid on the block - with various possible key-properties https://github.com/liferay/liferay-blade-samples/blob/7.1/liferay-workspace/extensions/lifecycle-login-preaction/src/main/java/com/liferay/blade/samples/lifecycle/loginpreaction/LoginPreAction.java