Saturday, August 27, 2011

Oracle R12 Controller Class extension in OAF

Oracle shipped documentation for Jdeveloper 10g that includes screen prints and instructions for an older product with a different user interface. Hence, all information presented on this page is a result of random and sometimes brutal hacking.

The example used to show that a Controller class extension *is* actually possible in R12 will be defaulting a MessageLoVInputBean within the New Hire process in Self Service Human Resources.First, log in to Oracle Applications to see where this defaulting will take place:

(N) Manager Self-Service -> Hire

Proceed to step 3 and notice that Oracle provides the Setup Business Group for the default Department/Organization name:

Click "About this Page" link in lower left corner to begin the process of finding the field name to default. Click "Expand All":

Then search for the Department; notice that the Controller class is called OrganizationCO:

Click Business Component Reference Details to get the complete path where the OrganizationCO is stored on the application tier:

Lettuce begin extending this file so that the Department name field is set to null. Open JDeveloper R12 on your client machine. This tutorial assumes you have already downloaded the client from Oracle and unzipped it to a root directory like

C:\JDEVOAR12. Also, set the Windows environment variable JDEV_USER_HOME:

Right-click My Computer -> Properties -> Advanced (tab) -> Environment Variables (button) -> JDEV_USER_HOME -> edit

Set the value to C:\JDEVOAFR12\jdevhome\jdev if "C:\JDEVOAFR12\" is where you unzipped JDeveloper R12.

Inside of JDeveloper, create a new Workspace by doing the following:

(N) File -> New and then choosing General -> Projects -> Workspace Configured for Oracle Applications

Enter an arbitrary value in the File Name dialog box to identify the kind of workspace this will be. I'll be hacking, so naturally mine is called 'hack.jws':

For a default project package, change the delivered names to a custom name.

oracle.apps.per.selfservice.deployperson.webui.OrganizationCO will be extended so our default package for the extended files will be

Choose a .dbc file for the connection. If one is not already configured, follow these steps:

1. Browse to
2. Complete the information and click Test
3. Click "Enter AOL/J Setup Test"
4. Click "Locate DBC file"
5. Copy/paste the resulting DBC file and save it as hack.dbc to C:\JDEVOAFR12\jdevbin\oaext\dbc_files\secure

In order to extend the delivered Controller class and have your project work correctly, you will need to import the delivered

Controller class into your project. Each file in Oracle apps has many dependencies; rather than import one at a time, I download the entire JAVA_TOP to my local machine. Connect to the middle tier and do the following:

1. cd $JAVA_TOP
2. tar -cvf java_top.tar oracle
3. FTP the .tar file to C:\JDEVOAFR12\jdevhome\jdev\myclasses
4. extract the .tar file

Note that the above procedure could take a long time to complete as the $JAVA_TOP can be over 1GB. Now that the files are in place, connect to the database and run the following script:

set feedback off
set serveroutput on format wrapped
set linesize 100
spool hack.lst
execute jdr_utils.printDocument('/oracle/apps/per/selfservice/deployperson/webui/AssignmentPG',100);
spool off

This will spool the AssignmentPG page to a flat file, which can be saved and imported into JDeveloper:

Place it in C:\JDEVOAFR12\jdevhome\jdev\myhtml\OA_HTML. Now import the file into JDeveloper by doing File -> Import:

Even though it is not a Java file, you must choose "Java Source" (makes perfect sense):

Browse for C:\JDEVOAFR12\jdevhome\jdev\myhtml\OA_HTML

Deselect all and then check AssignmentPG and click OK. You will see the Page populate in the "Application Sources". Click on the Page and you will see the Structure populate in the "Structure" pane:

Right Click the HROrganizationRegion which has the HrDepartment field that will be updated and click "Set New Controller..."

Enter a package name identical to the delivered package but with your custom project name in front of it. For example, mine is: The Controller class filename will follow the same standard: hackOrganizationCO

Note that this is an extended controller class that is not specific to the OrganizationCO:

You must import the delivered CO and extend that one; additionally, import the OAMessageLoVInputBean class for the field that will be defaulted:

The following code will default the Department Name field to null if it is equal to the value "Setup Business Group". The processRequest method has the code that performs this default. This is the code that is executed when a user hits the page. processFormRequest is called when the user submits the page to move on to the next one. Notice that the defaulting code is to occur when the page is first rendered. Also, the "super.processRequest(pageContext, webBean);" line tells Oracle to execute the delivered code and then fires the code inside processRequest.

| Copyright (c) 2001, 2005 Oracle Corporation, Redwood Shores, CA, USA |
| All rights reserved. |

import oracle.apps.fnd.common.VersionInfo;
import oracle.apps.fnd.framework.webui.OAPageContext;
import oracle.apps.fnd.framework.webui.beans.OAWebBean;
import oracle.apps.fnd.framework.webui.beans.message.OAMessageLovInputBean;
import oracle.apps.per.selfservice.deployperson.webui.OrganizationCO;

* Controller for ...
public class hackOrganizationCO extends OrganizationCO
public static final String RCS_ID="$Header$";
public static final boolean RCS_ID_RECORDED =
VersionInfo.recordClassVersion(RCS_ID, "%packagename%");

* Layout and page setup logic for a region.
* @param pageContext the current OA page context
* @param webBean the web bean corresponding to the region
public void processRequest(OAPageContext pageContext, OAWebBean webBean)
super.processRequest(pageContext, webBean);
* find the HrDepartment bean programatically
OAMessageLovInputBean oaMessage = (OAMessageLovInputBean)webBean.findIndexedChildRecursive("HrDepartment");
* if the value is not null...
if (oaMessage.getValue(pageContext) != null) {
// get the value currently in the text box
String strDepartment = oaMessage.getValue(pageContext).toString();
pageContext.writeDiagnostics(this, "strDepartment: " + strDepartment, 3);
// If it's equal to the Setup Business Group...
if (strDepartment.equals("Setup Business Group")){
pageContext.writeDiagnostics(this, "Here10", 3);
// set it equal to null
pageContext.writeDiagnostics(this, "Here20", 3);

* Procedure to handle form submissions for form elements in
* a region.
* @param pageContext the current OA page context
* @param webBean the web bean corresponding to the region
public void processFormRequest(OAPageContext pageContext, OAWebBean webBean)
super.processFormRequest(pageContext, webBean);


Now that the code is written, right-click the CO file and do a "Make" and then a "Rebuild". This creates the compiled .class files that will be transferred to the middle tier for execution inside Oracle Applications.

Go to C:\JDEVOAFR12\jdevhome\jdev\myclasses and find the folder called 'hack'. Right-click and create a .zip file. Follow these instructions to deploy it to the application tier:

2. unzip

Now browse to the page where this Controller .class code needs to be executed.

(N) Manager Self-Service -> Hire -> Step 3 -> Personalize Page

Click on Complete View then Expand All (link):

Find the Department Default Single Column and click the Pencil:

Set the Controller Class field to Click Apply and then

"Return to Application" link.

This is Oracle so don't expect your changes to show up just yet. In R12, in addition to bouncing Apache, you must also bounce the OC4J process. Technology has advanced to the point that changes to the application require two laborious steps. You need to perform the following commands on the middle tier first:


4. sleep 10

Once these steps are complete, close your Browser and log back in to the application. In order to show that our code is being executed we will enable Diagnostics and check that our pageContext.writeDiagnostic messages are being written to output.

In order to enable diagnostics, click Diagnostics in the upper right hand corner. If this link is not present, set the profile option FND: Diagnostics to "Yes":

Show log on screen; click "Go":

Choose Event as the messages written out to diagnostics in the Controller class used a code of "3" for event. Going further down to Statement level will write more and more output to screen:

Now you've got mad junk written on the screen.

Go to the Hire process, step 3 and confirm that the Department field is null and that the output messages are written to the diagnostics dump at the bottom of the page:

Your code will also show up on the "About this Page" link. Score! Rah rah!

No comments:

Post a Comment

Best Blogger TipsGet Flower Effect