Transient Instance Members in AM - Their Passivation and activation

There are cases where everything works well during development and testing but we face a lot of exceptions in the production environment. In most of the cases, this strange behavior will be related to wrong transient attribute usage, transient attribute whose value is not passivated and then it is lost after activation. In production, when there will be high workload and many concurrent users, ADF will start to passivate Application Module instances and we will face a problem. Production environment can be simulated by disabling Application Module Pooling.

Disabling AM Pooling
For disabling the AM pooling, checkout the AM and right click on it, select Configuration and then select Edit. Click on the “Pooling and Scalability” tab and disable the “Enable Application Module Pooling” check box.

Passivation of Instance Variable in AM
Instances variables are not passivated by the framework. Framework recommends not using any instance variables by the developer. If at all developer badly needs instance variables in any of the Impl class, Developer needs to explicitly override 'passivateState' and 'activateState' methods(in corresponding Impl) to passivate and activate those variables.

Passivating and Activating Custom Information in the State Snapshot XML Document

/**

* Overridden framework method to passivate custom XML elements
* into the pending state snapshot document
*/
public void passivateState(Document doc, Element parent) {

// 1. Retrieve the value of the value to save

int counterValue = getCounterValue();

// 2. Create an XML element to contain the value

Node node = doc.createElement(COUNTER);

// 3. Create an XML text node to represent the value

Node cNode = doc.createTextNode(Integer.toString(counterValue));

// 4. Append the text node as a child of the element

node.appendChild(cNode);

// 5. Append the element to the parent element passed in

parent.appendChild(node);

}

/**

* Overridden framework method to activate custom XML elements

* into the pending state snapshot document

*/

public void activateState(Element elem) {

super.activateState(elem);

if (elem != null) {

// 1. Search the element for any <jbo.counter> elements

NodeList nl = elem.getElementsByTagName(COUNTER);

if (nl != null) {

// 2. If any found, loop over the nodes found

for (int i=0, length = nl.getLength(); i < length; i++) {

// 3. Get first child node of the <jbo.counter> element

Node child = nl.item(i).getFirstChild();

if (child != null) {

// 4. Set the counter value to the activated value

setCounterValue(new Integer(child.getNodeValue()).

intValue()+1);

break;

}

}

}

}

}

private int getCounterValue() {

String counterValue = (String)getSession().getUserData().get(COUNTER);

return counterValue == null ? 0 : Integer.parseInt(counterValue);

}

private void setCounterValue(int i) {

getSession().getUserData().put(COUNTER,Integer.toString(i));

}

private static final String COUNTER = "jbo.counter";

Passivating/Activating Binary Objects

@Override
protected void passivateState(Document doc, Element parent) {
super.passivateState(doc, parent);
String stringifiedValue=getBase64EncodedObject( objectTobePassivated )

// Add them to the XML
Node nodeUserData = doc.createElement("USERDATA");
Element elem = doc.createElement("AM_OBJECT");
elem.setAttribute("KEY", key);
elem.setAttribute("VALUE",(String)base64EncodedProperties.get(key));
elem.setAttribute("TYPE", "java.lang.Object");
nodeUserData.appendChild(elem);
parent.appendChild(nodeUserData);
//...........Your code goes here........
}
private String getBase64EncodedObject(Object propertyValue) {
// Converts object to Base64 format
ByteArrawetputStream bos = new ByteArrawetputStream();
FastByteArrawetputStream fbos = null;
try {
fbos = new FastByteArrawetputStream();
ObjectOutputStream out = new ObjectOutputStream(fbos);
out.writeObject(propertyValue);
out.flush();
out.close();
} catch (IOException e) {
e.printStackTrace();
}
return Base64.byteArrayToBase64(fbos.getByteArray());
}

@Override
protected void activateState(Element parent) {
if (parent != null) {
NodeList nl = parent.getElementsByTagName("USERDATA");
if (nl.getLength() > 0) {
Node n = nl.item(0);
NodeList nl2 = n.getChildNodes();

for (int i = 0; i < nl2.getLength(); i++) {
Element e = (Element)nl2.item(i);

String key = e.getAttribute("KEY");
String value = e.getAttribute("VALUE");

try {
byte[] obj = Base64.base64ToByteArray(value);
ObjectInputStream in =
new ObjectInputStream(new
FastByteArrayInputStream(obj));
setValue(key, in.readObject());
in.close();
} catch (Exception ex) {
ex.printStackTrace();
}

}
}
}
super.activateState(parent);
}

Passivate state of a view object

1. In the Application Navigator, double-click a view object to open it in the overview editor.

  1. On the General page, expand the Tuning section.
  2. Select Passivate State to make sure the view object data is saved.

Optionally, you can select Including All Transient Attributes to passivate all transient attributes at this time but see Fusion Dev Guide Section 39.8.4, "What You May Need to Know About Passivating Transient View Objects" for additional information.

References

        1. http://andrejusb.blogspot.in/2010/01/demystifying-adf-bc-passivation-and.html
2. 
http://docs.oracle.com/cd/E12839_01/web.1111/b31974/bcstatemgmt.htm#sthref3211
3.
http://jobinesh.blogspot.in/2010/09/annotate-your-applicationmodule-to.html
4.
http://jdeveloperfaq.blogspot.in/2010/02/faq-14-how-to-test-application-module.html
5.
http://productivitywithchoice.blogspot.in/2011/03/is-your-application-passivation-safe.html

Comments:

Post a Comment:
  • HTML Syntax: NOT allowed
About

ADF Tips and Tricks

Search

Categories
Archives
« April 2014
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today