Cross Column

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

Thursday, October 11, 2012

Passivation and Activation in Oracle ADF—jbo.passivationstore

The passivation/activation implementation in Oracle ADF Business Components[1] is designed to keep transaction states across multiple requests or sessions.

In this article, we will discuss one aspect of the passivation/activation implementation in Oracle Fusion Applications—the passivation store.

Passivation and Activation


There are two kinds of pools in use when running a typical Fusion web application:

  • Application Module (AM) pools
  • Database connection pools

An application module pool is a collection of instances of a single application module type which are shared by multiple application clients. As for database connection pools, they are usually maintained by the J2EE container. You can read [9] for more details. To tune Fusion Application's performance, you need to understand both pools[8].

Each time a user accesses a resource and that resource uses an AM to display data, the Application Module pool manager assigns an AM instance to the user session. If the pool runs out of connections, the AM pool Manager passivates the state of one of the sessions (either in the database or in a file), thus releasing an instance and assigning it to the new session. When the user that was passivated resumes their work, ADF will activate their state from the configured store. This is done automatically for you.

Passivation Store


In order to manage application module pending work, the application module pool asks AM instances to "snapshot" their state to XML at different times. If the value of the jbo.dofailover configuration parameter is true (default), then this XML snapshotting will happen each time the AM instance is released to the pool.

The AM instance snapshots can be saved either in the database or in a file. To configure it, you can set jbo.passivationstore to be:
  • database
  • file

File Store


If you set jbo.passivationstore to be file, by default passivation should go to use.dir. However, you can change the location by setting:
  • -Djbo.tmpdir
For example, in our CRM Fusion Application, we have selected file to be the passivation store. But, we didn't set its location (i..e jbo.tmpdir). By default, it used "user.dir":
  • <Installation Home>/instance/domains/<Server Name>/CRMDomain

To find out where "user.dir" points to on Linux, you can do:

$ls -l /proc/<pid>/cwd
cwd -> /c1/mt/rup1/instance/domains/myserver/CRMDomain


So, going to that directory, you can find a bunch of files used by CRM for passivation:

-rw-r----- 1 mygrp testuser 6380   Oct 11 10:04 BCacc13d9BCD
-rw-r----- 1 mygrp testuser 263    Oct 11 10:04 BC325e092dBCD
-rw-r----- 1 mygrp testuser 127186 Oct 11 10:04 BC166a7e7fBCD


DB Store


If you set jbo.passivationstore to be database (default), XML snapshots will be written to a BLOB column in a row of the PS_TXN table in the database.

While the file-based option is a little faster, unless your multiple application server instances share a file system, then the the database-backed passivation scheme is the most robust for application server-farm and failover scenarios.

Configuration Parameters


To summarize, the following configuration parameters are related to this topic:
  • jbo.dofailover
    • Enables eager passivation or not
  • jbo.passivationstore
    • Dictates the store type
  • jbo.tmpdir
    • Specifies the location for file store
You can reference [10] for other application module pool configuration parameters.

References

  1. Oracle ADF Essentials
  2. Reusable ADF Components—Application Modules
  3. Java System Properties
  4. Why is the user.dir system property working in Java?
  5. ADF BC Passivation/Activation and SQL Execution Tuning
  6. Demystifying ADF BC Passivation and Activation
  7. Ensuring that your ADF Application is Passivation/Activation Safe
  8. Understanding Application Module Pooling Concepts and Configuration Parameters
  9. Monitoring WebLogic JDBC Connection Pool at Runtime
  10. What You May Need to Know About Application Module Pool Parameters

Wednesday, June 15, 2011

Reusable ADF Components—Application Modules

In the course of application development, certain components will often be reused. Creating and consuming reusable components should be included in the early design and architectural phases of software projects.

Whether the reuse happens within the same application, or across different applications, it is often advantageous to package these reusable components into a library that can be shared between different teams. These shared libraries can be added to a repository. Later if you need a component, you may look into the repository for something to be reused.

Multiple Oracle ADF components are reusable, which include[1]:
  • Application modules
  • Business Components
  • Data controls
  • Task flows
  • Page templates
  • Declarative components
These reusable components can be packaged into the ADF Library for reuse in applications (see [4] for how-to). Creating an ADF Library JAR involves compiling the project and validating the components, creating a resource service file, control files, an adflibREADME.txt, and adding the relevant project files into a JAR.

In this article, we will discuss a specific reusable component—Application Module. Application modules are associated with Business Components. When the reusable application module was packaged, the JAR includes the Business Components used to create the application module. These components will be available for reuse.

For packaging application modules, JDeveloper adds three control files to the JAR:
  1. oracle.adf.common.services.ResourceService.sva
  2. Manifest.mf
  3. adfm.xml
The service resource file for an application module includes entries for the Business Components associated with the application module, as well as an entry for the application module data control.

When you add an application module to a project, the application module appears in the Data Controls panel.

What's Application Module

Within a running BC4J application, one can think of the following containership of application objects:
  • Root Application Module contains nested Application Modules
  • An Application Module contains View Objects
  • A View Object contains Row Sets
  • A Row Set contain Row Set Iterators
Application Modules can be nested. That is, an Application Module can (logically) contain one or more other Application Modules (i.e., nested AMs) as well as View Objects. The outermost containing Application Module is referred to as the "root" Application Module.

What Do You Need to Know about Nested Application Module

In this Andrejus Baranovskis' article, it has two application modules which contain View Objects created from Employee and Job tables and are packaged into two ADF libraries
  1. adflibEmplooyeesApp.jar
  2. adflibJobsApp.jar
These two libraries can be imported into an ADF web application in two ways:
  1. Integrating ADF JAR's directly into the ViewController project (i.e., using Application Modules directly from ADF JAR's)
  2. Integrating ADF JAR's into the Model project with its own Application Module (i.e., Application Components from imported libraries are created as nested Application Modules)
Using either approach, you need to add both JAR's to the application first. When you add an ADF Library JAR to a project, either by using the Resource Palette or by manually adding the JAR, an ADF Library definition is created in the project. The ADF Library JAR file will be added to the class path of the project. The project will access and consume the components in the JAR by reference. See here for how to add an ADF Library JAR to a project using the Resource Palette.

In the first approach, two JAR's are added to the consuming project's (i.e., ViewController project) class path and so is available for reuse. See here on how to add them to the ViewController project manually. As shown below, adflibEmployeesApp.jar and adflibJobsApp.jar are added to the ViewController project's class path:
LinkIn the second approach, you first create a new Application Module (i.e., HrModule) in the Model project. See here on how-to. To specify a composite root application module that nests an instance of an existing application module, you use the overview editor for the application module. See here on how-to.

As shown below, EmpModule and JobsModule are nested under root Application Module HrModule in the second approach:
Important notes about nested application modules:
  • A nested Application Module design is useful for applications that define several functional
  • sub-applications that share the same transaction context and transaction caches.
  • With a nested Application Module design, it is easy to re-deploy nested Application Modules as standalone Application Modules in different client applications without having to modify the metadata for the other existing Application Module.
  • When a root application module contains other nested application modules, they all participate in the root application module's transaction and share the same database connection and a single set of entity caches.
    • This sharing is handled for you automatically by the root application module and its "Transaction" object.
  • A nested Application Module cannot see the instances of any other Application Modules that might be nested beneath the same root.
  • The API for application modules also supports nesting of application modules at runtime.
  • Nested Application Module can help performance by reducing database connection usage (i.e., sharing a single database connection instead of owning a separate connection per AM).

Further Considerations

  • You should consider how to organize and group the library JARs in a structure that fits your organizational needs. For example,
    • Usually you want to have two separate application modules to support UIs and define services because
      • UI application modules may contain additional view objects and context values
        that are only required for a particular UI, but not needed by a business service.
      • Application modules that define public services are versioned, but internal UI
        application modules are not.
  • You should also consider creating standardized naming conventions so that both creators and consumers of ADF Library JARs can readily identify the component functionality.
    • You want to try to have unique names to avoid naming conflicts with other projects, components, or connections in the application.
    • Naming conflicts could arise from components created in the consuming application and those loaded from other JAR files.
  • A project corresponds to one ADF Library JAR.
    • If you create multiple projects and want to reuse components from each of the projects, you may need to create an ADF Library JAR for each project.
  • You can package multiple components into one JAR file, or you can package a single component into a JAR file.
    • Oracle ADF and JDeveloper give you the option and flexibility to create reusable components that best suit you and your organization.
  • You should avoid metadata naming conflicts between projects that will be combined at runtime.
    • The basic package naming requirement is that ADF metadata registries (.dcx,.cpx, and so on) are generated based on the project's package name. So, make the package name unique.

References
  1. Reusing Application Components
  2. Defining Nested Application Modules
  3. What you may need to know about Nested Application Module
  4. How to Package a Component into an ADF Library JAR

Sunday, May 1, 2011

Invoking Application Module Custom Methods from Oracle ADF Frontend—Why and How?

In an Oracle Fusion web application, you should use managed beans[4] to store logic that is related to the UI rendering only. All application data and processing should be handled by logic in the business layer of the application.

In this article, we'll show how to refresh a calculated attribute[6] named Total Comments after user adds a new comment using Create Comment Dialog. As noted above, refreshing Total Comments should be handled in ADF backend (i.e., ADF Business Components), not ADF frontend (i.e., ADF Faces). Note that ADF backend refers to Model project and ADF frontend refers to ViewController project in a Fusion web application.

Background Information

In the described application, we have two view objects (i.e., TestVO and TestCommentVO) with master-detail relationship. "TotalComments" on the TestVO is a calculated attribute which computes total number of chronological comments (represented by TestCommentVO) added to a test.

On the Test View page, it displays Total Comments column which is also a link. By clicking on the link, user can navigate to the Test Comment page. On the Test Comment page, user is allowed to add new comments. After adding new comments, the Total Comments column on the original Test View page need to reflect the new total.



The Task

To achieve this task, we need to invoke a custom method implemented in ADF Business Components from the Test Comment component implemented in ADF Faces. Method invokation is triggered when user clicks the Save and Close button to save the newly created comment.
The bridge provided between ADF frontend and ADF backend is the Data Binding Layer in Fusion web application[3]. ADF data-binding layer implements the Data Controls and Bindings from JSR-227. The data controls abstract the back-end business service implementations and binding objects link front-end user interface controls in a declarative way to back-end data.

The steps of the task ordered from backend (in blue) to frontend (in black) are summarized here:
  1. Creating a custom method named refreshTotalComments in the application module Class (i.e., SelTestPortalAMImpl.java).
  2. Exporting refreshTotalComments by including the method on the application module's UI client interface.
  3. Adding a new action binding[5] named refreshTotalComments on TestCommentPageDef.xml.
  4. Creating a managed bean named TestCommentBean.java with a method action named saveAndClose. In the method, it will retrieve and execute refreshTotalComments operation binding.
  5. Registering new managed bean in adc-config.xml with the scope of request.
  6. Linking method action saveAndClose on the managed bean to the actionlistener of Save and Close button.
In the following sections, we'll describe those steps in details.

Step 1 — Adding Custom Method to the AppModuleImpl File

To add a custom service method (i.e., refreshTotalComments) to your application module, you must generate the application module class files first.

To generate Java files for your application module class:
  1. In the Application Navigator, double-click the application module.
  2. In the overview editor, click the Java navigation tab and click the Edit java options button.
  3. In the Select Java Options dialog, select Generate Application Module Class.
  4. Click OK.

In SelTestPortalAMImpl.java file, you add your custom service method — refreshTotalComments. Here we have left out the details of refreshTotalComments. For ADF developers need to write a custom method such as refreshTotalComments, you can read this document. It provides a high-level description of the key ADF Business Components classes in the Oracle Application Development Framework and it summarizes the methods that ADF developers write, call, and override most frequently.

Step 2 — Publishing Custom Method on the Application Module’s Client Interface

To include a public method from your application module's custom Java class on the client interface, use the Java Classes page of the overview editor for the application module, and then click the Edit icon in the Client Interface section of the page to display the Edit Client Interface dialog. Select method refreshTotalComments from the Available list and click the Add button to shuttle them into the Selected list. Then click OK to close the editor.


You can include any custom method in the client interface that obeys these implementation rules:
  • If the method has a non-void return type, the type must be serializable (i.e., implements the java.io.Serializable interface).
  • If the method accepts any parameters, all their types must be serializable.
  • If the method signature includes a throws clause, the exception must be an instance of JboException in the oracle.jbo package.

Step 3 — Adding a New Action Binding

In the ViewController project, select Test Comment page and right click it. From the context menu, select "Go to Page Definition." This will bring you to the TestCommentPageDef.xml.

In the Overview editor for the Test Comment page definition’s Bindings and Executables tab, click the Add icon in the Bindings section. Then, follow these steps:
  1. In the Insert Item dialog, select methodAction and click OK.
  2. In the Create Action Binding dialog:
    • Select the data collection (i.e., SelTestPortalAMDataControl) where you have created your handler.
    • From the Operation dropdown list, select the handler (i.e., refreshTotalComments).
    • Click OK.



Step 4 — Creating a New Managed Bean

In the ViewController project, create a managed bean named TestCommentBean.java with a method action named saveAndClose as shown below.
public void saveAndClose(ActionEvent actionEvent) {
try{
// Commit the transaction
OperationBinding  oper = getOperBindings("Commit");
oper.execute();
// refresh total comments
oper = getOperBindings("refreshTotalComments");
oper.execute();
}catch(Exception e){
e.printStackTrace();
}
}
/**
* This methos returns the operation bindings of the passed method name
* @param operation name
* @return
*/
private OperationBinding getOperBindings(String operation) throws Exception
{
OperationBinding oper=null;

try
{
FacesContext facesContext = FacesContext.getCurrentInstance();
ExpressionFactory exp = facesContext.getApplication().getExpressionFactory();
DCBindingContainer bindingContainer =
(DCBindingContainer) exp.createValueExpression(facesContext.getELContext(),
                                      "#{bindings}",
                                       DCBindingContainer.class).getValue(facesContext.getELContext());
// A ControlBinding that binds an datacontrol action, including navigational
// actions such as "Next" and "Prev", or other actions such as "Commit" and
// "Rollback", to a view component.
oper = bindingContainer.getOperationBinding(operation);
}
catch(Exception e)
{
e.printStackTrace();
}
return oper;
} //end getOperBindings

As shown in the code, we need to retrieve two operation bindings (i.e., Commit and refreshTotalComments) from the binding container[7]. Operation binding refreshTotalComments is used at runtime to invoke our Application Module custom method.

Step 5 — Registering New Managed Bean in adc-config.xml

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.

To register TotalCommentBean in adc-config.xml, do the following:
  1. In the Application Navigator, double-click the adfc-config.xml file in theWEB-INF folder.
  2. In the editor window for the adfc-config.xml file, click the Overview tab.
  3. In the Managed Beans page, in the Managed Beans section click the Add icon and enter TotalCommentBean as the name of the bean, enter the fully qualified class name, and select request scope[8].

Step 6 — Linking Method Action to the ActionListener of Button

The final step is to link method action saveAndClose on the managed bean to the actionListener of Save and Close button as shown below:
<af:commandbutton id="FAsc1"
textandaccesskey="#{applcoreBundle.SAVE_AND_CLOSE}"
shortdesc="#{applcoreBundle.SAVE_AND_CLOSE_SHORT_DESC}"
actionlistener="#{TestCommentBean.saveAndClose}">
</af:commandbutton>
Note that you can achieve this linking declaratively using Property Inspector.

The Explanation

An application module can expose its data model of view objects to clients without requiring any custom Java code. This allows client code to use the ApplicationModule, ViewObject, RowSet, and Row interfaces in the oracle.jbo package to work directly with any view object in the data model.

Whenever there is a need to provide custom codes as shown in our sample application, you should encapsulate the details by writing a custom method in your application module's Java class.

When working with Fusion web applications using the ADF Model layer for data binding, JDeveloper configures a servlet filter in your user interface project (i.e., ViewController) called the ADFBindingFilter. It orchestrates the automatic acquisition and release of an appropriate application module instance based on declarative binding metadata, and ensures that the service is available to be looked up as a data control using a known action binding or iterator binding, specified by any page definition file in the user interface project.

At runtime, you can access the application module's client interface from the DCBindingContainer by naming an ADF action binding or an ADF iterator binding (see step 4). You can also reference the binding context[7] and call methods on the custom client interface in any JSF managed bean.

Reference(s)

  1. Most Commonly Used Methods in ADF Business Components
  2. A detailed look at Binding Model Parameter Options (NDOption)
  3. Oracle ADF Model In Depth
  4. Managed Beans in Oracle Fusion Web Applications
  5. Action Bindings and Method Bindings in Oracle ADF 11g
  6. Examining View Object Attributes in Oracle ADF 11g
  7. Oracle ADF BindingContext and BindingContainer
  8. Types of Memory Scopes in Fusion Web Applications
  9. Oracle Fusion Developer Guide: Building Rich Internet Applications with Oracle ADF Business Components and Oracle ADF Faces
  10. Open Source sample applications for Oracle Fusion Middleware technology
  11. Using Bind Variable to Implement Range Selection Declaratively (Xml and More)
  12. Book Review: Developing Web Applications with Oracle ADF Essentials (Xml and More)