Sunday, March 25, 2012

Red Samurai Tool Announcement - MDS Cleaner V2.0

This is announcement post: very soon, we are going to publish free Red Samurai tool available to everyone - Red Samurai MDS Cleaner V2.0. This tool is designed to work with plain ADF applications, as well as with WebCenter Portal or WebCenter Spaces applications. It allows to delete and edit corrupted or obsolete MDS entries.

You know how often we need to clean corrupted MDS entries, so there is no point to explain offered benefits.

Key features:

0. Works with ADF/WebCenter 11g PS1 - PS5

1. Plug&Play ADF Task Flow concept. Integrate into any ADF or WebCenter project, assign ADF security permission and you are ready to perform MDS housekeeping

2. Allows to search for MDS entries by package path or file name. Supports wildcard search options

3. Allows to delete one or many MDS files during single transaction

4. Allows to view MDS file content

5. Allows to edit and save updated MDS file content



Hopefully this will be life saver for MDS administrators, as there is no such tool available from Oracle (at least for now).

Stay tuned.

ADF BC AM Class Variables - Why To Avoid Them

ADF BC AM class variables - not harmful thing from the first sight. Only until we remember how AM pooling works, keep in mind - AM instance can be reused by different users through AM pool. AM instance object will keep initialized AM class variables from one user to another. This means private data of one user, will be visible to another user. This is not a bug, it just bad development practice to use class variables inside AM instance, when pooling is enabled.

Here is simple diagram, it will help you to understand described use case for sample application - SecurityFormLogin_v3.zip:


Sample application contains AM implementation class:


This class declares private variable - userName of String type:


There is pretty simple custom method, it accepts current user name as parameter and is initializing private variable (if not null). This is important - if not null, means if local variable was already initialized - it will not assign new value. If variable value will be stored inside AM instance object for different users - it will not be null for another user, who will reuse same AM instance. Method returns variable value:


This method is exposed through Client Interface:


Method is invoked from Page Definition, current logged user name is passed as argument:


Let's test it now. Login as first user - redsam:


AM variable was initialized correctly, it shows redsam as user name:


ADF Logger report correct value:


Now logout and login as scott, available AM instance is not destroyed yet and it will be reused from previous user - redsam:


And what we see - after login, still redsam is returned as user name from AM variable. This means AM variable was not null and it was not reinitialized - same AM instance object was used by two different users:


ADF logger reports the same:


If we wait some time, AM instance timeout happens and AM variable will be reinitialized for newly created AM instance - user scott is assigned:


Tuesday, March 20, 2012

Testing ADF BC Proxy User DB Connection in Multi-User Environment

I had a blog post about ADF BC Proxy User DB connection - Extending Application Module for ADF BC Proxy User DB Connection. It was quite interesting to test, how this approach works in multi-user environment, when passivation/activation happens. Good news - I didn't found any problems, all works well, I would like to describe my experiment today.

Sample application - AMExtendApp_v2.zip implements such use case - different users are connecting from the Web, ADF BC creates DB proxy, on stress load - PS_TXN table is used for passivation/activation:


In order to test how proxy user works, I have 3 DB users (APPUSER, HR and REDSAM). Both REDSAM and HR have EMPLOYEES table:


With different data:


Proxy user - APPUSER, doesn't have any tables:


For the stress test, I have disabled AM pool - this will simulate passivation/activation environment:


ADF BC internal connection is left as default - blank, this means it will create PS_TXN table inside proxy APPUSER schema (you can change it to different data source):


There are two users defined in the local security store:


Once page is opened, we set Bind Variable value for VO SQL statement. Bind Variable is set from onload popup (read here for onload popup technique - Opening ADF PopUp on Page Load). Bind Variable is set to 5000 for the first user:


To 50 for the second user:


When navigating through the rowset, passivation/activation happens correctly - bind variable value is not lost:



As expected, PS_TXN table is created inside proxy user schema:


I have tested as well with database connection pooling enabled (read more - Stress Testing Oracle ADF BC Applications - Do Connection Pooling and TXN Disconnect Level). ADF BC proxy user works well with database connection pooling enabled:


TXN Disconnect Level = 1:


Friday, March 16, 2012

Adding UI Facets into ADF Page Template Based on Facelets Type

If you will try to add UI Facet into ADF Page Template based on Facelets type (JDeveloper 11g R2) - you may get into trouble of accessing UI Facet from consuming fragment/page.

Here is what I mean - assume there is a template created based on Facelets type:


This template contains UI Facet - we drag and drop it from Component Palette:


Facelets type fragment is created based on Facelets template:


We try to access UI Facet inside fragment - but its not accessible:


Declared UI Facet is not accessible even from Structure window:


This is because of error in ADF Template - related to Facet definition:


JDeveloper creates (when you drag and drop Facet component) invalid Facet definition for ADF Template based on Facelets (it works well for JSP XML template). Facet definition error - remove wrong facet definition manually:


We can workaround this, by going into Facet Definitions section and manually defining facet for the template with the same name - content:


As you can see, facet definition is correct now and is based on afc tag:


Facet is available from consuming fragment:


Download sample application - FaceletsTemplateUI.zip.

Thursday, March 15, 2012

Use Case for ADF BC With No Database Connection

There is very good sample application from Steve Muench - #147 ADFBC Application With No Database Connection (not yet documented). I was using it to implement recent request from the project, its why I would like to document it. We had a discussion with SOA developers and they were wondering if its possible to run ADF BC application, without DB access. This is quite common use case in SOA projects, there is no direct access to DB and we need to consume data through Web Service layer, as for example. Yes its possible and I see quite strong advantage of ADF BC, even when working with non DB data sources - its easy to centralize data access through programmatic VO's, its fast to expose programmatic VO through Data Control and finally is easy to capture user data input, use out of the box functions to process user data (getting current row from VO, iterating over row set, creating new rows, deleting rows, etc.). This can be as alternative for Web Service Data Control.

Sample application - ADFBCNoDatabaseWSApp.zip use case is described in this diagram:


ADF BC application is disabled from creating database connection, instead it contains programmatic VO to retrieve data from alternate data source.

I would recommend to check Steve Muench sample #147 (see link above), for this use case I took original code and migrated it to JDev 11g R2:


If you want to disable database access for ADF BC application, you will need to update bc4j.xcfg with proper entries. I would recommend to update this file from outside, not from JDeveloper - otherwise you may experience errors - seems like JDeveloper IDE is constantly scanning changes from bc4j.xcfg. Make sure to update bc4j.xcfg as from sample application, for example RequiresConnection=false and other settings:


Default Connection Strategy is extended to disable database connection:


Application Pool is disabled to perform passivation:


Handle Commit and Handle Rollback methods are disabled:


We are done with extending framework. Now I can describe simple use case - programmatic VO to retrieve user roles from WebLogic security provider (based on my previous post). Programmatic VO is reading data from WebLogic security provider:


View Object doesn't have any SQL statement, obviously it retrieves data from non database source:


When building ViewController, we can use regular Data Control - same as we would have from standard ADF BC:


Data is rendered successfully on ADF UI:


In this case, application runs independently of database and we still can use all powerful ADF BC data processing features.

Saturday, March 10, 2012

Opening ADF PopUp on Page Load

You may have requirement to capture user parameters, before navigating to actual page. This can be implemented by opening ADF popup during page load. User provides required information and confirms it by closing popup - actual page is rendered based on dialog action.

Sample application - IntroPopUpApp.zip, is implemented based on following process:


With ADF Faces its pretty easy to open user friendly popup on page load. All what developer needs to do is to define af:showPopupBehavior operation for af:document tag:


af:showPopupBehavior trigger type should be set to load. This will ensure, it will be executed during document load and will call popup during page rendering phase:


PopUp is rendered on page load:


Such functionality can be very useful, when we need to set bind variable value for VO, based on user input. Instead of building separate data entry page, we can handle user data entry from on-load popup.