Thursday, June 16, 2011

ADF Managed Bean Memory Scope and its Configuration Files

From time to time, I see lots of people messed up with managed bean memory scopes as the application complexity increases. Those errors you would see are types of Null Pointer Exception or the bean/its attribute/method cannot be found. Most of the time the reason behind it is its managed bean memory scope is not set up properly.

JSF web application itself has 4 types of scopes: application, session, request and none; ADF technology has brought 3 additional types of scopes: page flow, view and backing bean. The most common ones being used across an ADF fusion application are request, page flow, view and backing bean. Though placing a managed bean into a bigger scope than it should be will still work for your application most of the time but will bring cost on the overhead, placing the bean the other around will definitely stop your application from working properly.

If you are working on the ADF fusion application, the developer's guide should the first resource to refer. The following table list 3 locations of registering your managed bean and their rules of thumb:


Table 20-1 Effects of Managed Bean Configuration Placement
Managed Bean PlacementEffect
adfc-config.xml
  • Managed bean can be of any scope. However, any backing beans for page fragments or declarative components should useBackingBean scope. For more information regarding scope, see Section 21.3, "Object Scope Lifecycles."
  • When executing within an unbounded task flow, faces-config.xml will be checked for managed bean definitions before theadfc-config.xml file.
  • Lookup precedence is enforced per scope. Request-scoped managed beans take precedence over session-scoped managed beans. Therefore, a request-scoped managed bean named foo in the adfc-config.xml file will take precedence over a session-scoped managed bean named foo in the current task flow definition file.
  • Already instantiated beans take precedence over new instances being instantiated. Therefore, an existing session-scoped managed bean named foo will always take precedence over a request-scoped bean named foo defined in the current task flow definition file.
Task flow definition file
  • Managed bean can be of any scope. However, managed beans of request scope, of pageFlow scope, of view scope, or with the scope set to none that are to be accessed within the task flow definition must be defined within the task flow definition file. Any backing beans for page fragments in a task flow should use BackingBean scope.
  • Managed bean definitions within task flow definition files will be visible only to activities executing within the same task flow.
  • When executing within a bounded task flow, faces-config.xml will be checked for managed bean definitions before the currently executing task flow definition. If no match is found in either location, adfc-config.xml and other bootstrap configuration files will be consulted. However, this lookup in other adfc-config.xml and bootstrap configuration files will only occur for session- or application-scoped managed beans.
  • Lookup precedence is enforced per scope. Request-scoped managed beans take precedence over session-scoped managed beans. Therefore, a request-scoped managed bean named foo in the adfc-config.xml file will take precedence over a session-scoped managed bean named foo in the current task flow definition file.
  • Already instantiated beans take precedence over new instances being instantiated. Therefore, an existing session-scoped managed bean named foo will always take precedence over a request-scoped bean named foo registered in the current task flow definition file.
  • Customizations are allowed.
faces-config.xml
  • Managed beans can be of any scope other than pageFlow scope or view scope.
  • When searching for any managed bean, the faces-config.xml file is always consulted first. Other configuration files will be searched only if a match is not found. Therefore, beans registered in the faces-config.xml file will always win any naming conflict resolution.
  • No customizations can be made.



Additionally, the guide says:

As a general rule for Fusion web applications, a bean that may be used in more than one page or task flow, or one that is used by pages within the main unbounded task flow (adfc-config), should be registered in the adfc-config.xml configuration file. A managed bean that will be used only by a specific task flow should be registered in that task flow's definition file. There should be no beans registered in the faces-config.xml file.

The most common mistakenly setup of managed bean scopes in an ADF fusion application are:
  • A bean is used in more than one page or task flow and registered in one of the task flow definition files
  • A bean for page fragment in a task flow is not put into the backing bean scope.
  • Put a common accessible bean into faces-config.xml
  • Put a bean in adfc-config.xml and choose the scope as "PageFlowScope"
  • Put a bean in a bigger scope than it should.

Wednesday, June 1, 2011

Invoke actions on non-command component

It's a small demo on how to perform additional actions on click a goLink component which doesn't support any action logics inherently. The solution is to use javascript to invoke a command component programatically. But why do I need to perform some action on a golink click, why don't I use commandLink directly? Well, the reasons can be many, one of the valid reason is if you have such requirement like: on click of a link, open a predefined URL in a new window and also perform some action. I know there must be other similar scenarios which could be categoried into the same group like this one.

The implementation is fairly easy. Here is the code snippet:



The command link is hidden and aligned after goLink in page source. The additional action logics is defined in the action listener of the command link. 

Here is the demo to download. (JDeveloper 11.1.1.5 and need HR schema objects to run)