Friday, June 26, 2009

Oracle ADF and International Characters

My team is developing application in Oracle ADF with internationalization support. When we did preliminary tests, we have noticed that we can't save local characters to database, entered characters simply were transformed to code representation. Our database character set is not UTF-8, but local. We were lucky to find very elegant solution - just to change content type charset of our pages. We have changed it to UTF-8, inside our JSPX pages, and ADF automatically transforms it to database character set. This means, same approach works when we have UTF-8 charset in database, or any local charset as well.

You can download my sample application - ADFInternationalChars.zip, where you can test how it works on your database.

Let's say we have simple form:


And type text in local language for First Name field, this time in Russian. When user will want to store this record and will invoke Commit, local language characters will be transformed to unreadable form by default:


I saw people are asking related questions quite frequently on OTN forums. Actually solution is simple, we just need to change page content type charset from default one:


To UTF-8 charset:


This will allow to accept local characters on JSPX page and to transfer them through ADF Business Components to database. And now Russian text is saved to database without problems:


And if to check database, here is this text stored:


Finally, its important to mention, that if your database is installed with UTF-8 support, you can store all local characters. But, if you have database with specific character set, you can store only this specific charset from JSPX pages. Its good thing you dont need to modify your JSPX pages in both cases, just declare UTF-8 for page charset encoding. My database is installed with UTF-8 charset:

Friday, June 19, 2009

Quick Hint for ADF Faces Rich Client Performance Tuning

In this post I want to write about quick hint applicable for ADF Faces Rich Client performance tuning. This hint was found by my colleague - Sasha Stojanovich, we are working in the same project. I think it will be useful for community as well.

We have discovered, that we can disable ADF Faces Rich Client animation functionality globally, just by adding one line in trinidad-config.xml file:
  • animation-enabled = false
If you really don't need animation effect, this will help greatly when rendering LOV popups, drawing data tables and etc. By disabling animation, artificial delay of components rendering is removed and this allows to achieve better UI performance.

Thursday, June 18, 2009

Oracle OpenWorld San Francisco 2009

My paper for Oracle OpenWorld 2009 - Oracle JDeveloper/Oracle Application Development Framework 11g Production Project Experience is accepted !

Session ID#: S307721 abstract:

This session, based on practical experience in Oracle JDeveloper/Oracle Application Development Framework (Oracle ADF) 11g technology, describes development best practices for J2EE development with Oracle ADF Business components, Oracle ADF Task Flows, and Oracle ADF Faces Rich Client. The speaker focuses on technical aspects of his work and demos an Oracle JDeveloper 11g quality extension his team created. It implements Oracle ADF 11g development best practices for Model-View-Controller parts as a set of rules applied to Oracle Fusion. The speaker also describes how his team is using the Oracle JDeveloper 11g Subversion (SVN) client for team development with SVN branches.

I will be happy to see you there on Oracle Develop: Oracle Fusion Development track in San Francisco this October !

Saturday, June 13, 2009

Working with View Criteria Items

I will describe how you can work with view criteria items in easy way. Often when you will use Oracle search component - af:query, you may face requirement to access entered criteria items and perform one or another action based on the result. I would like to recommend always base view criteria items on Bind Variables, this will greatly help you while working with query pages.

Download developed sample application - QueryCriteriaParams.zip. In this sample I'm accessing entered criteria item values and based on this show or hiding result components.

As I already have mentioned, I have declared view criteria based on Bind Variables:


In View layer I have overridden Query Listener (more: ADF Query Component and View Criteria Functionality with Custom Query Listener in 11g):


I'm accessing view criteria items directly in overridden Query Listener. I can do this by getting Bind Variable values from VO Variable Manager. Here is a power of defining View Criteria on Bind Variables, not just Literals. Sample code where I'm accessing criteria values and showing/hiding result components on the page:


On runtime, when page from my sample application is rendered, user will see just View Criteria available:


According to implemented logic, if user will enter First Name criteria and will do search, table component with results data will be present:


If user will enter both criteria parameters - Firs Name and Last Name, this means instead of table, form component will be rendered:

Saturday, June 6, 2009

JDeveloper 11g IDE Performance Problem - Reproduced

2009/06/08 UPDATE: I got answer from Oracle, this problem is not reproduced anymore in their internal latest build.

2009/06/12 UPDATE: Additional Helpful workaround was posted on From Developers To Developers blog.

Our team have reproduced performance problem in JDeveloper 11g IDE while developing ADF applications. This problem seems so big, that it can crash JDeveloper 11g in 5 minutes by returning 'Low Memory Message'. In this post I will describe how to reproduce IDE performance problem and will provide sample application as test case. You can reproduce bug in latest JDeveloper 11g release - Build JDEVADF_MAIN.BOXER_GENERIC_090328.0229.5205. It was logged on Metalink in November 2008, but not fixed still (BUG 7601410).

You can download developed sample test case where you can reproduce 'Low Memory Message' in 5 minutes - ViewControllerPerformance.zip. Sample is really simple, it contains ADF BC from HR schema and one JSPX page, one entry in DataBindings.cpx.

When opening application in JDeveloper 11g, in the beginning IDE behaves normally, it consumes just as usual around 300 MB:


Here is structure of sample application, really nothing complex:


Nothing complex except two property bundle files - buttons.properties and labels.properties. Those files contain around 1000 entries each, and you will see now what problems it creates. Im using couple of entries from those files in main.jspx and just by opening this page I'm getting doubled memory usage up to around 800 MB:


I have tried to open just one Expression Builder on main.jspx:


And I got 1200 MB used in 3 minutes:


Same time I got 'Low Memory Message' in JDeveloper 11g IDE:


The reason for this is large property bundle files and how those files are referenced from JSPX page. When developer puts label from property file on the page, JDeveloper automatically creates following references:


Those references cause JDeveloper 11g IDE to consume memory heavily and run out of memory, especially when property bundle files are big.

If you will comment property bundle files referencing:


JDeveloper 11g IDE will behave as expected, without high memory usage:


I wish described IDE performance bug will be addressed and fixed in next JDeveloper 11g release.

Spanish Summary:

En este capitulo, Andrejus identifica un problema de rendimiento en la herramienta JDeveloper 11g. Se muestra un ejemplo que al ser ejecutada con la herramienta tiene un alto consumo de memoria. Afortunadamente, Andrejus ha enviado a ORACLE sus descubrimientos para una pronta solución del problema.

Sunday, May 17, 2009

Parent Action Activity in ADF Task Flow

Recently I have faced a problem, when was trying to navigate to ADF Task Flow Call activity. The problem was, that I was initiating navigation from inside the region and navigation flow was defined not in bounded region ADF Task Flow, but inside parent bounded page ADF Task Flow. This means, navigation outcome from parent ADF Task Flow was simply invisible for button I have created inside region. But as usual in most of the cases, ADF provides very elegant solution to solve problem of external navigation from inside the region. I will describe it in this post.

The problem is, that I have bounded ADF Task Flow, however main page is using region and this region can't see declared navigations from this ADF Task Flow:


Region is used on main page, this region provides table of Countries, user can select any country and navigate to Location ADF Task Flow:


And here is the answer for described problem - in order to navigate from region using navigation rule from parent ADF Task Flow, you can use Parent Action activity inside region ADF Task Flow:


Only one thing you need to do is to define parent-outcome property, or in other words - navigation outcome from parent ADF Task Flow you want to use. In my case it is child navigation outcome:


Defined parent outcome will navigate to ADF Task Flow call activity and will open locations page.

On runtime, when user will press Location button implemented in region component, navigation from parent ADF Task Flow will be triggered:


Correct list of locations is returned:


You can download sample application for this post - ADFRegionNavigation.zip.

Useful hint, when user will return to Countries table, in order to show previously selected record, set DisplayRow = selected for af:table component:

Saturday, May 16, 2009

Inheritance Feature in Oracle ADF BC - Part 2

My today post is second post that describes inheritance functionality support in ADF BC. I will describe how you can use inheritance in View Objects. In previous post I was describing inheritance in Entity Objects - Inheritance Feature in Oracle ADF BC Part 1. Inheritance on View Object layer adds more object abstraction, you can operate not only different sets of data based on discriminator, but implement polymorphism for View Row classes. For more information, you can read 35.7.5 Working with Polymorphic Rows section from ADF Developer Guide.

I have developed sample application - ADFBCInheritance2.zip, based on application from previous post - ADFBCInheritance.zip. Updated sample contains additional View Objects, extended from Country. Those new View Objects are CountriesAfricaView and CountriesEuropeView:


In the View Row class of CountriesView, I have defined calculateProfit method. This method will be overridden in extended View Objects:


I will create only two overridden View Objects from possible four - for Africa and Europe discriminator values. CountriesAfricaView inherits calculateProfit method:


And CountriesEuropeView inherits same calculateProfit method:


I have defined Row Class for both extended View Objects, in those classes I'm overriding calculateProfit method from parent Row Class of CountryView:


For example, in CountriesEuropeViewRowImpl class I'm setting profit value to 500, while in CountriesAfricaViewRowImpl class to 200 and finally in CountriesViewRowImpl to 700. This means rows that belong to Asia and America discriminator value, will get 700 value for Profit attribute:


Last step, when enabling inheritance in View Objects layer, you need to set Subtypes in Application Module for polymorphic View Object - CountriesView in our case:


Press Subtypes button and and choose available View Object that extends parent:


In View layer, from Backing Bean, I'm scrolling through all rows from CountriesView and invoking calculateProfit method. Through implemented polymorphism, this method will be invoked for specific row based on its discriminator type, we dont need to specify it directly:


During runtime, I will invoke method from Backing Bean, by pressing Set Profit button:


To test that polymorphism really works, go to Europe section and check that Profit value is set to 500, as it was specified in overridden method:


Then go to Asia section, and check that Profit is set to 700, as it was specified in the Row Class of parent CountriesView:


Spanish Summary:

El post anterior, mostró como aplicar el concepto de Herencia en las Entidades. Sin embargo el mismo principio puede ser aplicacion a los componentes View Object. En este post, Andrejus nos muestrÔ, de manera prÔctica como aplicar herencia entre Vistas.