Friday, March 28, 2014

ADF 11g PS6 Table Pagination and Displaying Selected Row Issue - Solution

While ago, I had a blog post about new feature in ADF 11g PS6 (11.1.1.7) - table pagination support. There is an issue, when we want to open specific row and display it automatically in the table - required table page for the selected row is not opened correctly. However, blog reader suggested a fix, received from Oracle Support. Blog reader was kind enough, to post a comment with suggested fix, you can read it here - JDev/ADF sample - ADF 11g PS6 Table Pagination and Displaying Selected Row Issue. I decided to test this fix myself and provide updated sample application. The fix is to use range start from the iterator and set to it for the first property of the table with pagination. Actually, this fix does the job, but not completely perfect. Current row is displayed, only if Range Size for the iterator is set to 25, probably there is some hard coding somewhere. Ok, but at least it works.

Download sample application - TablePaginationApp_v5.zip. This application contains two fragments, second fragment with the table is opened from the first - where current row is selected. In the first fragment, we call setPropertyListener for navigation button and save required information in pageFlowScope (to be used in the second fragment):


This information - range start, once we move current row in the row set, range start is also changed. We are going to use range start, to set first property for the table - in such way, we could force table to display required page with selected row:


Here you can see, how table first property is set - we are using range start saved in pageFlowScope in the first fragment. This would force ADF table with pagination to display required page of rows:


Let's see how this works. Select a row belonging to the first range (I have configured Range Size to be 25):


Table with pagination is loaded and selected row is displayed in the first page, this is correct:


Navigate to some row from the second range (this should be after first 25 rows):


Selected row is displayed in the second page, as expected. There is one small issue - selected row is displayed at the bottom, while it should be somewhere in the middle. Well, this is another issue related to ADF table pagination:


If you navigate back to the first page and then again navigate to the second page - selected row will be displayed correctly in the middle:


In my opinion, ADF table pagination is not yet very tested and stable feature. Perhaps we should wait for improvements in the next release, until using it in the complex scenarios.

Thursday, March 27, 2014

Red Samurai Performance Audit Tool v 3.0 - Getting Smarter

Our ADF Performance Audit tool is growing and getting smarter. Current release v 3.0 is focusing on collected audit data reporting effectiveness. There were many features added since early release in 2012 - Red Samurai Performance Audit Tool - Runtime Diagnosis for ADF Applications. You can check features added in 2.8 release - Red Samurai Performance Audit Tool v 2.8 - Activation Focus.

Why v 3.0 release is smarter? Because it can tell ADF application health. We are collecting and analysing multiple ADF application performance metrics and calculating LED status - red, yellow or green to indicate ADF application health (see top right corner):


Application health indication can be drilled down to see more detailed metrics about ADF application performance:


My favourite new feature - performance analysis monitor. We display full history for performance issues, logins, queries and transactions. It is very easy to see and compare ADF application performance in time:


We are not only reporting data, but also analysing it. We apply special algorithm to smooth data and display trends in ADF application usage and number of issues:


This helps to understand, if ADF performance issue are result of higher load on the system or ADF BC is not tuned.

We also display total distribution of activations per each AM - this helps to understand AM's under heavy activations and tune ADF BC configuration:

Wednesday, March 26, 2014

ADF Alert - Facelets Vulnerability in ADF 11g R2 and 12c

If you are running your application in ADF 11g R2 or 12c environment and using facelets - you should double check, if a source code for the facelet pages is not accessible through the URL. There is another security vulnerability in ADF 11g R2, documented here - Alert for ADF Security - JSF 2.0 Vulnerability in ADF 11g R2. Apparently this is a patch from Oracle for JSF 2.0 vulnerability and also there is a manual fix. However neither patch or manual fix are not applied by default, potentially your source code could be exposed for public access.  This is why I post it on the blog - for all ADF users to be aware.

I don't have solution for vulnerability described in this post, you should contact Oracle support and ask for a patch. To reproduce this vulnerability is pretty easy - you could remove "faces" from URL and try to access your page (for example main.jsf), source code for the page will be loaded.

Sample application  - VulnerabilityTestCase.zip was tested with ADF 11g R2 and 12c runtime.

It doesn't help to set .jsf extension name in web.xml context parameter, as it does for ADF security vulnerability described in the previous post:


When we reference ADF web page with "faces" in the context root, page content is rendered as expected:


However, if you remove "faces" in the context root and try to access main.jsf - instead of returning error, ADF 11g R2 runtime will bring main.jsf page source code (a bit unexpected, right?):


The same with ADF 12c runtime:


Update from Oracle Support: Patch CVE-2013-3827 is available for this issue in October 2013 CPU.

Sunday, March 23, 2014

Alert for ADF Security - JSF 2.0 Vulnerability in ADF 11g R2

You must be concerned about your system security, if you are running ADF runtime based on ADF 11.1.2.1.0 - 11.1.2.4.0 versions. These versions are using JSF 2.0, with known security vulnerability - Two Path Traversal Defects in Oracle's JSF2 Implementation. This vulnerability allows to download full content of WEB-INF through any browser URL. There is a fix, but this fix is not applied by JDeveloper IDE automatically, when creating new ADF application. To prevent WEB-INF content download, you must set javax.faces.RESOURCE_EXCLUDES parameter in web.xml - make sure to provide all file extensions, you want to prevent to be accessible through URL.

By default, when vulnerability fix is not applied, we can access WEB-INF content using similar path: http://host:port/appname/faces/javax.faces.resource.../WEB-INF/web.xml. Unless you want to allow your users to download the source code, make sure to apply the fix in web.xml manually:


My test case - VulnerabilityTestCase.zip (this sample comes with vulnerability fix disabled - default version) is implemented with JDeveloper 11.1.2.4.0, I will demonstrate how to reproduce JSF 2.0  vulnerability with this version:


Test case consists of two basic applications, one of them is packaged as ADF library:


ADF library is imported into main sample application:


Two reproduce vulnerability is pretty easy - run main sample application, login with redsam/welcome1 user:


Default URL is generated in the browser and first page is rendered - all good so far:


1. web.xml vulnerability

Remove main page name and after faces/ type javax.faces.resource.../WEB-INF/web.xml, you will access web.xml content:


2. weblogic.xml vulnerability

Access content with javax.faces.resource.../WEB-INF/weblogic.xml:


3. Local ADF Task Flows vulnerability

Access in WEB-INF, using Task Flow path and name:


4. ADF Library JAR vulnerability

All ADF Library JAR's by default are packaged into WEB-INF folder, this means we could download these JARs and get entire code. You only need to type JAR file name. It is possible to get JAR file names from ADF BC configuration file, for such JAR's imported into ADF Model:


5. adfm.xml configuration file vulnerability

Here we can get a list of DataBinding files:


6. DataBindings.cpx file vulnerability

We have a list of DataBindings files from previous step. No we could open each DataBindings file and get a list of pages/fragments together with Page Definition mappings. We can read path information for ADF BC:


7. ADF BC vulnerability

Based in ADF BC path information from previous step, we could access Model.jpx file and read information about ADF BC packages:


8. ADF BC configuration vulnerability

We could go down and download every ADF BC component - EO/VO/AM. From bc4j.xcfg we can read info about each AM configuration, data source name, etc.:

Thursday, March 20, 2014

Shortcut to Call Custom View Row Method from JSF Expression

There is a custom method in Generic View Row Implementation class and you need to invoke it from UI. What would you do? Most likely you would generate Java View Row Implementation class for the specific VO, publish custom method through the interface and later consume it through ADF bindings. This works, but there is a shortcut - especially well working for generic solutions.

Sample application - RowIndexAppADF.zip, implements a table with row status displayed in each row. Once user is changing data, row status is updated - this is the use case, to display row status generically for each row:


We can see from the log - row status is evaluated for each row:


Such check is implemented without a method binding in Page Definition, instead we are accessing current row (available in the table context) and from the row getting row object (the one that represents actual VO row). Next from row object, invoking our custom method, implemented in generic View Row Implementation class - row.row.checkRowStatus:


There is a generic View Row Implementation class, View Object in the sample app extends from this class:


Generic View Row Implementation class contains our custom method, invoked from ADF UI - getCheckRowStatus:


Pay attention, in JSF expression, get part is omitted from the method name: row.row.checkRowStatus.

I believe, this is simple, but very effective technique.

Thursday, March 13, 2014

How To Setup MDS Repository for Embedded WLS Instance

Recently I was enabling external MDS repository for ADF MDS Seeded Customizations, I was facing issues while testing such MDS repository with my local embedded WLS instance - running it directly from JDeveloper. I managed to find a solution at the end, so I would like to share it with you.

I was doing same thing as to configure MDS support for ADF Query Saved Search - defining persistence config in add-config.xml file. This config allows to map your ADF application, enabled with MDS, with MDS repository during deployment:


With persistence config in adf-config.xml present, while deploying sample application - MainMDSApp.zip, to the embedded WLS server instance:


You will get MDS repository configuration wizard screen, where you could choose MDS repository name, type and provide partition name. However, by default MDS repository is not present on embedded WLS and we can't really define MDS repository:


Good news - to define MDS repository for the embedded WLS instance is quite easy. Of course, this MDS repository is supposed to be used during development only, not during production. During production you should use DB based MDS repository configured on the stand alone server. While locally, we could create pretty basic file based MDS repository. This can be done in Persistence Stores section, under Services - choose to create new File based repository. Only things you need to set: name and directory. See below my example:


Once you press OK, MDS repository is created in the file system:


Try to deploy sample ADF application again - you should get MDS repository name in the list. This is file based repository and you could define MDS partition name. Under this partition will be stored all MDS documents for the current application:

Thursday, March 6, 2014

Why You Don't Want to Code Validation in Before Commit

You should know by now - there are many things possible in ADF, but it doesn't mean every solution is right, even if it works. One example of such case - coding validation rules in beforeCommit method. This method is invoked after all changes are posted and ADF BC assumes data is valid, if we throw later validation error from beforeCommit - ADF BC state remains unchanged and changed data is not submitted again. There is a workaround to set jbo.txn.handleafterpostexc=true and to force in memory passivation snapshot with subsequent activation on validation error - however, this is a big performance hit. Every time, where there will be validation error - rollback will be executed and entire AM with all VO instances will be re-activated (SQL re-executed and data re-fetched). Today post is about bad practice, to demonstrate why you should not code validation in beforeCommit method.

Sample application - ADFHandleAfterPostApp.zip, implements validation rule in EO beforeCommit method. Validation rule calls PL/SQL function and throws exception if validation result is false. It validated salary value from the current row (PL/SQL function code is attached in sample application):


PL/SQL function checks if salary value is lower than 2000:


Sample application is configured with DB pooling. By default, without DB pooling set - DB lock will not be removed after exception from beforeCommit:


To test beforeCommit validation behaviour, open the form and set Salary value below 2000. Change also another field - FirstName, for example:


As expected, there will be validation error and exception thrown - error message displayed:


We can see the sequence of steps happening in the log. There is DB lock for the current row, data is posted successfully for both Salary and FirstName attributes, then exception happens:


Ok, we can fix Salary attribute value and set it to be higher than 2000. Keep the same value for FirstName attribute, it is not committed yet to DB and we expect it to be committed now:


What we can see in the log now - Salary attribute value was posted and committed, as validation passed successfully. However, second changed attribute - FirstName, value was not committed. This is because, ADF BC thinks FirstName was committed during previous commit, when it actually failed. As exception was thrown in beforeCommit, this is already after ADF BC marks data as valid and assumes to be committed to DB. This is the main issue with coding validation in beforeCommit - ADF BC transaction state remains invalid:


If you press Rollback - you will see, FirstName will be reset to the previous value:


There is a workaround for this case, to use jbo.txn.handleafterpostexc = true property in AM configuration:


However, this leads to runtime performance issues - as it fires passivation in memory on each commit and does rollback with re-activation on every validation error in beforeCommit. We can track all such activations, fired from beforeCommit, by overriding activateStateForUndo method in AM:


We can test the same scenario - change LastName and Salary attributes, set Salary to be less than 2000:


Now we can spot - there was activation event raised:


During activation, all VO's are re-executed and re-fetched. Here we can see SQL query and data fetch for Employees:


There is SQL query and data fetch for Departments, even we didn't touch it: