Manual passivation and activation of Application Module instance variables

JDev version:

We are aware of ADF's passivation and activation mechanism. We know that when we need to persist the state of a transient attribute of a view object, we ask the framework explicitly to passivate such an attribute.

However, sometimes we may also need to persist the state of an Application Module class' member variable. Let us say that we have an Integer variable which gets incremented on a certain operation. At a high user load, or when doFailover is turned on, the application module instance is passivated and activated almost on every request.

The ADF framework passivates only that data which is required to initialize the application module to the earlier state, and the ones that we explicitly ask for (by checking the passivate checkbox). All other instance level values are rejected and re-initialized. Let's see an example.

To demonstrate this, I have turned off application module pooling, to ensure all requests are forced to be passivated to the database table.

I have an integer variable, initialized to 1. I have a method to increment this variable 5 times. I have exposed this method as a client service method, and I run this from the UI.
I run this method 3 times, and every time, I see that the counter variable has been re-initialized to 1, and the final value goes up to 5.

Now what if I want to save the state of the variable? What if my use-case asks me to track the the number for my session?

If your immediate response is a static variable, then NO! A static variable would mean that all application module instances, irrespective of which session they cater to, will hold the state of the variable. And that is not what we want!

ADF framework's oracle.jbo.server.ApplicationModuleImpl gives us two public APIs to help us with our cause here - passivateState and activateState. Let's see how we can make use of them.

passivateState method takes two arguments - org.w3c.dom.Document and org.w3c.dom.Element. We make use of these parameters to create a DOM structure, with all the data that we want to persist. This method is called automatically by the framework when the application module needs to be passivated.

We usually create one root element (APMI_OBJECT in this case), and multiple child elements (APMI_ELEMENT for example). All child elements are attached under the root node. But this structure depends on the use-case and the way you want to structure your variables.

Once the framework needs to activate the application module instance, the activateState method is called. This method takes in org.w3c.dom.Element parameter. This element is the root node, from which we get the root element, and its corresponding child elements.

We create our own node, save the structure. We reference the same node and retrieve the value from the structure. Now if we run our application, we get what we want. Run another instance of the application from another browser, you'll notice that each session holds its own AM variable, which gets incremented accordingly.