Monday, March 16, 2015

ADF code review (crime #1)

Doing code review is like reading a mystery novel. You always wander why… and you rarely find logical answers.

An example of ADF code in managed beans:
            try {
                OperationBinding ob = ADFUtils.findOperation("Rollback");
                ob.execute();
            } catch (NullPointerException npe) {
                //Probably due to being the first time... no worries.
            }

Why would someone want to hide such an exception?

And then you check the ADFUtils. findOperation method:

    public static OperationBinding findOperation(String name) {
        OperationBinding op = getDCBindingContainer().getOperationBinding(name);
        if (op == null) {
            throw new RuntimeException
("Operation '" + name + "' not found");
        }
        return op;
    }


And you see that NullPointerException will never be thrown since it is overridden with a  RuntimeException.

In any case, if there is no operation in the binding it is a development bug. Why would someone want to hide it?

One more unresolved crime…

Monday, February 2, 2015

One Application Module to rule them all?

I was called to help on an ongoing ADF project
There were only one application module.
It is live in production for the past 2 years with around 20000 concurrent users at peak times
It has around 200 view instances.


So I ask:
Me: why only one?
Response: In order to have just 1 connection per user.
Me: Ok, but that could be done by other means
Response: Ok but if not one, how many? Why not only one?

...I had seen various posts in the net, so I took a look again.
I see an old post from Frank that actually suggests one root application module and many nested.

I also see a more resent episode on ADF Architecture TV from Chris.
He states that this is a wrong question and depends on the requirements but actually implies that in most cases it could be done with only one root application module and Task flows transaction management.

So, why not only one root application module (even with many nested)?
It seems to me similar to the question ‘why not only one java class (even with many nested classes)’.
Apart from the obvious:
  • The additional ‘Shared’ module that is suggested for static lists for better performance
  • The Implementation class of the module that will be huge.
  • The frustration to find out which view objects are used in which cases.
  • The  conflicts resolution when many developers works on the same module
Some additional reasons in order not to use only one Application Module
  1. Heavy Rollback operation. When rollback is performed all initiated view objects of the application or nested application modules are requeried by default.
  2. Heavy passivation - activation. Similar to rollback all initiated view objects will be passivated-activated by default.
  3. Handle errors after post. In order to handle errors after posting data there is an application module parameter bo.txn.handleafterpostexc. When this parameter is set to true then the related application module performs passivation before each transaction in order to perform activation in case of exception. I am not sure how and if this works on nested application modules.
  4. In case you want to expose some functionality as web services, a single Application module will create a single web service that will be heavy and coupled. I am not sure how this work with nested application modules.

Alternatively I have used the following approaches with numerous application modules and minimizing the database connections at the same time:
  1. The ‘do connection pooling’ approach
  • 300 root application modules
  • No Task flow transaction management 
  • Set application module properties: jbo.doconnectionpooling="true" and jbo.txn.disconnect_level="1"
With this setup we had less than 5 active connections for 100 concurrent users in production. 

According to the documentation this has a performance overhead for getting and releases the connection each time an application module use it. Yet it is recommended when minimizing the database sessions is a priority.
       
       2.  The ‘Use existing transaction’ approach
  • numerous root application modules
  • Task flow transaction management with a main task flow that always start a new trasactions and regions that ‘Use existing transaction if possible’
  • The main task flow has one application module that logicaly is used as root, the regions have other application modules that are automatically nested according to usage.
This setup has typically 1 connection per user. Caution is needed on commit and rollback in order for the transaction not to be lost from the main task flow (i.e. use DataControlFrame commit and rollback)

So in my opinion it is not a good practice to have only one application module unless you have only 1 simple business use case.

Monday, December 29, 2014

More than a year without a post.

I just realized than it’s been more than a year without a blog post.
No I haven’t stop working on fusion technology. It’s probably because I work more….
I have 5 versions of jdevelopers in my pc. One for each different project.

It’s a confusion to work on so many different versions of jdevelopers. There are differences in behavior and in design time that you need to cope with. So why do different projects need to be in different jdeveloper’s versions?

Mostly because older projects are in production and even though enhancements and second project phases are in development, the cost to migrate to newer jdeveloper versions is high.

Also jdeveloper versioning is a little confusing, since most 11.1.2.X versions are older than 11.1.1.6 and 7 versions.
11.1.2.X versions were the first versions using JSF2 yet they don’t have SOA or BPM.
In my opinion 11.1.2.X versions should not have been used for live projects. If you check the quantity and quality of bugs fixed in the release notes of later versions you would agree.

Even jdeveloper 12 versions did not have SOA and BPM until the latest release 12.1.3 release on June 2014.
So it seems like a good time now to push our customers to 12c migration within 2015.

I wish you all a happy new year.

Saturday, July 13, 2013

ADF-BPM Integration: Custom Worklist.

A custom worklist is something commonly required from customers that use both ADF and BPM.
There are some user tasks that must go through a BPM process and other tasks that are performed directly.
So usually in the ADF application a worklist to display the BPM Tasks is required.

Oracle fusion gives many options to approach this and this can cause confusion.

Direction 1
My first approach some years ago was to use the exposed task flows of the BPM worklist:
See Oracle® Fusion Middleware Developer's Guide for Oracle SOA Suite,
32.13 Creating Reusable Worklist Regions
Some features available in worklist are exposed as standalone reusable components that can be embedded in any application. Moreover, these standalone task flows provide many customizations through parameters that enable you to build and customize a worklist application to meet requirements.’
The first attempt looked impressive to the moment that I tried to perform some customizations. The parameters are not well documented so I was using the trial and error methodology.
I could not customize it enough…see http://adfbugs.blogspot.gr/search?q=worklist
Also there was no way to override any of the worklist functionality (e.g add a link to another ADF task flow)

Direction 2
So we went ‘by the book’ and used the java api as described in the next chapter of Developer's Guide
33 Building a Custom Worklist Client

Along with some help from RedStack posts we managed to create the worklist we needed
http://redstack.wordpress.com/worklist/

Direction 3
Yet by reaching the next chapter of the Developer’s Guide
34 Introduction to Human Workflow Services
you see that there are also web services exposed to query and edit human tasks.
I though, why to use the java api and so many libraries? After all we are doing SOA and we should use the web services to create the custom worklist, and to update human tasks from ADF.
First I tried the easy way, to directly create data bindings from TaskQueryService web service. The result was the following:

I could not manage to create the correct structure of the input parameters in order to call the web service. Especially the ‘Predicate’ iterators were a nightmare.

So I tried a web service proxy:


A lot of types are created, similar but not the same with the java api and I managed to create and pass the correct parameters for the web service to run and return the Task list.

One issue was that the dates was exposed as iterators in the bindings?!

Yet the show stopper was that the Task type created from the web service do not have the getPayloadAsElement and setPayloadAsElement methods as the Java Api has. I did not find any way to update the human task payload from the web service.

The bottom line is that even though there seems to be 3 directions, only the second, seems to be the safe way to go for now.

Friday, April 5, 2013

New (11.1.1.7) Oracle Fusion release



Sorry for the long time to post.

I would like to say that i was very bussy but that could hardly describe it.

New full fusion version (11.1.1.7) is released from oracle this week.
this is mostly a bug fixing and new features releases (not the technology upgrade).

I guess that the 12c full fusion technology upgrade is not expected soon (may be at end of the year)

I see some interesting new features in release notes of jdeveloper:

Also there seems to be many additional features in BPM:

See also a great post of Chris about Why to migrate to this version:

I will evaluate our applications in the new release and let you know.

Wednesday, December 12, 2012

ADF Table Click to Edit functionality

I haven't been posting lately, i feel sorry for that.

This is mostly because i am up to my head with new projects, BPM, SOA, BI and other fusion middleware technologies. Also because:
  • we are using Jdeveloper 11.1.1.6 that is stable
  • we are using more or less the well known functionality
  • end users have started to get used to ADF functionality
 Still we need to keep walking, so i keep an eye from time to time, on the latest jdeveloper version 11.1.2.3.0 and functionality that we don't frequently use like the  ADF Table 'Click to Edit'.

Actually its a fancy functionality that make the table look nice and works fine with navitating either with mouse or by 'Tab' or arrows.
It is easy to implement, just set editingMode="clickToEdit" in editable ADF table.

everything works fine apart from the Date picker that does not work in Firefox 17 and it is not related with click to edit functionality (see forums.oracle.com )

Everything work fine until you press CreateInsert button.
Then a new row is inserted and highlighted yet it is not editable, the previous selected row is editable.


If you click on any other row by mouse nothing happens, rows don't become editable.
Arrows navigation don't work and If you try to navigate with tab it never go to the new row.
So the only applicable action is to click with mouse in the new row.

If you make a mistake not to fill the required fields and click on a different row, then validation errors appear as expected.
After that if you press rollback, even if it seems that the table is back to normal some rows are not editable any more when you click on them.
Sometimes rows display as duplicate on the table with these steps.
So it seems that click to edit functionality does not work properly for newly created rows on editable tables.
What we do to override this is that we create a popup dialog for new row data to be inserted and committed before they are editable in the table.

Test Case

Tuesday, July 24, 2012

Focus is Lost in IE8 when value is changed in Input List of values

New bug in Jdeveloper 11.1.1.6 version. It was not reproduced in 11.1.1.4.
It also happen only in Internet Explorer 8, not in 9 and not in Firefox.
When a value is selected or typed in an Input List Of values then the focus (cursor) goes to the internet explorer tab. This causes frustration to user's and delay in data entry.
Details in java.net/jira/browse/ADFEMG-31