Thursday Aug 06, 2015

Dynamic logging using the JDeveloper debugger

With the debugger integrated into JDeveloper, its quite easy to debug applications (either remotely or running inside the internal weblogic server) by single-stepping them and examining variables and method parameters after each step or when a breakpoint was hit. However, especially when setting a breakpoint on a method which gets called very often, it is a pain to continously press the "resume" button just to watch a specific parameter or member variable. It might be easier if we could simply log those values to the console, especially in early phases of debugging when we are still in the process of getting an overview of what happens. The usual approach is to insert System.err.println() calls at the appropriate locations, but this requires a redeployment of the application. More importantly, redeployment might even be impossible when remote debugging against a test environment where we can not redeploy at will.

Fortunately, JDeveloper allows to do exactly what we need, without modifying the source code. The below example uses JDeveloper 12c, but also works with 11gR1.

Lets assume we have an ADF application for which we want to track which application modules get released when we execute a specific action in the Web UI. The relevant method is oracle.jbo.common.ampool.ApplicationPoolImpl.releaseApplicationModule, so we start by adding a breakpoint on this method:

Even though we might not have access to the ADF runtime source code (customers with a support contract can get it through Oracle support), the debugger will now stop when the releaseApplicationModule() method is called for the first time.

When prompted for the source file, simply choose "Generate source code stub" if you do not have access to the source code. From the stub or from the JavaDoc, we know that releaseApplicationModule has cookie of type HttpSessionCookie as first parameter - even if we do not have access to the source code, we will still be able to inspect the method parameters once the breakpoint gets hit:

By navigating through the cookie parameter, we finally find a member which seems to store the application module name:

We now have the full path to a variable which stores the application module name when the releaseApplicationModule() is called: cookie.mInfoObject.mApplicationModule.mObjName

Lets edit the breakpoint which we set earlier again. On the "Edit Method breakpoint" dialog, select the "Actions" tab:

There, we need to uncheck the "Halt Execution" option, so that whenever the breakpoint is hit again the program execution is not halted. We also need to make sure that the "Log Breakpoint Occurrence" option is set (which it is by default), so that breakpoints are logged when they occur. Then, in the "Expression" field we enter the access path which we found out above. This expression will be evaluated each time the breakpoint is hit, and the result will be written to the console. Press "Ok" to close the dialog.

Now press the debugger's "Resume" button to resume program execution. You will see that, whenever the application calls the "releaseApplicationModule" method, it will not halt but continue running. However, each of the calls are logged on the console, together with the name of the application module which was passed inside the cookie parameter:

Monday Jul 27, 2015

Modifying the run configuration for the JUnit test runner

Sometimes it is necessary to set specific java properties or to add specific virtual machine options when unit tests are executed with JDeveloper's JUnit test runner. However, there is no separate option to modify the runtime environment for the test runner - it simply takes the active run configuration which is selected in the "Run/Choose Active Run Configuration" menu (which is by the way the case for any "Run..." and "Debug..." actions executed from context menus, e.g. on a ViewController project).

Adding a test execution specific run configuration (e.g. to add properties to enable logging) is therefore not different from adding a new run configuration for an application:

Select "Run/Choose Active Run Configuration/Manage Run configurations" and press "New" to create a new run configuration:

JDeveloper allows to copy an existing run configuration (e.g. "Default") as the basis. Press "Ok" to save the new configuration, then, press "Edit" to open the Run Configuration Editor:

Add some java properties, like -D to define a property or -X to define memory settings. Then press "Ok". Also press "Ok" on the "Project properties" dialog to close it.

The new run configuration is now available in the "Run/Choose Active Run Configuration" menu. To run the JUnit tests with this configuration, simply set it as active and launch the JUnit test.

Remember that this is now the active run configuration for all Run/Debug actions - you might want to reset it to "Default" or something else before launching your application the next time.

Andreas is an Applications Architect in the Oracle Fusion Applications group.
The intention of this blog is to explore, explain and elaborate Oracle ADF and Java related topics.


« August 2015