Need of
clustered environment
If your system is underperforming and not available enough
then that signs that you need clustering. It will improve Scalability and high
availability (If one member of the cluster is unavailable, any other available
member of the cluster is able to handle the request.)
When the Fusion web application runs in a clustered
environment, a portion of the application’s state is serialized and copied to
another server or a data store at the end of each request so that the state is
available to other servers in the cluster .If it not serialized then user will
lose data upon fail-over.
WebLogic duplicates those sessions by serializing the
objects in the session and then transfers it to the secondary machine. Only the
objects that are stored in the session will be replicated. From an ADF
perspective this means that managed bean with pageFlowScope and above will be
replicated.
Configuring Oracle ADF development for High Availability
JSF Component Binding
- Always use ComponentReference binding code in your managed beans, regardless of the scope the bean is in.
- Never use UIComponent binding in session-scoped managed beans.
- Please make sure that managed beans used in ADF application with a scope greater than one request should be serializable (implement the java.io.Serializable interface).
Specifically, beans stored in session scope, page flow
scope, and view scope need to be serializable.
UIComponent is not a serializable class, and you are
going to get a serialization exception in case of binding components to the
long-living managed beans.
Also the UI component tree might not be released correctly,
significantly increasing the memory load of your application.
Solution: (for
Binding UI Component)
The standard UIComponent binding code looks like this:
RichInputText nameField;
public void setNameField(RichInputText
nameField)
{
this.nameField = nameField;
}
public RichInputText
getNameField()
{
return nameField;
}
Should be replaced with code
like this:
private ComponentReference
nameField;
public RichInputText
getNameField()
{
if (nameField!=null)
{
return (RichInputText)
nameField.getComponent();
}
return null;
}
public void
setNameField(RichInputText nameField)
{
this.nameField =
ComponentReference.newUIComponentReference(nameField);
}
Configuring
Application Modules
Right-click the application module and select
Configurations. Click Edit. Click the Pooling and Scalability tab. Select the
Failover Transaction State Upon Managed Release checkbox.
<AppModuleConfig ...
<AM-Pooling
jbo.dofailover="true"/>
</AppModuleConfig>
Configuring
weblogic.xml
In weblogic.xml file, add entry as below
persistent-store-type definition to the session-descriptor element like below
<weblogic-web-app>
<session-descriptor>
<persistent-store-type>REPLICATED_IF_CLUSTERED</persistent-store-type>
</session-descriptor>
</weblogic-web-app>
Configuring
adf-config.xml
In adf-config.xml file, add entry as like below
<adf-controller-config
xmlns="http://xmlns.oracle.com/adf/controller/config">
<adf-scope-ha-support>true</adf-scope-ha-support>
</adf-controller-config>
Notify ADF for Bean
new value
When a value within a managed bean in either view scope or
page flow scope is modified, the application needs to notify Oracle ADF so that
it can ensure the bean's new value is replicate.
Map<String, Object> viewScope =
AdfFacesContext.getCurrentInstance().getViewScope();
MyObject obj =
(MyObject)viewScope.get("myObjectName");
Obj.setName("newValue");
Use the markScopeDirty() method,
controllerContext ctx =
ControllerContext.getInstance();
ctx.markScopeDirty(viewScope);
There is one more option which needs to be tested:
You can also enable automatic tracking of scope
modifications. To do this you should modify adf-config.xml as shown below,
Check default logger
messages
Run each use case in UI application. Verify that you don’t
see below highlighted errors in Domain console log.
[manageserver1] [ERROR] [] [oracle.adfinternal.controller.state.SessionBasedScopeMap]
java.io.NotSerializableException:
com.ram.mytest.manage.TestMB
Changes in
Application server
While doing development Jdeveloper integrated server will
not throw any errors by default. Add this parameter in server
(setDomainEnv.cmd) has to be run with the following JVM parameter:
-Dorg.apache.myfaces.trinidad.CHECK_STATE_SERIALIZATION=all
For more detail about sample application deployment in
cluster and configurations, check out my post here