Saturday, March 19, 2011

Exception Handler for Method Calls inside ADF Task Flows with Pages

I have described specifics of handling exception for ADF Bounded Task Flows with Fragments - Exception Handler for Method Calls inside ADF Task Flows with Fragments. We will look today what are the differences when using ADF Bounded Task Flows with Pages.

Download sample application - MethodCallExceptionHandler2.zip. This sample contains only pages, no fragments. We can press Process Data button to simulate JboException in Method Call activity:


In this case, our application will crash completely:


Process Data button invokes Method Call activity from ADF Bounded Task Flow:


In order to handle JboExceptions, ADF Task Flow Template should have Method Call activity marked as Error Handler:


Make sure your ADF Task Flow is based on ADF Task Flow template with Error Handler activity defined:


Error Handler Method Call activity invokes Java method from Managed Bean, where catched exception can be logged and reported. Its a difference with ADF Bounded Task Flows based on fragments, exception data is shown inside popup automatically. But for ADF Bounded Task Flows based on pages we need to show error popup manually:


There is no browser error anymore, instead user is informed with popup message:


31 comments:

Saurav Kumar said...

Hi Andrejus,

This is a very useful post.
We are developing applications based on Fusion framework. I am trying to implement similar 'error handler taskflow template' in my application. But the error handler task flow is never invoked.

I am getting following exception 'javax.el.ELException:

java.util.EmptyStackException ADF_FACES-60097:For more information, please see the server's error log for an entry beginning with: ADF_FACES-60096:Server Exception during PPR, #2' in UI popup.

I followed the same approach as you mentioned in this blog. It would be great if you can point me why the error handler task flow is NOT invoked.

Thanks,
Satya

Andrejus Baranovskis said...

Hi,

Can you send me sample app with reproduced problem?

Andrejus

Achinto Banerjee said...

Hi Andrejus,

I noticed that when using methodAction binding from a view the error handler is not called . But in case of method-call activity Error handler is .

Is it required that for error handler to work one must use method call activity . Could not find anything on this in the FMW documentation.

Though found one post in OTN http://forums.oracle.com/forums/thread.jspa?messageID=9562603

Regards,

Achinto

Andrejus Baranovskis said...

Hi,

Yes its how it should be. This blog post describes ADF Controller error handler functionality. It handles all errors encountered in ADF Task Flows.

If you want to handle errors from bindings, you need to define DCErrorHandler class and register it inside DataBinding.cpx file.

Andrejus

Achinto Banerjee said...

Thanks for the quick response Andrejus. Eager to try it out . If you have some sample app or link to it will certainly help .

Achinto

Andrejus Baranovskis said...

You can read these links:

http://radio-weblogs.com/0118231/2008/01/21.html

http://jobinesh.blogspot.com/2011/03/customizing-business-components-error.html

Andrejus

Achinto Banerjee said...

Hi Andrejus,

In our case we basicaly want to catch the exception triggered in the task flow . The DCErrorHandler class catches the exception in bindings defined .

But I am mostly interested in scenario in which I have following code in the view of the taskflow.



Note that myBackingBean given above is a backing bean(pojo) in the ADF Taskflow in the controller project . The method process() in the backing bean is something throws exception .

public String process(){
//stub to generate exception
Object obj = null;
obj.toString();
}

Now note that if I have another button in the taskflow calling the same process method via navigation case defined in task flow the error is caught by the exception handler (as is demonstrated in this blog post) .

But in the first case where I am binding using action=#"myBackingBean.process" the error handeler is not called and error is shown in windows popup.

Also, have tried extending the Extending the ADF exception handler . http://blogs.oracle.com/jdevotnharvest/2011/03/extending_the_adf_controller_exception_handler.html . But here the flow comes to the Overridden exception handler but not able to redirect only the errored out taskflow to the error page rather redirection happens at a page level (and considering the page is dashboard having multiple task flow and only one erroring out and rest working fine) which does not suit us .

Andrejus Baranovskis said...

Ok, in this case - such error is not handled by ADF Task Flow, because error doesn't happen in Controller but inside your EJB bean class.

Its out of scope of framework to catch such errors. You can either use Java try catch mechanism or extend ADF Fatal Error Handler (as you mentioned from blog URL).

If you still want such error to be handled by ADF, you must generate Data Control on top of your EJB and declare managed bean method inside Page Definition.

Then you would be able to use ActionListener=#{bindings.YourMethod.execute}. If error will happen, Bindings layer should handle it in such case.

Andrejus

Achinto Banerjee said...

Point taken . But what if I simply have a managed bean in ADF and call it using action = "#{managedBean.process}" and the process method throws unhandeled exception . The exception handeler does not get called . It gets called though when
action ="navigationAdfCallingProcess" .

Basicaly , while selecting an action in the view in Jdeveloper I have a choice of either selecting method binding or Action outcome. The exception handeler works with action outcome(method call) but does not work with method binding thorws a popup(same managed bean method called in method call).

Would it be fair to assume that for exception Handler to work we would need to replace all the method binding to action outcome .

Overriding the Exception handler seems to be the only way out which called in all the scenarios (but does not fully satisfy our req)

Andrejus Baranovskis said...

Yes, its possible option, to invoke all actions through ADF Task Flow navigation. But I guess, sometimes there will be situations it will be easier to call managed method directly.

I would recommend to keep healthy balance between Java try/catch and Controller error handling.

Andrejus

Anonymous said...

Hi Andrejus,

Would it be possible of you to document (for the use of general ADF Community) as per your extensive experience, under what scenarios we would we need to call managed beans methods directly from the action source component ?

In our project we do not want the developers to use managed beans method calls directly as this would violate the the layered design pattern of MVC. We always bind to the model layer through bindings right ?

Andrejus Baranovskis said...

You should call managed bean methods directly from action or action listener. Only that exceptions will not be handled by controller automatically. In terms, of design there is no violation in ADF to call managed bean method from action or action listener directly.

Andrejus

Debojit Sinha said...

Hi Andrejus,

I'm attempting to reproduce your scenario, but the method-call activity is getting flagged with an error: Required child (parameter|return-vaue|outcome) is missing from element method call.

Could you please provide some insight?

Regards,
Debojit

Andrejus Baranovskis said...

Did you specified return outcome from method call?

Andrejus

Achinto Banerjee said...

Hi Andrejus,

This might not be the right blog to ask . But just wondering if you could give your expert guidance on an issue related to ADF loopback scripts .


The same has been posted on the oracle forums but haven't had any response .

https://forums.oracle.com/forums/thread.jspa?messageID=9844347#9844347

Andrejus Baranovskis said...

Its a bit hard to answer on your question 100% right, because its touching internal ADF things. I would suggest to ask Oracle Metalink, to confirm officially regarding ADF script loopback disabling.

Andrejus

Debojit Sinha said...

No, it seems that I didn't.
Since the method didn't have any control flow exiting it, so I didn't think an outcome would be necessary. I've added one and it's working fine now.

Thank you,
Debojit

Juan said...

Hi Andrejus.

Great post.

Your scenario works fine. But in my case, I need to assing a page redirection when the user clicks on the button of the pop up.

Do you know how to make this functionallity?

Thanks

Andrejus Baranovskis said...

Hi,

Most probably instead of using JSF popup, you need to use your own popup and handle navigation from dialog listener.

Andrejus

Anonymous said...

Hi Andrejus,

Did you ever tried such one Exception handler in case of bounded task flow (full page based) running in a modal dialog ?

A have use case, in which default (first)activity (setCurrentRowWithKey) causes RowNotFoundException. The exception handler (backin bean method which return String)gets control as expected, but then I am stuck with empty modal dialog, with message in a WebLogic console :

Could not queue return event: no launch source

This is a strange, because I am invoked task flow from toolbar button as a launcher...

Thanks in advance,
Cvele

Andrejus Baranovskis said...

It might be ADF bug related to ADF Modal dialog and TF. Please log it on our public Wiki: http://redsamoracle.wikispaces.com/

Thanks,
Andrejus

Anonymous said...

Thanks for response.

Did you reproduced such one behaviour ? What I want, is to simply return from task flow when Exception occurs.
In any case, I will log it on Wiki...

regards, Cvele

Andrejus Baranovskis said...

No, I was not reproducing such behavior myself yet.

Thanks for logging on wiki.

Andrejus

Phuu Tek said...

Hi Andrejus,

I just wonder.

Will this code still work if your backend is a web service?

Assume you are just displaying a list of employees from a web service.

Will the method call marked as error handler still be able to handle such exception?

Thanks,
Phuu

Andrejus Baranovskis said...

Yes, it should handle it, if your Web Service is called through ADF bindings.

Andrejus

MG2 said...

Andrejus Hello, I try to implement the solution you type in the post but I have not been successful, my task-flow type are page fragments not know if this has anything to do but I can not my method is invoked to handle the exception

Amit Surve said...

Thanks for the post, Andrejus.

I was getting currentRootViewPort.getExceptionData() as NULL. So, I had to use this following alternative:

Exception exceptionData = currentRootViewPort.getExceptionData();
if (exceptionData == null) {
ViewPortContextImpl viewPort = ControllerState.getInstance().getCurrentViewPort();
exceptionData = viewPort.getExceptionData();
}

Hope this is useful.

Anonymous said...

Hello Andrejus,

Thanks for nice example.

I came from Java background and we used to write something like below for exception handling in Java (Jsp->Servlet->DbLayer)

In Db Layer

catch SQLException
throw ServletException

In Middle Layer(Servlet Layer)

catch ServletException
throw UIException

In UI layer we used to show msg from a text file using ResourceBundle.

Now here I can see, you are using a bounded taskflow template.

My questions here is, in order to understand specific problem, you need to first understand which layer is throwing this exception. In a big application this is very important. Where do I need to concentrate, in order to push this code (your example code) to production?

Mohammed AlJasim said...

nice post,,
i have a question ?
how to handle max sessions reached for application in memory session max limit when reached,

how to show a user friendly page or message instead of the error stack
like """ Error 500--Internal Server Error

weblogic.servlet.SessionCreationException: Cannot create new sessions as the MaxInMemorySessions limit (100) has been exceeded"""

thanks

Don Kleppinger said...

We had a fragment based task flow running in a popup using a bean data control that would validate required input fields and throw JboException for errors which would then display in a popup message. This worked fine on jdev 11.1.1.4 but when we upgraded to 11.1.1.7 the messages no longer displayed. I has to use your technique to make the messages display again exception I had to call getCurrentViewPort instead of getCurrentRootViewPort because the root view port didn't have any exception data.

Andrejus Baranovskis said...

Yes, I had a comment about it on another post: http://andrejusb.blogspot.lt/2011/03/exception-handler-for-method-calls.html (in comments).

Thanks,
Andrejus