Saturday, July 7, 2012

Proxy or DataControl with webservices in ADF

A recent article by Frank in Oracle Magzine issue July/August 2012 , provides a clear insight and guidelines, about which approach one should take while interacting with web services in an ADF application :
Frank's Article.


Tuesday, June 19, 2012

ExecuteWithParams in ADF 11g

A small post after a long time regarding "ExecuteWithParams"  operation with VO. Most of the time, since coming from OAF background I usually write small methods in AM implementation class and expose it to view controller layer using interface and then drag and drop it as a binding layer in my ADF page.

 But recently was struck, when tried to ease my work using ExecuteWithParams drag and drop directly and assign the bind variable value from pageFlowScope.I worked for almost 4 hours tried all sorts of debugging but everytime when my bounded taskflow reaches executewithparams activity , i use to get error code like :
JBO 27122 error and the exception message like "Missing IN or OUT parameter at index:: 1 " error.

Generally happens with me :) , whenever try to ease my work , some innovative error  comes in... ! But anyways after a careful review of the VO xml files and comparing with old code where I have used this operation many times I came to the conclusion : There are two kinds of bind variables: "where" and "viewcriteria". While editing my viewobjects I accidentally created a variable of the kind "viewcriteria", which means that it cannot be used in the where clause of the sqlquery, but only in a viewcriteria. When you create a "where" variable, you are allowed to use it in the where clause of your query.This all makes sense, but the GUI for editing the variables does NOT show the difference.

So if you run into the error above, look inside the XML of your viewobject for your variable and if you see Kind="viewcriteria", then change it to Kind="where" and try again and  your code should work fine.

Monday, April 23, 2012

Weblogic Vs Jdeveloper 11g

An interesting post on Timo Hohn's blog ,  which helps to avoid different version(s) of ADF Jdeveloper and Weblogic server :

http://tompeez.wordpress.com/2011/09/14/jdeveloper-versions-vs-weblogic-server-versions/

Tuesday, July 6, 2010

JDBC Connections leakage and optimization in Oracle Apps R12.

Identifying issues with JDBC connections in Apps can sometimes be a frustrating process, as the investigations may need to consider multiple failure points and complex architectures. I hope this article will give you a better understanding of JDBC Pooling and where to start looking for issues. Hopefully this article should help system and technical architects in Apps to resolve connection leak problems.

Recently while working with Oracle MEA in world's first major implementation of CMRO module in Apps, we faced some critical performance issues, initially. One of the major performance issue was "JDBC connections leakage". Over a period the "INACTIVE" jdbc connections rise and finally they cross the maximum jdbc connections figure set in database and server goes down. The immediate solution was bouncing OC4J Core and HTTP containers of Oracle Apps application server 10g, but off-course this is something you can not do daily in a production environment.

Since our implementation layer has a strong layer of custom code and standard code , done by various teams and you don't have control on coding of individual new developers. I thought it is next to impossible to identify root cause and fix it ,but thanks to Oracle... in Apps there are some standard ways to fix this problem.

Ok to start with lets start with some basic definitions and facts to understand the problem , I am talking about here :


What is JDBC ?
The Java Database Connectivity (JDBC) API is the industry standard for database-independent connectivity between the Java programming language and a wide range of databases – SQL databases(Oracle,mysql etc) and other tabular data sources, such as spreadsheets or flat files. The JDBC API provides a call-level API for SQL-based database access.

What is JDBC Connection ?
Java JDBC APIs uses connection (session) instance in which SQL statements are executed and results are returned within the context of a connection.

What is JDBC Connection pool?
If you have used a SQL or other similar tool to connect to a database and act on the data, you probably know that getting the connection and logging in is the part that takes the most time. An application can easily spend several seconds every time it needs to establish a connection.

In releases prior to JDBC 2.0 every database session requires a new connection and login even if the previous connection and login used the same table and user account. If you are using a JDBC release prior to 2.0 and want to improve performance, you can cache JDBC connections instead.

Cached connections are kept in a runtime object pool and can be used and reused as needed by the application. One way to implement the object pool is to make a simple hashtable of connection objects.

What is Connection leakage ?
An application(basically application server) is said to be leaking connection, if it acquires a connection and does not close it within specified time period. If this feature is enabled, the application server detects these potential connection leaks and dumps the leak tracing logs to server logs. Looking at the logs the user can figure out which application is leaking connection and fix the issues with application, if exists.

What is Connection locks ?
If your are doing multiple DML jdbc transactions in your code with autocommit flag as false on the connection object,the jdbc connection remains locked till the time commit is issued specifically.(By default in OAF/JTF the autocommit flag is false.)


How to identify that Apps instance has connection leakage problem ?

You can run the following sql statement occasionaly to monitor jdbc connections
behaviour :

select s.machine, s.username, s.module, s.inst_id, count(*) how_many
from (select distinct PROGRAM, PADDR, machine, username, module, inst_id from gV$SESSION) s,
gv$process p
where s.paddr = p.addr
and p.inst_id = s.inst_id
group by s.machine,s.username, s.module, s.inst_id


This will list down number of jdbc connections in each module. For OAF, the module is shown as page AM and for JTF/JTT/JSP, the JDBC connections are listed in "JDBC Thin Client". You can keep of track of connections in each module mainly ("JDBC Thin Client"), if this is growing each day. You can also check the status of these connections in v$session if its "INACTIVE" and these connections are persisting for more than 24-48 hours, means these sum up to connection leakage.

For OA Framework calls AOL/J when it needs a database connection, and it is up to OAF to release any such connection when it has finished with it. There is an added complexity, in that OAF also has its own pooling mechanism for the OAF Pages, which is the "Application Module pool" (AM pool). This means that although a user may have finished with a page, the page and its associated database connection are retained for a period of time.So, generally this layer would not have problem, because developer does not have to release/close connection in his code, that is automatically taken care by framework depending upon AM instance pooling and Database Connection Pooling enabled on the instance.

AOL/J JDBC code is the code that handles JDBC connection, it is often the first area to be blamed, but the JDBC connection pool can only drop database connections where the calling application has released the JDBC connection it holds in the pool, so it often turns out to be an issue higher up the code stack.This layer covers all yours JSP/JTT/JTF layer and 99% of the cases is responsible for connections leaks.

How to track leaked and locked connections?
Once you see that your instance has a problem of growing jdbc connections over a period of time all with inactive status for more than 24-48 hours, you will now start to debug and find the exact leaked and locked connections.To gather JDBC Connection statics , do following steps :
1) We need to first identify number of OACORE processes running on apps application server, then on each OACORE process we will check number of leaked locked jdbc connections in Apps instance.To note the number of OACORE processes , we need to do following in Unix box of each application server node :

(i) Login to Apps Application server unix box using ftp tool like putty.
(ii) cd $ADMIN_SCRIPTS_HOME
(iii) adoacorectl.sh status

The output will look like :

Processes in Instance:
---------------------------------+--------------------+---------+---------
ias-component | process-type | pid | status
---------------------------------+--------------------+---------+---------
OC4JGroup:default_group | OC4J:oafm | 21894 | Alive
OC4JGroup:default_group | OC4J:forms | 21861 | Alive
OC4JGroup:default_group | OC4J:oacore | 21775 | Alive
OC4JGroup:default_group | OC4J:oacore | 21776 | Alive
HTTP_Server | HTTP_Server | 21699 | Alive

From this we can analyse that there are two OCCore processes running with process id
21775 and 21776 .

Please note in case of multi-node enviorment i.e. Application server with multiple nodes,you will have to run this command individually on each node to get the OACORE process id(s) for that node.

2) Enable FND Diagnostics profile at your user level.

3) Login into Apps instance, on home page click "About This Page" link.

4)Go to subtab "Java System Properties" and note "CLIENT_PROCESSID" from the
table, this will be one of what you got in step 1.

5) Now in the url type : http://< host >:< port >/OA_HTML/jsp/fnd/AoljDbcPoolStatus.jsp

6) This will display you the list of leaked and locked connections for the process id you got in step 3. For leaked connections if you will click the hyperlink, you will also get detailed stack for each leaked connection , which can furthur help you
in identifying the code layer where connection leak is happening.


You need to repeat step (3) and (4) again and again each time logging out and closing the browser to track all the CLIENT_PROCESSID locked and leaked connections.


How to get the root cause/code that is causing this connection leak ?
Actually AoljDbcPoolStatus.jsp is the key to resolve this problem and leaked connection stack will help us to figure out our problem.We can make following conclusions from the stack :

1) The first obvious thing you will want to look at is that whether or not your custom code is causing this problem. Thats easy just search the stack with ur custom top name eg- all your extensions lie in lets say xxabc folder under $JAVA_TOP, then you can search xxabc in leak connection stack, that will give you pointers of class and code where this connection is instantiated and later not released/closed.

2) For custom and standard jsp(s), search the stack with "_" as all jsp classes in apps are compiled as "_" pre-fixed to the jsp name. So this can give you idea where and which jsp are leaking connections. In my experience, this is the layer where most developers make mistakes.

3) Lastly if not custom class then standard classes are doing this (This is a rare case), and for this you anyways just have to raise an SR with Oracle to fix this. To identify search stacks and see its coming from which module i.e., the stack will we like oracle.apps.per.xxx.yyy or oracle.apps.icx.yyy.zzzz , this simple points you that per=> HRMS or ICX=> I-procurement module standard class is causing this problem. Its always good to decompile and look at the code of these classes because often developers do invaisive customization to Oracle code, directly changing the seeded Oracle file to take easy way to their customizations , without realising that this can later cause bigger problems.

Hopefully these analysis will help you to fix root cause of connection leakage problem.

Wednesday, April 7, 2010

Adding programmatic fire Action to UIX beans which dont support it

Recently, a friend had a requirement of a customization in a seeded page where he needs to put some validation on a table column which was actually OAMessageDateFieldBean.

This is quite simple and generic requirement , when he called me ...I told him that since , this has to be done in seeded Oracle page and fire action elements can't be added by personalization,he just needs to extend the CO and attach fire action programatically to the OAMessageDateFieldBean in process request and then can handle his logic of validation in process form request.But the tricky part came when he told me his code is not compiling since setFireActionForSubmit API is absent in OAMessageDateFieldBean class.

I just wondered how is it possible since this bean allows me to configure fireaction decalaratively, then there should be an API of doing it programatically too in the bean. Then I remebered with each UIX bean Oracle also gives a helper class, which can usually be instantiated by using getHelper(), on the bean instance.

Whenever you are in such situations , its worth while to look into bean helper classes. Ok.. so here is the code how you can configure firection on OAMessageDateFieldBean programatically :

//In process request.

//getting table bean instance
OATableBean t=(OATableBean)webBean.findChildRecursive("< table bean id >");

//getting OAMessageDateFieldBean inside
//table bean
OAMessageDateFieldBean expDate = (OAMessageDateFieldBean)t.findChildRecursive("< OAMessageDateFieldBean id >");

//hard-parameters for fire action
//it will help us to identify if action
//has occured or not
Hashtable params = new Hashtable (1);
params.put ("XX_ACTION","XXX");

//bound value parameters for fire action
// basically the primary key attribute of
//VO to get the row from which action has occured
//eg, lets say the VO attribute is Visit id AND
//that is primary key
Hashtable paramsWithBinds = new Hashtable(1);
paramsWithBinds.put ("XX_PRIMARY",new OADataBoundValueFireActionURL((OAWebBeanData) expDate, "{$VisitId}"));

//Most important---
//taking helper class instance
// there we get the API to attach fire action.
expDate.getHelper().setFireActionForSubmit(expDate,"delete",params, paramsWithBinds,false,false);

//In Process form request

if(pageContext.getParameter("XX_ACTION")!=null)
{
//by this primary key we can retrieve the VO row at which
// action occured and utilise the other column data
// for validations.
String primary_key=pageContext.getParameter("XX_PRIMARY");

.......

//finally releasing the parameters from
//current pagecontext requesr
pagecontext.removeParameter("XX_ACTION");
pagecontext.removeParameter("XX_PRIMARY");
}



Alternative : There is a alternate way to attach PPR/Fireaction to any bean.Use static methods in class OAWebBeanUtils, like
OAWebBeanUtils.getFirePartialActionForSubmit()
OAWebBeanUtils.getFireActionForSubmit()
and then use

// finally set it on your bean
bean.setAttributeValue
(PRIMARY_CLIENT_ACTION_ATTR, fireAction);

Happy coding....!

Wednesday, March 17, 2010

Concept of Nested AM.

Hi All,
Writing a theoretical article after a long time. What inspired me to write.... hmm... lot of questioning developers :) . Ok, my target with this article is to make an OA Framework developer understand what is nested AM? and how can u find a nested AM instance from master/root AM instance? What we should know about it while developing extensions or new pages.

What is a Nested AM?
--------------------------------------
An application module may be a root application module or a nested application module. A root application module is not contained in another applicatin module. It provides transaction context for all objects contained in it. It may optionally contain nested application modules. A root application module is created through JNDI calls.

A nested application module is contained in another application module. The containing application module is referred to as the parent application module. If one traverses this containership ancestry, one will eventually find the root application module (which does not have a parent application module). A nested application module uses the transaction context provided by the root application module. Thus, data modifications performed in application modules parented by one root application module will commit or rollback together.

Transaction
-----------------------------
Associated with the root application module is the Transaction object, which provides this transaction context. From any (root or nested) application module, the user can retrieve the transaction object through a call to getOADBTransaction(). In reality, getOADBTransaction() first locates the root application module and then returns the transaction object from it.

The transaction object manages connection to database and entity caches. Thus, changes made through one view object are visible to other view objects as long as these view objects all parented by the one root application module. In contrast, if two view objects are parented by two separate root application modules, then changes made through the view object will not be seen by the second view object until the changes are committed to database through the first root application module and the second VO executes query (to retrieve the most up-to-date data from database).

Creating Application Module
--------------------------------------------------------------------
A root application module is created by:

Finding the application module home through JNDI.
Calling create() on the application module home.
Here is a sample code to create a root application module:

java.util.Hashtable env = new java.util.Hashtable();

// Add environment entries into env...

javax.naming.Context ic = new InitialContext(env);

// 'defName' is the JNDI name for the application module
// definition from which the root application module is to
// be created
String defName = ...;

oracle.jbo.ApplicationModuleHome home = ic.lookup(defName);
oracle.jbo.ApplicationModule am = home.create();


One creates a nested application module by calling createApplicationModule on the parent Application module.

How nested AM concept works in OAF :
---------------------------------------------------------------------------
Now to associate a nested application module with a region,
specify either of the following properties:
1) AM Instance -- The application module instance name as specified in the application module's data
model. For example, PoSummaryAM1.
2) AM Definition -- The fully qualified name of the application module instance. For example,
oracle.apps.fnd.framework.toolbox.tutorial.server.PoSummaryAM.

If you specify the AM Instance property, OA Framework attempts to find and return the AM instance with the given name. It searches the application module associated with the parent web bean.
If you specify the AM Definition property, OA Framework assigns a generated AM instance name to the nested region. This name is comprised of the following values:
a) Region code of the associated nested region (if the region was originally created in AK)
b) Nested region application ID
c) Nested region ID
d) AM definition name.

OA Framework checks to see if the nested AM with the system-generated name has been already created under the application module of the parent web bean. If the instance is not found, OA Framework creates and uses a nested AM with the system-generated name. Otherwise, it reuses the pre-existing AM with the system generated
name.


When specifying both the AM Instance and AM Definition properties
if a matching AM instance is found, OA Framework compares its definition with the AM Definition property value. If there is a mismatch, OA Framework throws an exception.
If a matching AM instance is not found, OA Framework creates and returns a nested application module instance with the given AM instance name and the definition.


Code for finding nested AM instance in root AM :
-----------------------------------------------------------------------------------
Hence, whenever you are trying to find an nested AM instance linked to a OA region under pagelayout region, please check the am defination and am instance property of that region, because only then you would be able to have a idea of name of nested AM instance. It can be system generated AM instance or name given by developer for AM instance.So, you need to confirm this from the three cases mentioned in the previous article.For debugging purposes, you can get the list if Application modules in root AM and print there names ,too :

String[] nestedAMNames = parentAM.getApplicationModuleNames();

// If you want to retrieve all currently loaded nested Application Modules
ApplicationModule[] nestedAMs = new ApplicationModule[nestedAMNames.length];

for (int i = 0; i < nestedAMNames.length; i++)
{
nestedAM[i] = parentAM.findApplicationModule(nestedAMNames[i]);
}



Otherwise for finding nested AM instance by :
ApplicationModule nestedAM = parentAM.findApplicationModule("MyNestedAM");

This concept is really helpful while doing extensions in OAF, as you may have to find a nested AM in a CO of particular OAF region.You can always find root AM of the page in any controller using pagecontext.getRootApplicationModule().

I hope after reading this article nested AM conecept becomes crystal clear in your mind :), if not raise queries, and I will try to answer you.

Wednesday, February 3, 2010

Attaching AutoSubmit Property to a OA page.

Hi All,
I recently received couple of mails where people more or less have the requirement like :
1) Data of the page gets refresh every 10 sec automatically.
2) Data of the page should be autosaved every 10 seconds etc.

This is very similar to autosave feature of microsoft word or popular email websites like yahoo and google. A small javascript function can do this for you.Here are the steps how, you can achieve this functionality in an OAF page :

/**
* @param pageContext -current page context in CO
* @param evt_name - javascript event will be registered with this name.
* @param time_in_milli_sec - time in milli sec after which page will refresh
* e.g if you wanna submit page every 10 sec , enter 10000
* This api should be used in process request and not process form request.
*/
public void attachAutoSubmitPropertyToPage(OAPageContext pageContext,
String evt_name,
String time_in_milli_sec)
{
OABodyBean bodyBean = (OABodyBean) pageContext.getRootWebBean();
String javaS =
"javascript:setTimeout(\"submitForm('DefaultFormName',0,{'" +
evt_name + "':'Y'});\"," + time_in_milli_sec + ");";
bodyBean.setOnLoad(javaS);
}

/**
* @param pageContext -current page context in CO
* @param event_name - pass javascript event name that you registered
* in process request.
* @return return true/false accordinging whether the event has occured or not.
* This api call should be there in process form request.
*/
public boolean isAutoSubmitEvent(OAPageContext pageContext,
String event_name)
{
boolean b = false;
String s =
pageContext.getRenderingContext().getServletRequest().getParameter(event_name);
if (!((s == null) || ("".equals(s.trim()))))
{
if("Y".equals(s))
{
b = true;
pageContext.removeParameter(event_name);
}
}
return b;
}

Then , in process request add the api call

public void processRequest(OAPageContext pageContext, OAWebBean webBean)
{
super.processRequest(pageContext, webBean);
// see javadocs for parameter description
//10000 for 10 sec as we are paaing in millsec
attachAutoSubmitPropertyToPage(pageContext,"XX_EVT","10000");

.
.
.
}



In process form request... you can catch this event in every 10 sec:
public void processFormRequest(OAPageContext pageContext,
OAWebBean webBean)
{
super.processFormRequest(pageContext, webBean);
.
.

if(isAutoSubmitEvent(pageContext,"XX_EVT"))
{
// YOUR LOGIC TO SAVE THE PAGE CONTENTS.
//or to refresh the data... etc
}

I hope this is interesting and will help developers of such kind of requirement.
Happy Coding..!