Today I will talk more about best practices, not about technical problems. From what I saw, especially new ADF developers, frequently are experiencing problems with handling JboExceptions. Its not about how to throw JboException, but about how to invoke method that throws it.
Download sample application - JboExceptionPropagation.zip. This sample implements two approaches about how to call custom method from the Model layer. Custom method is simple, it just throws JboException in both cases:
Method that I'm calling from managed bean, is implemented and exposed through Application Module client interface:
It simply throws JboException:
This custom method is declared in Page Definition Bindings, to make it available for the client:
Now most important part of this blog - how we invoke custom method defined in Application Module implementation class:
First function calls custom method correctly - through bindings. In case of JboException in that custom method, framework will raise error popup automatically.
Second function is accessing Application Module Implementation class directly, bypassing bindings layer. In this case, if developer forgets to catch thrown JboException - server error will appear and application will be broken.
So, always call custom methods from Application Module interface through bindings layer.
Hello Andrejus,
ReplyDeleteAll your posts are useful, great effort.
I have question
which better calling custom method through binding layer or by bypassing it and create instance of Application module in backing bean?
Regards
Karim
Hi Karim,
ReplyDeleteAs per blog entry, it is better to call custom method through binding layer.
First, it is wrong ADF practice to bypass binding layer and create instance of Application Module in backing bean.
Second, JboExceptions are not catched automatically, if you bypass binding layer.
Regards,
Andrejus
This is a nice little demonstration.
ReplyDeleteHi....First button click is generating stack trace error message on the console....I want to handle that..Please let me know about it....
ReplyDeleteYou can handle it with ADF error handling inside DCErrorHandler class. What is specific issue?
ReplyDeleteAndrejus
Hi
ReplyDeleteI have just downloaded your application and try it to run on my machine....then of course it is generating pop-up alert but it is also generating stack trace message on the console.....I want to handle that stack trace message...Can you please provide with that type of working application...
I tried to do it with DCError handler class...but it is not getting handled...
ReplyDeleteTry those posts:
ReplyDeletehttp://andrejusb.blogspot.com/2011/03/exception-handler-for-method-calls_19.html
http://andrejusb.blogspot.com/2011/03/exception-handler-for-method-calls.html
Andrejus
Hi already have tried these two examples....and facing same issue ...that is not able to handle stack trace....please you try it at your end...
ReplyDeletePlease send me detail screenshots and steps to reproduce your problem. I can't help you on so abstract question.
ReplyDeleteAndrejus
Hi
ReplyDeleteHow I can send the screen shot....I am not able to find any option on this site to send the image..
I sending the details of the exception that I am getting on the console....
racle.jbo.JboException: Data Processing Failed
at com.redsamurai.model.HrModuleImpl.processData(HrModuleImpl.java:30)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at oracle.adf.model.binding.DCInvokeMethod.invokeMethod(DCInvokeMethod.java:638)
at oracle.adf.model.binding.DCDataControl.invokeMethod(DCDataControl.java:2136)
at oracle.adf.model.bc4j.DCJboDataControl.invokeMethod(DCJboDataControl.java:3063)
at oracle.adf.model.binding.DCInvokeMethod.callMethod(DCInvokeMethod.java:261)
at oracle.jbo.uicli.binding.JUCtrlActionBinding.doIt(JUCtrlActionBinding.java:1635)
at oracle.adf.model.binding.DCDataControl.invokeOperation(DCDataControl.java:2143)
at oracle.jbo.uicli.binding.JUCtrlActionBinding.invoke(JUCtrlActionBinding.java:740)
at oracle.adf.controller.v2.lifecycle.PageLifecycleImpl.executeEvent(PageLifecycleImpl.java:394)
at oracle.adfinternal.view.faces.model.binding.FacesCtrlActionBinding._execute(FacesCtrlActionBinding.java:252)
at oracle.adfinternal.view.faces.model.binding.FacesCtrlActionBinding.execute(FacesCtrlActionBinding.java:210)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at com.sun.el.parser.AstValue.invoke(Unknown Source)
at com.sun.el.MethodExpressionImpl.invoke(Unknown Source)
at oracle.adf.controller.internal.util.ELInterfaceImpl.invokeMethod(ELInterfaceImpl.java:168)
at oracle.adfinternal.controller.activity.MethodCallActivityLogic.execute(MethodCallActivityLogic.java:160)
at oracle.adfinternal.controller.engine.ControlFlowEngine.executeActivity(ControlFlowEngine.java:989)
at oracle.adfinternal.controller.engine.ControlFlowEngine.doRouting(ControlFlowEngine.java:878)
at oracle.adfinternal.controller.engine.ControlFlowEngine.doRouting(ControlFlowEngine.java:777)
at oracle.adfinternal.controller.engine.ControlFlowEngine.routeFromActivity(ControlFlowEngine.java:551)
at oracle.adfinternal.controller.engine.ControlFlowEngine.performControlFlow(ControlFlowEngine.java:147)
at oracle.adfinternal.controller.application.NavigationHandlerImpl.handleAdfcNavigation(NavigationHandlerImpl.java:109)
at oracle.adfinternal.controller.application.NavigationHandlerImpl.handleNavigation(NavigationHandlerImpl.java:78)
at org.apache.myfaces.trinidadinternal.application.NavigationHandlerImpl.handleNavigation(NavigationHandlerImpl.java:43)
at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:130)
at org.apache.myfaces.trinidad.component.UIXCommand.broadcast(UIXCommand.java:190)
at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:475)
There is email in about blog section.
ReplyDeleteWhich sample you are running - one with pages, or one with fragments?
Andrejus
One with pages....Although...one with fragment is also generating the same stack trace ...
ReplyDeleteStack trace will be generated always, only in addition you can intercept error in DCErrorHandler. But you cant hide stack trace.
ReplyDeleteAndrejus
Of course, unless you will do try/catch in Java code.
ReplyDeleteAndrejus
Here is code where exception is catched, in case of pages: https://lh5.googleusercontent.com/-Ev7aqW3NaKM/TYUPEwJ0lGI/AAAAAAAAE6k/_T9n3Uy27Kw/s1600/6.png
ReplyDeleteAndrejus
But if we are using try catch in application module then also ...it is generating stack trace.....
ReplyDeleteWhat I can say, if you say so :-)
ReplyDeletepublic void processData() {
ReplyDeletetry{
int a=10/0;
}catch(Exception e){
throw new JboException("Data Processing Failed");
}
}
The code is generating stack trace....now please let me know....
But if I remove line throw new JboException("Data Processing Failed"); then no exception is generated...
Yes, thats how it works. Because we are doing throw new JboException("Data Processing Failed"); then ADF reports stack trace. From ADF Model layer we are throwing to ViewController. Thats normal behavior.
ReplyDeleteIf you dont want to throw exception, you can just log it in catch block and not re-throw.
Andrejus
Then how we will let the user know that the what kind of exception has occurred...??
ReplyDeleteI want the use to navigate to different screen on occurence of exception..
Just define Error Handler activity (page) on ADF Task Flow, and you are done.
ReplyDeleteAndrejus
please explain it in detail....I am able to navigate to different screen but not able to hide the stack trace...
ReplyDeleteYou will not hide stack trace, I already explained it.
ReplyDeleteAndrejus
Thanks a lot for your co-operation......means there is no way to hide stack trace...
ReplyDeleteBut I am able to do it when I am writting my own custom functions .....in managed bean....
public void arthException(ActionEvent actionEvent) {
try {
int a = 10 / 0;
}
catch (ArithmeticException e) {
System.out.println("Exception thrown..." + e);
throw new JboException("Arithmetic Exception", "ARTH", null);
}
}
and is able to navigate to appropriate screen by passing ARTH object error code in adf-config. with out stack trace message..
Thats because in your example JboException is thrown from ViewController itself, framework is not registering it. However when you throw from Model, then its different.
ReplyDeleteIts common practice to show stack trace error.
Andrejus
Ther exception which is generated is not able to reach the following code in my application....please let me know what I can be missing..??
ReplyDeletepublic TaskFlowId getDynamicTaskFlowId() {
ControllerContext context = ControllerContext.getInstance();
ViewPortContext currentRootViewPort = context.getCurrentRootViewPort();
Exception exceptionData = currentRootViewPort.getExceptionData();
if (currentRootViewPort.isExceptionPresent()) {
exceptionData.printStackTrace();
currentRootViewPort.clearException();
TabContext.getCurrentInstance().removeCurrentTab();
List tabs = TabContext.getCurrentInstance().getTabs();
for (int i = 0; i < tabs.size(); i++) {
TabContext.getCurrentInstance().removeTab(i);
}
return TaskFlowId.parse(taskFlowIdError);
}
return TaskFlowId.parse(activeTaskFlowID);
}
if (currentRootViewPort.isExceptionPresent())
this statement is returning false on presence of exception also....
I am trying for fragments case...
What is the best practice, if I want to commit the transaction after invoking the operation. I want that the transaction i committed or rolled back depending on whether the operation was successfully called.
ReplyDeleteYou can implement your custom method in AM impl class with try/catch. Rollback in catch block.
ReplyDeleteAndrejus
Hi,Andrejus.
ReplyDeleteI have used listofcombobox we enter wrong data error come from frame work like error is : Invalid values: sssss . my case i want override error message its possible.
kindly help me.....
Thanks
Hi,
ReplyDeleteWhat if we customize DCErrorHandlerImpl to display custom error but for same error we want to show different msg according to different page. How can we achieve this for jsff page in dynamic region ?
Hello Andrejus,
ReplyDeleteI have implemented database commit as AMImpl client interface and doing rollback in bean catch block if JBO error is thrown.
If any JBO error occurs, the page becomes invalid and I need to rerun the page to perform other operations. Can you please let me know how can I completely rollback the changes and continue with the current transaction.