Nested Application Modules

Send me a mail
 Dive into Oracle ADF   Click to see the XML version of this web page.   (Updated: 2/3/2008; 9:26:10 PM.)
Tips and tricks from Steve Muench on Oracle ADF Framework and JDeveloper IDE

Nested Application Modules

I got a question today from a user:

Is it possible/valid to call one application module from another, i.e. nesting application modules?  We're currently building the core components for our solution using ADF and want to keep the AMs small with logical functional groupings.  Several "root" AMs may access the same core AMs, e.g. to create a widget.  We don't want to duplicate this core logic in several root AMs.  So we'd have something like this:

Is this valid or does it break the model? Any views on approach, performance implications etc...


Nested application modules are a built-in feature and are used for exactly the kind of service component reuse that this user is envisioning. It is (service) component reuse at it's easiest.

You can nest an instance of an application module inside another application module in one of two ways:

  • Declaratively, at design time:

    In the application module editor (for the enclosing AM you're define that wants to include a nested instance of another AM), on the "Application Modules" panel of the editor, just shuttle any other AM into the list of selected (nested) AM instances, and adjust the instance name as desired. This is declaratively configuring the application module's XML component descriptor so that at runtime the framework will "inject" an instance of this dependency (in this case, an AM bean instance) for you without writing code.
  • Programmatically, at runtime:

    The oracle.jbo.ApplicationModule interface has the createApplicationModule() method to create a new nested application module instance based on the fully-qualified name of the application module definition (e.g. com.yourcompany.yourapp.model.SomeAMName) and allows you to assign an instance name.

An AM is a transactional container of VO instances and/or nested AM instance. The application module at the root of this hierarchy is known as the "root" application module, and it's the resource that is pooled in the application module pool. The nested instances of View Objects and nested instances of (other) Application Modules that are contained by this root AM are simple, lightweight javabean components. In fact, even the root AM itself is a simple, lightweight javabean component. The only thing that the "root" AM has at runtime that distinguishes is from other AM's is that as the top of the component hierarchy, it hangs onto the reference to the transaction as shown in Figure 1 of the Most Commonly Used Methods in ADF Business Components whitepaper.  The nested components automatically participate in the root AM's transaction.

The nested instances of VO and AM beans are conceptually no different from any other beans with nested bean instances. Think of the AM as having a Map of nested components that it contains, each keyed by its instance name. This set of ("InstanceName",VO-or-AM-Instance) pairs, are the nested instances. You can use the findViewObject() and findApplicationModule() methods on the oracle.jbo.ApplicationModule interface to find a component by its instance name. There are other methods to give you a list at runtime of the nested instances of VO's and AM's that a given application module contains in case you're writing generic framework code that might benefit by that kind of runtime discovery capability.

One interesting point is that when you nest an instance of application modules, you begin to create a hierarchical namespace of instance names for your view objects. Here's a quick example. Suppose you have two application modules:

  • com.mycompany.myapp.InventoryManager
  • com.mycompany.myapp.CustomerManager

And suppose that InventoryManager nests an instance of CustomerManager with an id (a.k.a. instance name) of "CustMgr". If the CustomerManager application module contains a view object instance named "CustomerList" then the following code would find the CustomerList view object from the outer inventory manager:

ApplicationModule inventoryMgr = /* Assume we have an inventory manager instance */
ViewObject customerList = inventoryMgr.findViewObject("CustMgr.CustomerList");

Of course, this is just a slightly more convenient way of writing code like the following:

ApplicationModule inventoryMgr = /* Assume we have an inventory manager instance */
ApplicationModule customerMgr = inventoryMgr.findApplicationModule("CustMgr");
ViewObject customerList = customerMgr.findViewObject("CustomerList");

But it's nice to know that there's a simpler way to do it.

ADF Data Binding works with nested application modules as well. You'll see the nested service component indented beneath the nesting application module, and you can expand it to see its contained view objects.

The nesting is not limited to a single level, so you can use nested application modules as you see fit. At runtime the creation of nested instances of application modules (the same as for View Objects) boils down to a first-time metadata lookup (once per VM) and then a java bean creation, so it's not prohibitively expensive to use nesting.

 



© Copyright 2008 Steve Muench. Click here to send an email to the editor of this weblog.
Last update: 2/3/2008; 9:26:10 PM.