Saturday, July 25, 2009

Integration in Oracle ADF Through ADF Libraries and ADF Task Flows

Last year June, I was blogging about how to use ADF Libraries for calling remote ADF Task Flows - How To Call Remote Task Flow in JDeveloper 11g. Recently in our project we decided to split one big application into smaller ones and to create separate ViewController projects per each module implemented by Model projects. Splitting was divided into two steps - extract modules into separate ADF applications and then integrate all those applications back. Key requirement is to have one deployment archive, centralized security and at the same time to work on separate applications without any interruption. In order to implement this task, I decided to revisit ADF Libraries topic and actually I saw that in new JDeveloper 11g release integration can be implemented much easier than before. I will not focus in this post on ADF Libraries and ADF Task Flows description, you can check my older post for this. I will describe today how integration could be done now and one problem I faced (with solution of course :).

Developed sample application - ADFIntegration.zip, contains three ADF applications - LocalApp, RemoteApp and RemoteSecondApp. LocalApp acts as main application, where other two are integrated. I'm integrating two applications, because problem I faced is not reproduced in basic case - when integrating only one.

For overview purpose, main application contains one page and two ADF Task Flow calls defined. Its calling two integrated applications through ADF Task Flows:


You can see that two ADF Task Flow calls are just usual calls:


This means that we can integrated separate application through ADF Task Flow in so called plug and play way. Both ADF Task Flows are integrated through ADF Libraries generated from separate applications:


You can just drag and drop ADF Task Flow from ADF Library and it works fine - it can access your ADF BC, Bindings and Web pages. When libraries are added into your main application, you can see them listed under ADF Library definition:


And perfect news, when main application is starting, WebLogic loads all three DataBindings files (just provide different names for them and dont forget to update adfc-config.xml also). You can see from the log that DataBindings.cpx from main application is loaded first, then DataBindings from integrated libraries are loaded - DataBindings1.cpx and DataBindings2.cpx accordingly:


Along with DataBindings, all Page Definition entries are loaded.

Everything seems fine, but during integration in my project I have faced a problem (as usual :)). When loading one of ADF Task Flows from integrated application I got NullPointerException. I reproduced this in my sample, you can see it from the log:


From the first line of log, you can see that it tries to load RemoteModuleDataControl from DataBindings2.cpx file, which is incorrect - RemoteModuleDataControl is defined in first ADFLibrary, inside DataBindings1.cpx file. After some thinking, I saw in previous log message with DataBindings load order, that DataBindings2.cpx is loaded the last. This means, my integrated form was trying to use incorrect DataBindings.cpx file. I was even more sure about this, when I saw that form from second application was working, its because its based on last load DataBindings2.cpx file. At first I was thinking may be its Oracle bug, but then I found its actually was our bug - we were calling Application Modules from default Method Call activities in our ADF Task Flows directly, bypassing Binding layer. Let's describe a best practice how it should be done.

I fixed this integration error, by going to ADF Task Flow from application I was integrating:


I have opened selected ADF Task Flow and it looks like this - Method Call is defined as default activity, and it was cause of problem. We are using Method Calls as default activities, because we are invoking specific actions before opening page, I believe its common requirement:


I have checked what is invoked from this Method Call - its Backing bean method:


Then I opened this method and I saw it calls Application Module directly, bypassing Bindings layer - which is bad practice. We always should access Application Module through Bindings in ModelViewController type applications. Bad practice example:


In general, we should get DataBindings and invoke method from Application Module, this method also should be defined in Page Definition. However, in this specific case, we even don't need method in Backing bean. Better we can declare Method Call through Binding layer in ADF Task Flow directly:


Separate Page Definition file was created for this Method Call and action from Application Module defined:


We are invoking custom method from Application Module using Method Call declared as default ADF Task Flow activity:


After fix, don't forget to redeploy ADF Library, main application will pick-up changes automatically. On runtime, when opening form from first integrated ADF Library, correct DataBindings1.cpx is loaded now:


Form screen from integrated application is successfully loaded:


It seems, application splitting and integration is pretty good in latest JDeveloper 11g release.

12 comments:

Chris Muir said...

Excellent post Andrejus, great work.

Andrej Baranovskij said...

Thanks Chris !

Unknown said...

Andrejus

Thanks for this excellent example. One question - how do you change the name of the databindings from the default value of databindings to show as databindings1, databindgings2 etc. Appreciate your guidance.

Thanks
Ram.

Andrej Baranovskij said...

Hi Ram,

To change name follow those steps:

1. Change physical name for DataBindings file

2. In DataBindings file, change its ID property in header - id="DataBindings1"

3. In adfm.xml change DataBindingRegistry path="lt/andrejusb/view/remote/DataBindings1.cpx" property accordingly

Regards,
Andrejus

Unknown said...

Thanks for the prompt response.

We will give it a try.

Thanks
Ram

spido said...

Really great work Andrejus!

Here something regarding the method call that broke your splitted app.

http://developers2developers.blogspot.com/2009/09/accessing-adf-client-interface-in-jsf.html

Andrej Baranovskij said...

Hi Spido,

Thanks for working on this !

Andrejus

minarti said...

hi Andrejus,
I have aplication like this. When I run in windows, it works well. But when I run it in redhat, not work well at all. I have a master-detail page. When I add detail and save, data will be saved to database, but all of detail data is not visible (detail will be empty) and I can't add data anymore except I refresh the page.
Have u facing problem like that?
Thanks..

Andrej Baranovskij said...

No I'm not. Most likely on linux server you have different version of ADF runtime, it doesn't match your development environment.

Andrejus

minarti said...

Hi Andrejus.
I trying to run my application in linux again.

And now, it's work well. I'm so confuse about this, because a week ago when I run this application, it's not work well when I tried to addrow detail and save it.

Do you hve any idea?

Thanks,

minarti

Unknown said...

Hi Andrejus,

Excellent post about integration of two Applications.

I just followed this post to integrate two applications.
my requirement is to use remote application task flow as fragment in local application as region.
while trying this facing an ADF Error
ADF: Adding the following JSF error message: Configuration AppModuleLocal is not found.
oracle.jbo.ConfigException: JBO-33005: Configuration AppModuleLocal is not found.

pls give me a suggestion to solve this issue


Thanks & regards
Amar

ravi said...

Hi

i renamed Databindings.cpx file to DataBindings1.cpx ,
and i configured new cpx file name in adfm.xml file

but problem is when i create new .jspx page in portal application then jdeveloper creating a new DataBindings.jspx along with .jspx file in portal


can u guide me how to avoid this one