Showing posts with label Application Module. Show all posts
Showing posts with label Application Module. Show all posts

Sunday, May 2, 2010

FAQ #21 - How to passivate/activate ADF Application Module class instance variables

Introduction

If you are using instance variables in your Application Module (AM) class, as part of some algorithm in your application and you expect these variables to persist from one user request to another so that the algorithm works as expected, passivation (and activation) support for these variables must be added. This FAQ will show you how to do this and at the same time build a "mini sub-framework" to avoid duplication of the basic passivation-activation code that you must write for all your AMs in your project.


Main Theme

Some Introductory Information

Application Module pooling is the process of acquiring an AM from and releasing it back to a pool. This pool of AMs contains a limited number of AMs defined in a configuration file. When all AMs have been associated with user sessions, an already-used AM must be re-used. For this to happen, the existing data associated with the AM must be saved. The passivation process saves information used by the AM into the passivation store -  usually a database, while the activation process does exactly the opposite, restores the state of the  AM from the passivation store. The information is saved as an XML document. Take a look at FAQ #14 - How to test an Application Module for activation-safe in ADF 11g for additional information regarding the passivation and activation processes.

You can add custom passivation and activation logic in your AM class by overriding the ApplicationModuleImpl methods passivateState() and activateState() respectively. The passivateState() method should create the necessary XML elements for each AM instance variable that you need to passivate. The activateState()  method should detect the specific XML elements that identify the instance variables in the passivated XML document and restore them back into the instance variables.


A "mini sub-framework" for passivating/activating Application Module instance variables

If you are using multiple AMs, you can avoid code duplication of this basic implementation of the passivateState() and activateState() methods by putting it in a base AM class. Then derive all of your other AMs from this base AM. The base AM class can then provide activation/passivation "triggers" to which the derived AMs can respond. The implementation of passivateState()  in the base AM should look like this:




As you can see, after calling super.passivateState() to allow the framework to do its own processing, we call onStartPassivation() to signal derived AMs that a passivation process is taking place. Derived AMs should override onStartPassivation() in order to provide a list of the identifiers - each identifier tied to a specific instance variable - to be passivated. Below is an example implementation of onStartPassivation() by a derived AM class. 


In this case a single passivation identifier call EMPLOYEE_LIST_ID is returned to indicate a list of Employees class instance variable.

passivateState() then loops for all passivation identifiers, creates an XML node for each identifier in the XML passivation document and calls onPassivate() passing the passivation identifier as an argument to it. A  derived AM will override this method in order to return the passivation data for the specific passivation identifier. An example implementation is shown below:




In this case the passivation identifier is checked and if it matches the expected identifier, the passivation data is supplied. 

Finally, passivateState() calls onEndPassivation()  to indicate the end of the passivation process.

The reverse process of activation is similar. 
activateState() calls onStartActivation() to get the activation identifiers. It then loops looking for each activation identifier in the activated XML document. If the identifier is found, calls onActivate() supplying the activation data along with its activation identifier as arguments. The derived AM can identify the instance variable being activated - based on the activation identifier, and restore it.

To test the framework, bring up the Edit Business Components Configuration dialog and  disable Application Module Pooling as it shown below. You do this by right-clicking on the AM in the Application Navigator and selecting Configurations... Then you click on Edit... to edit the specific configuration.




 This will in effect initiate a passivation-activation cycle for each request when the application is running. Finally save the configuration, enable debug logging on the console and run the application. You should see your AM class instance variables being activated.





To further explore this framework, the source code is supplied below.

Conclusion

If you are using class instance variables in the BC layer and you want their values to persit from one request to another, then passivating-activating these variables becomes necessary. The ADF BC framework allows you to do this by overriding the passivateState() and activateState() methods.


Until the next time, keep on JDeveloping!

Code

http://jdeveloperfaq.googlecode.com/files/JDeveloperFAQNo21.rar








Sunday, February 14, 2010

FAQ #14 - How to test an Application Module for activation-safe in ADF 11g

Introduction

For ADF applications, Activation refers to the process of re-instating an Application Module (AM) from a stored snapshot. A recommended test practice for ADF applications is to ensure that AMs are tested for activation-safe. This FAQ will show you how to do so.

Main Theme

The intricacies of Application Module state management are quite complex and if we were to describe it in a brief paragraph and as simple as possible we would say:

"For each request, as AMs are allocated from a pre-defined pool, they become associated with specific sessions, acquire a transactional state and become referenced by specific Data Controls (DC). The AMs along with their acquired state are returned back to the pool as soon as the request is serviced. When all AMs in the pool are used, i.e. all of them have a state and are associated with specific sessions and DCs, it becomes necessary to store the state of one such AM to the database (Passivation) and then assign it to some other session. Activation is the reverse process of restoring the state of a previously passivated AM. Once it is activated, the AM has its transactional state restored and becomes re-referenced by its original session and DC."

Testing an AM for activation-safe ensures that the transactional state of the AM being activated is intact up to the moment when it was actually passivated. In order to do such a test, we need to force the AM to go through a passivation/activation cycle. We can accomplish this by disabling AM pooling. This is easily done by right-clicking on the application module in the Application Navigator and selecting Configurations... to bring up the Manage Configurations dialog.


Select the Local configuration and click Edit... to bring up the Edit Business Components Configuration dialog. Click on the Pooling and Scalability tab and deselect the Enable Application Module Pooling option.


Disabling Application Module pooling has the effect of setting the jbo.ampool.doampooling configuration property to false as it is shown below.


Because there is no AM pool in use, this in effect turns on the passivation/activation cycle forcing a Passivation to occur at the end of each request as the AM is de-referenced from the session and the DC. Activation takes place on the next request when the AM along with its transactional state is reconstructed from the passivation store - usually a database - and is re-referenced to the session and the DC in order to service the request. Once you setup debug logging in the console, the activation/passivation cycle becomes obvious by examining the log messages in the Log console. Observe what is happening as you do uncommitted changes to your view objects. Passivation XML records are generated for each request describing the data changes - the data before and after the changes. These records are written to the PS_TXN table of the passivation store.


The passivation store defaults to the database used by the AM database but it can be specified to a different database by setting the property jbo.server.internal_connection in AM configuration as it is shown below.


The passivation store can also be a file in the system file by setting the AM configuration property jbo.passivationstore as it is shown below. The file system location can be specified by setting the property jbo.tmpdir.


Testing your AMs for activation-safe is a must if you are using:
  • transient variables
  • bind variables
  • private member variables in AMs, VOs or EOs
  • custom data in the Session hashtable 
For a blog entry that examines the effects of the AM passivation/activation cycle on transient variables take a look at Andrejus Baranovski's Demystifying ADF BC Passivation and Activation.


Conclusion

Testing your AMs for activation-safe is a recommended practice especially for the cases mentioned above.

Until the next time, keep on JDeveloping!


References

Fusion Developer's Guide for Oracle Application Development Framework 11g Release 1 (11.1.1) B31974-03 [Section 39.10 Testing to Ensure Your Application Module is Activation-Safe]
http://andrejusb.blogspot.com/2010/01/demystifying-adf-bc-passivation-and.html







Related Posts Plugin for WordPress, Blogger...