Skip navigation.

Andrejus Baranovski

Syndicate content
Blog about Oracle technology
Updated: 4 hours 35 min ago

Oracle BPM 12c Installation Improvements and Issues with Mac

Sat, 2014-07-26 10:13
Oracle BPM 12c is improved with a great installation process - simplified and stable. You only need to download single installation package, run a wizard and after several clicks it gets installed. All required products are installed for you out of the box, no extra configuration is needed - JDeveloper, BPM/SOA extensions, BPM/SOA schemas in Java DB. Developer can focus on his development tasks, no need to spend days to install and configure development environment. You should read official guide - Quick Start for Oracle Business Process Management Suite.

Installer works on Mac OS platform, you can install entire Oracle BPM 12c infrastructure and run domain. However, it fails to open Human Task wizard, while running JDEV on Mac OS. I have developed extremely basic Oracle BPM 12c sample application, to test Human Task wizard with JDeveloper installed on Oracle Enterprise Linux and on Mac OS - BpmApplication.zip.

It works fine to load Human Task wizard with JDeveloper 12c installed on Linux:


The same Human Task fails to open with JDeveloper 12c installed on Mac OS. There is Null Pointer exception generated, thrown from JDeveloper IDE class:


Messages in JDeveloper log for this exception:


Probably you should not use Oracle BPM 12c for development on Mac OS, rather use Linux or Windows platforms. This is a bit pity, but on other hand JDeveloper extensions (except ADF Mobile) always had issues running on Mac OS. It should be no difference, but it seems like development on Linux or Windows with JDeveloper is more stable.

MDS Support for Mobile Application Framework (MAF) in JDeveloper 12c (12.1.3)

Fri, 2014-07-25 06:27
MAF framework in JDeveloper 12c (12.1.3) comes with MDS support. This means, we can customise mobile applications in similar way as we customise regular ADF Web applications. I'm going to explain and demonstrate with the sample application, how it works in MAF 2.0. You can read about it more in MAF 2.0 developer guide, Customizing MAF AMX Application Feature Artifacts.

Sample application, tested with iOS platform - MAFMobileLocalApp_v2.zip. Original version of this application brings Locations screen, where both City Name and Street Address are displayed:


We are going to customise original application with MDS, without changing source code directly. Customized application is based on two MDS tip layers - gold and silver level partners. Gold level partners are able to see State Name in addition to the Street Address:


While silver level partners are allowed to see only City Name:


To achieve MDS functionality behaviour for MAF application, you must define first MDS customisation class, this class must extend from standard MDS CustomizationClass and implement several methods. Important method is getName(), you must define MDS customisation name, the same name will be used for customisation (JDeveloper automatically reads this name during MAF application design time):


Customization class must be set in add-config.xml MDS section, in order to be registered for customisation use:


Once customisation class is registered, we can switch JDeveloper to the Customization Developer mode and start customizing application:


Make sure MDS layers are properly configured in CustomizationLayerValues.xml file. Customization layer must be set to the same name as you set in Customization class above. Layer values should specify different layers supported for customization:


I have defined two layers - gold and silver partnership. MDS layer can be selected for customisation, we start from Gold:


Locations page is updated to include State Name:


However, actual change is stored not in Location page, but in generated MDS file for Location page - it keeps delta for the changes made in customization mode. This file is generated under Gold Partnership profile folder:


State Name addition required to update Page Definition file for Locations, there is extra MDS file created with delta information for Locations Page Definition:


Next we can customize for Silver layer - change layer value:


Here we should keep only City Name and remove Street Address:


This change is reflected in MDS delta for Locations page, stored under Silver Partnership level:

Red Samurai ADF Performance Audit Tool v 3.2 - Large Fetch and Full Scan Audit Optimizations

Fri, 2014-07-18 10:05
Red Samurai ADF Performance Audit tool was updated with new features. Current update v 3.2 is focused on improvements for Large Fetch issues auditing, additionally we are able to track Full Scans (when user is fetching all rows and row count exceeds a threshold).

There are two additional threshold parameters introduced - WAT (Wait Activation Time) and WFT (Wait Fetch Time). These two are used to track long activation and fetch times in more accurate way. For simplified migration process from v 3.1, if no configuration is set in the database - default values are applied:


Large Fetch issue reports time it took to fetch rows, before it was reported only a number of rows fetched:


Audit tool knows how to track Full Scan - issue when user is fetching all rows and number of fetched rows exceeds Large Fetch threshold. This is useful, as it allows to understand specific cases, where we could optimise ADF code and potentially avoid fetching all rows:


Full Scan is reported together with all other issues, it is included to be a part of Performance Analysis graph:


Slow Query drill down was updated, to display VO instances with most recent slow query issues first (in red - number of issues in the recent 5 days):


Table with most recent Slow Query issues was redesigned to display issues in better ordered way. Today issues are displayed first, then issues from Yesterday, followed by Latest in 5 days and then All issues. Average time for each slow VO instance is calculated and displayed:


Daily Trend for VO instance was introduced in v 3.1, now tool also supports Monthly Trend - this allows to understand performance tuning impact better:


Large Fetch drill down was updated, it displays proportion of Large Fetch and Full Scan issues. List of VO instances reported with Large Fetch issues is redesigned in the similar way as for the Slow Query:


Today, Yesterday, Latest (5 days), and All issues are displayed. Average time is calculated and displayed for VO instance large fetch. Monthly Trend is calculated in the similar way as for the Slow Query.

Graphs displaying large number of days are configured with zooming - Daily Transactions and Logged Users graphs support zooming now:


User can zoom in data, this helps to analyse data points in specific days:

ADF Mobile 12c (MAF) Support for Master-Detail Data Control

Thu, 2014-07-17 14:15
ADF 12c is shipped with renamed mobile platform framework - Oracle Mobile Application Framework (MAF). Previously this was named ADF Mobile. 12c MAF is based on ADF Mobile and provides additional functionality and improvements. Everyone familiar with ADF Mobile 11g, should get up to speed with 12c without issues. I would like to highlight one interesting improvement implemented in 12c MAF - out of the box support for Master-Detail relationship. In previous 11g release, master record key was not preserved across different pages - developer was forced to store selected key in memory, to call execute method through invoke action in the second page and finally to reset a key. There was an alternative solution, described by Steven Davelaar - ADF Mobile – Preserving the Current Row Across Pages. Approach described in Steven's blog seems to be integrated into 12c MAF, there is no need to manage selected Master key manually, framework does this for you.

Sample application - MAFMobileLocalApp.zip, is based on HR schema loaded into local SQLite database and implements 2 level Details. Top Master is a Region:


First Detail screen brings a list of all Countries, from selected Region:


Second Detail screen displays available Locations, from selected Country:


Sample application provides navigation springboard, now there is only one Task Flow available - Address (may be there will be more options in the future):


Overall, 12c MAF is a great step forward - improved performance, better and cleaner UI, new features. MDS Seeded Customizations are supported now for mobile applications implemented with 12c MAF.

Sample comes with HR schema structure and data:


HR structure and data is loaded to the local SQLite database on initial application startup:


SQLite database is a physical file and we are opening JDBC connection. This is a database for single user, one user will be using it - no concurrency:


I will describe below, how to create Master-Detail structure and generate Data Control. There is a special extension available for similar task - A-Team Mobile Persistence Extension for Oracle MAF. However, for this exercise I would like to do it myself.

Firstly we should start with a model. There is Master-Detail relationship between Regions and Countries. Region object included a list of Country objects:


Country object in turn includes a list of Location objects, this is 2nd dependency:


This is our basic model, nothing complex. Model needs to be populated with data, this can be done with SQL, as all our data is stored locally in SQLite DB. Region, Country and Location rows are retrieved using SQL, Master-Detail relationship is populated manually:


Master-Detail relationship would not work, if there would be no Primary Key defined for Master object. By default, key is not set, when Data Control is generated. We need to edit Data Control object explicitly:


Here we can set a Primary Key for the attribute:


Task Flow displays relationship between Regions -> Countries -> Locations, there must be Primary Key set at least for Regions and Countries:


Important rule to know, 12c MAF doesn't really remembers current row in Data Control - it rather searching for iterator name and retrieves current state. This means, iterators in different pages must have the same names, otherwise current row key will not be resolved (even for the same data model object).

As for example, Region fragment:


Is based on data retrieved from regionsIterator:


This means Country fragment, displaying detail data:


Must have reference to Master iterator with the same name, as it is created in the first page Region (regionsIterator):

ADF 12c (12.1.3) Line Chart Overview Feature

Sat, 2014-07-12 10:51
ADF 12c (12.1.3) is shipped with completely rewritten DVT components, there are no graphs anymore - they are called charts now. But there are much more, besides only a name change. Previous DVT components are still running fine, but JDeveloper wizards are not supporting them anymore. You should check ADF 12c (12.1.3) developer guide for more details, in this post I will focus on line chart overview feature. You should keep in mind, new DVT chart components do not work well with Google Chrome v.35 browser (supposed to be fixed in Google Chrome v.36) - check JDeveloper 12c (12.1.3) release notes.

Sample application - ADF12DvtApp.zip, is based on Employees data and displays line chart for the employee salary, based on his job. Two additional lines are displayed for maximum and minimum job salaries:


Line chart is configured with zooming and overview support. User can change overview window and zoom into specific area:


This helps a lot to analyse charts with large number of data points on X axis. User can zoom into peaks and analyse data range:


One important hint about new DVT charts - components should stretch automatically. Keep in mind -parent component (surrounding DVT chart) should be stretchable. As you can see, I have set type = 'stretch' for panel box, surrounding line chart:


Previous DVT graphs had special binding elements in Page Definition, new DVT charts are using regular table bindings - nothing extra:


Line chart in the sample application is configured with zooming and scrolling (there are different modes available - live, on demand with delay):


Overview feature is quite simple to enable - it is enough to add DVT overview tag to the line chart, and it works:

ADF 12c (12.1.3) New Feature - ADF Query Item Reordering and Custom Operators

Thu, 2014-07-10 01:21
There are quite many new features in ADF 12c (12.1.3). One of them - ADF Query item reordering on runtime, user can choose the order to display criteria items displayed in ADF Query. View Criteria wizard in JDeveloper is updated, besides Criteria UI Hints (as we had before), now developer have access to Item UI Hints (here you can set item visibility, multiple values selection and removable support). Important addition - new tab in the wizard to define and manage Custom Operators for View Criteria items (this was possible before directly in the source code, now we have a wizard).

Here you can see new View Criteria wizard in ADF 12c (12.1.3) with UI Hints tab for each criteria item. I have set First Name criteria item to be rendered only in Advanced mode, also with removable option:


Custom Operators tab allows to create new operator or update/remove existing one, very useful feature to manage criteria search options:


ADF Query UI remains unchanged (by the way, First Name is not rendered in basic mode as it should):


Go to advanced mode - First Name is rendered now. There is additional button - Reorder. New functionality in ADF Query 12c (12.1.3):


Reorder brings a popup with ADF Query items, user can move Email to be the first item:


ADF Query is updated with the change - Email item is the first:


Even after returning to basic mode - order remains. I believe this will be quite useful functionality, especially for large ADF Query blocks with many criteria items:


Download sample application - ADF12cQueryApp.zip.

ADF BC 12c New Feature - Entity-Level Triggers

Tue, 2014-07-08 08:13
We have triggers support in ADF 12c! Powerful new feature is available - Entity-Level triggers. Previously it was often confusing if certain use case belongs to validation rule, or it is more generic business logic. Everything was implemented as part of validation rule in the EO. ADF 12c provides cleaner approach by supporting option of Entity-Level triggers, along with regular validation rules. Validation logic can be implemented as part of validation rule, non-validation (but still dependent on data management lifecycle) logic can be implemented as part of new Entity-Level trigger.

ADF 12c EO wizard offers new section - Entity-Level Triggers. Here you can define different triggers, for example - before update, before commit, after insert, before delete, etc.:


This means, you can inject any custom code to be invoked by the framework, during certain event from ADF BC lifecycle.

Wizard allows to select trigger type and define Groovy expression, here you can call any custom method from EO Impl class. However, there is one trick related to expression execution in untrusted mode - I will describe it below (thanks for a hint to Steve Muench):


Custom method is defined in EO Impl class, you can see it here:


If you simply define a trigger and try to test it, you will get an error about not permitted method call:


Trigger expression by default is running in untrusted mode, this means your custom method must be annotated with @AllowUntrustedScriptAccess. If you don't want to annotate, you could change trust mode to trusted for the expression. By default trust mode is set to be untrusted:


Change it to trusted mode:


Trigger should work just fine now. Try to change data and save:


There are two triggers defined - before update and before commit. Both of these triggers are invoked successfully, as you can see from the printed log (right before update and before commit):


Download sample application - ADF12cApp.zip.

ADF 12c (12.1.3.0.0) - View Object Declarative Mode is Default

Sat, 2014-06-28 10:25
Important event for ADF community - new release of ADF 12c (12.1.3.0.0). Quite many new features overall in the framework and there are some related to ADF BC. I will focus on ADF BC and highlight one new feature, which I think is very important to know. This is related to ADF BC VO mode, from now on - Declarative VO mode is a default. There is no longer Expert mode, this is renamed to Custom SQL and overall wizard for VO Query is changed. Read more about it in developer guide - 5.3 Working with View Objects in Declarative SQL Mode.

Every time when creating VO based on EO, JDeveloper will generate VO with Declarative mode:


This is how VO Query wizard looks like now. VO Query is declarative and will be generated on runtime. Although, it doesn't mean all attributes will be checked dynamically by default. On opposite, all attributes by default will be included into generated query:


Option 'Calculate Optimized Query at Runtime' is selected by default, this means Declarative mode is on. List of attributes is displayed, these attributes will be always included into SQL query. If we want to exclude some of them, we need to set Selected in Query = false for the attribute:


In sample application, I'm going to set this property to be false for all attributes, except a key:


If we return back to the VO Query wizard screen, now only key attribute remains selected:


UI is developed to display six attributes:


Only displayed attributes are included into SQL statement:


Download sample application - ADFBC12cApp.zip.

Time Selector for ADF Graph and Data Filtering

Fri, 2014-06-27 12:38
ADF graph with date/time data in X axis, could be configured with time selection and scrolling functionality. This could be very useful for such use cases, where we want to analyse specific set of data in the selected period of time. User could select a time range in the graph and display data from the selected range. We are going to include similar functionality into new release of our Red Samurai ADF Performance Audit Tool.

Here you can see example implemented in the sample application - ADFGraphApp.zip. User can select a time range to analyse data peaks, data will be filtered and displayed in the table below:


This is out of the box ADF graph feature - time selector. User is allowed to adjust selection range as he wants - move right or left. Data in the table below stays in synch with time range selection changes:


Another out of the box feature - graph zooming/scrolling along X axis with date/time data. This is quite useful, especially when data for long time periods is displayed and user wants to see changes in the specific period in more detail:


Zooming/scrolling is enabled with scrolling="on" property for 01Axis. Time selector is configured with separate element - timeSelector. You must set start/end interval and define time selection listener, so it could update dependent data displayed in the table (as in this example):


Important thing to remember, when working with date/time data displayed in X axis. You must ensure, duplicate data (using same date/time) is aggregated - otherwise, graph will be displayed incorrectly. You can set data aggregation directly in the graph binding with aggregation type setting:


The last bit - time selection listener. Here you can read start/end date/time intervals and apply these intervals to filter any dependent data. I'm using different VO instance with declarative View Criteria, to filter based on start/end for Hire Date. Setting bind variable values and re-executing VO instance:


More info you can find in ADF developer guide - 24.8 Adding Specialized Features to Graphs. Time selection listener code in given sample application, is based on example from ADF developer guide:

ADF BC Reserved Mode for DB Connection Critical Applications

Fri, 2014-06-20 06:31
With this post I would like to explain how you can control ADF BC mode and switch from default managed to reserved mode and back. With default managed mode, there is no guarantee in ADF BC for DB connection to stay assigned for the user session. Why it is highly recommended to design your ADF application in such way to be compatible with default managed mode, there are exceptional scenarios when we want to guarantee DB connection to stay the same between requests. Reserved mode allows to guarantee DB connection and there is a way to switch between modes on runtime. You can read more in ADF developer guide - 40.4 Setting the Application Module Release Level at Runtime.

Sample application - ReservedModeADFApp.zip, is developed to demonstrate how you can switch between managed and reserved modes. You can change any field and click Prepare Data, this will post it to DB. By default, data will be lost during the next request. However, if you click Enable Reserved Mode - ADF BC will switch to reserved mode and DB connection will stay assigned, until you will switch back to managed mode again:


Prepare Data button calls ADF BC post operation, to post data to DB. There are two key methods here - enableReservedMode and disableReservedMode. As you can see, it is pretty straightforward to switch between modes, you only need to call setReleaseLevel method available as part of ADF BC API:


Application Module configuration is set with all default settings, also DB pooling is enabled:


We should test how it works to switch between two different modes - managed and reserved. Let's change data in any field, for example Hire Date:


Click Prepare Data button to post changes for Hire Date to DB:


Click Save button to commit transaction:


At last, click Cancel button to check if previously posted changes were committed to DB:


You can see - changes in Hire Date are reverted back, as change was not saved after it was posted. Application Module is set with DB pooling, means during each request it will return DB connection back to the pool and get another one on the next request. This would mean all changes posted to DB are lost:


This is correct behaviour. But in some exception cases, we would like to keep DB connection between requests. We could force this by switching Application Module into reserved mode. By default, when DB pooling is enabled, you can see there are zero DB connections used (connections are returned quickly to the pool after request completion):


We should repeat our test, but little different now. Before posting changes to DB, click Enable Reserved Mode button - this will switch Application Module to reserved mode and guarantee DB connection across requests:


You can see from the DB connection monitoring, one connection gets reserved now and stays assigned:


Click button Prepare Data now, to post changes to DB when reserved mode is on:


Click Save button to commit transaction:


Click Cancel button to see if recent changes will be reverted:


Changes are not lost this time, means posted data was successfully committed in the next request, when Save button was pressed:


Changes were posted and committed to DB, we can switch back to default managed mode. Click Disable Reserved Mode button:


You should see from DB connection monitoring graph, previously reserved DB connection should be returned back to the pool:

Better Control for ADF UI Shell Tab Closing Order

Tue, 2014-06-10 14:02
This is third post in the series about ADF UI Shell usability improvement, you can read previous one - ADF UI Shell Usability Improvement - Tab Contextual Menu. When you work with Web browser tabs, expected behaviour after closing the tab in the last position is the next tab available on the left side to be opened. However, this works differently in ADF UI Shell and could be improved. I will describe how.

Here you can see three tabs loaded in ADF UI Shell, this comes with sample application - MultiTaskFlowApp_v5.zip:


If I would close tab in the last position - Locations, by default the first tab Departments would be set as current. However, users would expect Employees tab (next to the closed Locations tab) to be set as a current. This is how it works by default, when closing the tab in the last position - first tab becomes current:


In order to fix this behaviour, you need to update ADF UI Shell method responsible for tab removal and next current tab selection. By default, if closed tab is in the last position (there are no tabs further right) and counter is reaching maximum tabs, counter is reset to 0. Obviously there will be tabs available from position 0 and further to the right, however this would set as current tab not the closest one to the closed tab - but just first from the start. Highlighted code is the one that was added by me - when counter is reaching the end, instead of switching to the first position 0, I'm iterating leftwards. Once first tab on the left will be located, this tab will be set as current:


Again, I load three tabs and try to close the one in the last position - Locations:


This time proper tab gets selected - the next one on the left to the Locations, Employees tab:

ADF UI Shell Usability Improvement - Tab Contextual Menu

Sat, 2014-06-07 08:34
In my previous post - Improving ADF UI Shell - Tab Closing Icon Adjustment, I was describing how to implement ADF UI Shell tab closing icon to be located directly on the tab itself. Today I would like to share one more usability improvement - tab contextual menu. You could implement such functionality as - 'Close', 'Close All' and 'Close Others' with contextual menu invoked from the tab.

Sample application with ADF UI Shell tab contextual menu - MultiTaskFlowApp_v4.zip. Here you can see how ADF UI Shell tab contextual menu looks:


User can select a tab and choose to 'Close Others':


All tabs, except current will be closed - quite useful:


Contextual menu is implemented for ADF UI Shell tab with Client Listener calling custom Java Script function and Client Attribute to pass current tab ID:


Custom Java Script function is calling ADF popup, displayed as menu list. This popup is implemented with ADF command menu items - representing each option from contextual menu. Action Listener for menu item is configured with JSF attribute to pass current tab ID:


Here you can see methods responsible to close current tab, all tabs and other tabs. When closing all tabs or other tabs, it is important to check and close only those currently active:


You may face a conflict between tab contextual menu and regular browser menu for contextual action (typically right click). To block browser menu for contextual action, you could use code given above:

Improving ADF UI Shell - Tab Closing Icon Adjustment

Fri, 2014-05-30 13:22
Default tab closing icon in ADF UI Shell is located in the top right corner. Users are not really happy about this and there is a demand to have the same positioning as you can see in the Web browsers - directly on the tab. Tab placeholders are implemented in ADF UI Shell with af:navigationPane and af:commandNavigationItem components. Component af:navigationPane supports item removal, this means we can implement tab closing functionality directly in the tab. Unfortunately, out of the box ADF UI Shell template in ADF 11g and 12c is not updated with this adjustment. I will explain how you can implement by yourself, you would need to change ADF UI Shell source code.

Sample application is packaged with ADF UI Shell source code, including adjustment for tab closing icon - MultiTaskFlowApp_v3.zip. This is how ADF UI Shell tab looks with adjusted closing icon, directly in the tab:


User can click X icon to close Employees tab, it works perfectly fine:


This adjustment is implemented directly in ADF UI Shell template source code:


Default icon for tab closing is removed, see commented code:


Component af:navigationPane is set with itemRemoval="all" property. This renders and supports tab closing directly in the tab itself:


Component af:commandNavigationItem must be set with itemListener, this allows to implement a custom listener method to close current tab:


By default, close icon becomes visible, only when user moves mouse focus on top of the tab. This could be misleading for the users. However, there is a fix with custom CSS - you can define icon for disclosed and undisclosed tab:

Tab Navigation Performance in UI Shell and Multi Task Flow

Tue, 2014-05-27 13:36
I was investigating performance impact of navigating between tabs in UI Shell template. To compare, as alternative solution for UI Shell, I was using dynamic tabs with Multi Task Flow binding (Building Custom UI Shell with ADF 11g R2). When you switch between tabs in UI Shell, you could notice slight delay. This is normal delay (differently to browser tabs, where no delay), as there should be generated response from the server and JSF tree must be updated. However, it is not clear what is the impact of such delay to application performance. The goal of my post is to answer this question.

Sample application - MultiTaskFlowApp_v2.zip, contains two UI projects. One implements UI Shell and second Multi Task Flow binding based page for dynamic tabs:


Multi Task Flow binding is a new feature since ADF 11g R2, list of task flows can be referenced from the Page Definition:


This list can be rendered on UI with dynamic tabs, each tab would be physically created (in UI Shell case, only one region is rendered at a time):


Second project is using UI Shell template:


UI Shell doesn't render real tabs, instead it is using navigation pane component with links, displayed as a tabs:


Only one region is rendered at a time, the one you select. This means, when tab is changed - different region will need to be rendered again:


I was navigating through tab items for both solutions and recording tab opening time. Here are the results.

Multi Task Flow Binding: 

- Departments: 0.29 sec.



- Employees: 0.47 sec.


- Locations: 0.59 sec.


Average: 0.45 sec.

UI Shell:

- Employees: 0.61 sec.


- Locations: 0.55 sec.


- Departments: 0.28 sec.


Average: 0.48 sec.

You can see, both are almost the same. There is 0.5 second delay to open tab for a relatively simple UI with a form and editable table components. In the real scenario, with more complex UI, delay could grow to couple of seconds.

One second or couple of seconds delay is generally acceptable in UI Shell, for navigation between tabs. If delay is longer than that, something must be wrong in your application - slow data fetch or slow table initialisation, could be one of the reasons.

Personalising ADF Query with MDS User Persistence

Mon, 2014-05-19 22:24
I bet you are familiar with ADF Query UI having many criteria items. This may look irritating to the users, as there are so many options to use for the search. I will describe alternative approach in this post, with MDS user persistence and personalisation involved. It might be more user friendly, to offer only few criteria items by default and allow to add other items through ADF Query advanced option, together with MDS user persistence feature enabled for personalisation. Post is based on sample application from - ADF Query Saved Search in ADF 12c.

Here is updated sample application, for today post - SavedSearchApp_v2.zip. As you can see, there is minimal criteria set is available by default:


User could add additional criteria items he needs, like Email and save modified criteria for the future use:


Logout/login and personalised criteria for this user will remain available - quite cool. User could work only with criteria items he finds useful, this would make screen lighter also:


I hope such quick insight about ADF Query personalisation and criteria items optimisation will be useful for your project.

Implementing Dynamic Date Type Formatting with ADF BC

Wed, 2014-05-14 22:06
You may have a requirement to apply different format for date type attributes, based on username, as for example. Different users, may use different date formats - in such case, formatting for date type attributes must be set dynamically. This can be achieved, using approach described in my previous post - Controlling ADF BC Mandatory Attribute Validation Conditionally. I would extend explained technique and apply it for date formatting.

Sample application for download - DynamicFormatADFApp.zip. Here you can see two different browser sessions, two different users and different date formats applied in both cases. dd/MM/yyyy is applied for redsam1 and yyyy/MM/dd for redsam2:


ADF UI is standard for a inputDate component in a form - format is set through a standard EL expression in convertDateTime tag by referencing format property from AttributeDef object:


EL expression to get a format for the attribute, rendered in ADF table is changed slightly (otherwise, with default EL expression, overridden getFormat method is not invoked):


Generic View Row Implementation class must override createViewRowAttrHints and getAttributeHints methods - this would allow pass a custom format to be applied on ADF UI dynamically:


Finally CustomViewRowAttrHintsImpl class overrides framework method getFormat (this method is invoked from ADF UI EL for format property automatically). Here we could check for a username and return dynamic format (in real use case, this logic can be more complex):

Comparing ADF View Object and Row Fetch Execution Times

Sun, 2014-05-11 02:40
I bet one of the most common doubts ADF developer, or may be DB admin, has - why VO SQL executes slower than the one identical from SQL Plus? This is often the case, but there is nothing VO SQL to blame about. Usually VO SQL executes in almost same time, as it would execute in SQL Plus - but there is extra added time of row fetch. When ADF UI page is rendering, data becomes available after VO is executed and rows are fetched from result. These two separate technical actions, look like one for ADF UI user - data will not be displayed, until it is not fetched. So, there is extra time for row fetch on top of VO SQL query execution. This is why - displaying data in ADF UI, could be slower than displaying it in SQL Plus.

You should tune number of rows fetched by VO's, the worst practice is to set Range Size = -1 and fetch all rows at once. This is going to consume significant amount of memory to create many ViewRowImpl objects and waste time. Make sure to fetch only such amount of rows, close to be required for display on UI or any back-end operation.

I'm going to show you with a practical test - how time differs between VO SQL execution and row fetch for simple Employees table with 107 rows fetched as total. Here you can download sample test case application - ADFFetchApp.zip.

There is one iterator in Page Definition, for Employees VO:


I have set this iterator with Range Size = -1, to fetch all rows. I have seen the use cases, while reviewing and tuning ADF applications, where developers are using Range Size = -1 without actually understanding what a side effect for runtime performance it could create. Afterwards, it is common to blame ADF for a mystery, well hard to blame. Anyway, here is my test case Range Size = -1 setting for Employees iterator:


Sample application comes with a generic VO implementation class. There are two methods overridden here - executeQueryForCollection and createRowFromResultSet. In the first method, I'm tracking how long it takes to execute SQL for given VO. Second method tracks total time to fetch all available rows from Employees table (remember Range Size = 1 from above):


Fetch time is initialised, before constructing first ViewRowImpl object and stopped with the last row.

Just run sample application, after test page with Employees rows will be rendered you could check execution times and compare them:


In average it runs as following: 15 milliseconds for VO SQL query execution vs. 94 milliseconds for total row fetch:


As you can see, time added by row fetch operation could be quite significant and it makes sense to tune and ensure optimal row fetch in your application. SQL query is not only one thing to blame, when VO performance is slow, it could be you are fetching too many rows.

Red Samurai ADF Performance Audit Tool v 3.1 - Drill Down Analysis Improvements

Tue, 2014-05-06 13:21
We have new improvements in Red Samurai ADF Performance Audit tool. Update 3.1 is focused on new features in drill down reports for Slow Queries and Large Fetches.

Current day occurrences (in red) for Slow Queries are calculated per individual VO instance, along with latest occurrences (in yellow) and total occurrences. This helps to track outcome of performance fixes and understand if additional tuning is required for specific VO instance:


It is possible to select VO instance and display Weekly Trend - graph displaying distribution of reported Slow Queries per during previous days. This helps to understand, how reported issues were distributed recently and if tuning is producing any positive effect:


The same statistics are reported for Large Fetch issues in VO instances:


Weekly Trend is displayed for selected VO instance with Large Fetch:

Retrieving WebLogic Server Name and Port in ADF Application

Sun, 2014-05-04 08:50
It could come handy to know how to get WebLogic server name and port in ADF application. Particularly this could be useful, when running ADF application in the cluster and there is a requirement to track WebLogic node with application session instance running. Usually it is not enough to get server host, as cluster node is accessed through load balancer and server IP is different, not the one visible in HTTP session.

There is a way to get WebLogic server name and port. Server name could be retrieved from system property - weblogic.Name. Port could be retrieved from MBean - see the code below:


Server name and port is retrieved and displayed correctly for my test environment - DefaultServer and 7101:


You can download sample application - WLSEnvironmentAccessApp.zip to check how it works.

Adaptive Form with Dynamic ADF Attribute Value Binding

Thu, 2014-05-01 10:52
You can implement adaptive forms, generated on runtime using ADF Dynamic Form component in 11g R1 or 11g R2 (keep in mind - ADF Dynamic Form component is not supported with Facelets). In 12c you could use new ADF Dynamic Component to generate adaptive forms. All good, but customisation options are limited. For example, if you would need to define Value Change Listener for adaptive form UI component, this would be quite tricky as there is no direct access to ADF UI component properties.

If you need to control how UI is generated, you could implement your own ADF UI generation procedure. This would allow to manage ADF UI and ADF Bindings construction on runtime. I'm going to explain high level framework for such task and share sample application with ADF dynamic UI and ADF Bindings implementation.

Here you can download sample application - DynamicAttributeBindingApp.zip. The key part of this application is in the method below:


This method creates attribute binding dynamically, so you don't need to define attributeValues property in page definition on design time - this will be created on runtime. PNAME_TextField identifies simple binding (you could create different binding for LOV or Check Box). Iterator name must be set, along with attribute name and binding ID (exactly as it is defined in Page Definition XML, only programmatically this time). This code is not documented, you must check ADF source code for different scenarios.

Sample application contains ADF BC components, there is regular VO for Employees with a list of attributes defined:


There are no bindings for these attributes in Page Definition, all of them will be generated automatically on runtime. In real use case, you would have dynamic VO in the background or switch Iterator to use different VO's at runtime. This would allow to synchronise and generate adaptive form on runtime:


There are 3 steps to follow. Firstly we would need to construct on runtime a list of attributes to be displayed. This could be a custom method invoked from forEach ADF UI component:


This method gets a list of attributes from iterator and constructs a list of attributes to be displayed (some attributes could be hidden):


Second step is to render different attribute types. Text, number and date should be rendered differently, with different formatters or ADF UI components. For this purpose, we could use ADF UI switcher component and call custom method to return current attribute type:


Custom method retrieves information about given attribute and returns type to be used in the switcher (here I'm checking for text, date and numeric type only):


Third step is to provide properties for actual ADF UI component we are going to display. All properties as value, label, columns, validator, etc. should be provided. Expression language points to our custom method:


Custom method checks, if such attribute binding was already created, if not - it will be created. Attribute binding is created through a method described in the beginning of this post:


This is how it looks on UI - form is rendered same way, as it would be prepared on design time. I was checking if validation is executed correctly - as you can see, validation message is displayed properly: