Thursday, March 13, 2008

ADF : Hello World Page

Hi guys,
I am back for the much discussed topic on our OAF forum regarding ADF page creation and deployment .Without wasting much time lets see how to create a very basic Hello world page and in the next article i will discuss how to deploy it.

Step 1 : I hope you have downloaded Jdev, from the link I have mentioned in my last article.

Step 2: Setup Of Jdeveloper.
a)Unzip jdevstudio10133.zip
b)Click jdeveloper.exe inside the unzopped folder to start Jdev.
c)Create a DB connection with R12 instance.(Although not required since this is a hello world page) You don't need a dbc file for ADF project. You just need to have db credentials to create DB connection.


Step 3: Create a Application, see screenshots




Enter project name and location where you wanna make this project. We will use jdev directory to hold our projects, this is not mandatory, you can have any directory for the same.Enter following details:
Application Name: Mukul_ADF_SAMPLE
Directory name : (Jdev install dir)/jdev/(project name)
See screenshot below:



Step 3: Create projects for the Application created.
When you create an application it prompts for creating a project.We are creating a project with name "Model" in the application we created.




Now since , every application can be divided into MVC-- Model, View and Controller, we will make 2 projects.One project for Model(name--"Model") and one project for View and Controller(name--"ViewController").Here are the steps for creating ViewController project in the same application:







Basically our model project will contain all objects for the model layer, i.e BC4J layer, EO, VO, VL etc.Our viewController project will contain all web realted stuff and backing beans. The role of backing beans in ADF is somewhat similar to controller in OA Framework.
In this present example we need at all create the model project,because this is just a hello world page( we are not creating any BC4J object like EO,VO etc). I have created this just give a idea how do we work on a standard project, where there would be some Model layer objects.



STEP 4:Marking projects as dependent.
Now... as I explained that one project contains all model related stuff(Model) and one project for view and controller(ViewController),so, basically we need to tell application that our view and Controller project is depedent on Model project for all data bindings. This can be done declaratively through Jdeveloper.
Right click on ViewController project and click on "project properties":



Select "Dependencies" node and click tick on "Model.jpr", as shown in screenshot below:

This will in turn update web.xml and tell project the ViewController project components are based on Model project.

STEP 5:Creating faces-config.xml
I guess the step heading sounds quite difficult.... :), like we need to write a faces-config.xml. I hope you must thank to Jdev where most of your xml code is generated through wizards.Ok, so basically this xml file holds the flow diagram of the application.Entirely different from OA Framework, ADF provides a very lucid and effective flow mechanism.Lets see how?
Right click on your ViewController project and select new... and follow as shown in screenshots to create faces-config.xml file.









STEP 6:Defining Pages and flow.
In the component pallete for faces-config.xml you can see items like jsf page, note etc, jsf navigation case etc. They signify exactly what there name signifies. We will do the follwoing:
1)Drag Note from pallete to our diagram. The purpose of note, is to make a heading or notes in the diagram.Click in the note after u have dragged it in diagram and type"Flow diagram of project".



2)Drag a JSF page into the diagram. You would be "a yellow exclamation mark on page diagram", this basically signifies that this project is still not created,so, that user should remember the which pages in the flow diagram are not created yet.



Click untitled.jspx and edit it as /apps/HelloWorldPG.jspx.



Since, in my example I am just showing one page with hello world we don't need more pages. Still, to give you a idea, we will create one more page to show how we make navigation.Hence darg one more jsf page and edit its name as shown in screenshot.



3)Now to make navigation case from helloworld page to search page, click jsf navigation in component pallette, now click on helloworld page and extending the line click on search page.You would see following screenshot:



This diagram basically tells that any action/ost event occured on helloworld page with action name "success", will forward the flow to search page. We will change name of action from "success" to"search", this is just for appropriate name puprose, you can keep any action name like xyz.



4) Now in this step we will actually create the page.Double click hello world page in the faces-config.xml diagram, you would see following screenshot:



Make sure that select jspx document and click next...



Select "Automatically Expose UI Component in new Managed Bean", this is like your controller, you want to create or not. Although we won't need this in our hello world page, but just creating this to give you an idea what this file contains. By selecting this option in wizard, any UI bean attached to page, its getters/setters are automatically exposed in your backing bean class. Edit the backing bean name as shown:



In the next screen select following libraries:
1)ADF Faces Components
2)ADF Faces HTML
3)JSF Core
4)JSF HTML

Press finish.You would see following screenshot on finishing this in Application Navigator:



You can click pkg viewcontroller.backing.apps and see the backing bean class.It will contain getters/setters for all the beans in the page.Also, every new bean you add to page, is automatically added in this class. This class will contain all controller logic and will be used to invoke any method in AM. But method here to access AM is a little different than from AM, due to fundamental differences in techstack.
Also like the methods process request and process form request, we can customise lifecycle of a JSF page, but, here its all a bit different. All these facts can be fould in ADF developer guide, I am not explaining each and every fact here, to make this article short and crisp.Main purpose of this article is to give you start with ADF, rest depends on individual effort.

STEP 7:Page UI creation.
Extend all nodes in structure window of HelloWorldPG and click h:form. In the Component pallete select "ADF Faces Core".



Drag the scrollbar down in component pallete and select PanelPage and drag and drop this mouse to h:form, here are the screenshots, how it will look like:



"PanelPage" can be considered as pagelayout region in OAF, basic page layout with header and footer. Typically every page would have this, and all regions and otems will be child of this.One feature of Jdev is that as soon as you drag and drop any item from component pallete to structure of page, you can immediately see its look and feel on the page. This nis very essential from the point of development, as you would not everytime run the page and see that what your UI look like.

Now we can edit the title of page to Hello world from property inspector as shown in figure



STEP 7:Run The page.
We are done with our hello world page. You can right click the HelloWorldPage.jspx file and click run, a new browser window will open and your page will something like:



This finishes creation of Hello world page in ADF.... and I hope this article will give u an idea of ADF to self start it. In the next article will discuss how to deploy it.You can go through ADF developers' guide and learn fundamentals.

Thursday, February 21, 2008

The Next BIG thing ADF Faces: Getting the comfort level in comparison to OAF.

Hi all.... starting with new interesting article... after I have returned from my Vaishnodevi Trip!I was thinking of writing this article from quite a some time, but was busy with various things, as I recently moved back to Delhi!

Ok, I think lets' start, as we all know Oracle Fusion techstack includes ADF faces for all web related development, I think this is the best time to optimize your skillset to ADF faces and Bpel.ADF is an extensive J2EE framework, which is
documented as well as used for two category of programmers:

1)Developers from J2EE background,i.e. people having knowldge of JSF,STRUTS,JAVASCRIPT,SWING,TOPLINKS,EJBs etc,

2)Developers from Forms background,i.e. the best suited guys are the OAF guys, who already have exposure to BC4J.Basically this category of developers, as they work on this framework, they gradually learn more and more standard J2EE technologies gradually.

In this article, I have typically covered approach for OAF developers, who I assume have a good exposure to core Java and BC4J, but have not worked/have knowledge of toplinks, ejbs',struts etc.

Here is the list of downloads, you would need to have to start with ADF Faces on your laptop/computer:

1)JDEVELOPER 10G (Download Oracle JDeveloper (10.1.3.3))
Oracle JDeveloper(10.1.3.3)

2)ADF Faces guide for forms developers (Download Developer's Guide for Forms/4GL Developers pdf version)
Download Developer's Guide for Forms/4GL Developers

3)Database server(This you would require to download, if you don't have a database server, and your working on your home pc/laptop.Download Oracle Database 10g Express Edition (Western European) )
Oracle Database 10g Express Edition

Similarities between OAF and ADF
Both OAF and ADF follow industry best pratices i.e. MVC standard(Model-View-Controller), for people who still don't have a fundamental understanding of MVC, i would suggest reading:
Article On Web-Tier Application Framework Design
Here are MVC layers of both:

OAF
--------
Model : All BC4J Component classes like AM,EO,VO,VL etc.
View : UIX
Controller : CO classes.

ADF
-----
Model : All BC4J Component classes like AM,EO,VO,VL etc.
View : JSF JSPs, in simple terms file with extension .jspx
Controller : Backing bean classes.

As we see above Model layer is same for both i.e. BC4J, hence OAF developers, have a added advantage since, working with OAF, they already have sound knowledge of this. Next comes the view layer thats changed from UIX to JSF.One major problem with UIX in OAF is that UI is not very extensive, in the sense that there are many limitations on UI front , while if you take JSF, its a Sun's standard j2ee technology where you can have all web features integrated and is also flexible enough to integrate UIs from other technologies.... like industry popular Flex, flash etc.Jsf is capable enough to deliver most complex and extensive UIs.

Now, as in OAF,most of the UI development is done through drag and drop and wizards in Jdeveloper(Or even if the page is dynamic you would write java code for adding various UIX beans to pagelayout region), hence, even if you don't have any knowledge/limited knowledge of xml and UIX, then also you can work with ease,because Jdeveloper generates the xml for you.The same is in the case of ADF, most(not all) UI development is done through wizards and drag-drop functionality in Jdeveloper.You only need to have bean level knowledge, similar to OAF.

The last layer, i.e. the controller layer is quite similar to what we code in CO classes in OAF, typically every page where you need to put event logic, you would need to attach a backing bean class to that jspx page. This can be automatically done through wizard in Jdeveloper.The backing bean class typically contain getter/setter methods of all beans in the page, so you can add your custom event methods to this class which will be attached to UI through EL.

I think by now you would have developed some comfort level with ADF! One stunning feature of ADF are the flow diagrams, like in OAF to redirect to diffent page you use vaious page forward apis' in pageContext class.In ADF, you can design the whole flow in flow-diagram, which is a completely drag and drop feature of Jdeveloper ad then attach it with action of any bean say a "command button", on whose submission you want to redirect the flow.

To start with example, Oracle provides a fantastic tutorial called SRDEMO. You can run it on your Jdev, read the guide and get aquittaned with ADF.

Recently, there was a discussion on "OAF Forum" regarding "Can ADF Faces/ADF BC aplications developed on Jdeveloper 10g can be deployed on Apps 11i?".
Here is the Steven Chan's blog comments link which gives you the answer:
Read last question on this link.

He basically says "The E-Business Suite 11.5.10.2 uses Oracle9i Application Server 1.0.2.2.2 as its application tier server. You cannot use this to run externally-developed applications.

I would recommend running your custom application on an external Oracle Application Server 10g instance.
"

Another point is pointed by Tapash for Apache Jserv application server used in Oracle Apps 11i, he says "Apache JServ module , QApache are servers built at oracle not totally open sourced, so these are not pure J2EE servers, although you can run some J2EE components like jsps/servlets/EJBs, but these servers dont have containers for all J2EE components.". So, i would say Apache name is misleading, because Apache.org things immediately flicks my mind saying open source :)!

Hence, for Apps 11i version ADF faces can't be atleast in straight forward way be deployed. If you are using Apps 11i version , you should use external J2ee compliant server, like Apache Tomcat,OC4J etc. for hosting your ADF Faces/ ADF BC application.
This is not the case with Apps R12, which is a j2ee compliant server, hence you can deploy all ur ADF faces applications on the same application server.This is because of the fact Oracle has moved to OC4J application server with R12.


I hope I am able to give some picture of vast ADF to OAF developer community through this article!I will soon write another article of making a sample page in ADF and integrating it with OAF/JTT/JTF pages in Apps.

Friday, December 28, 2007

Passing pl/sql table to Java using Oracle JDBC and vice - versa

While replying several threads on OA Forums(http://forums.oracle.com/forums/forum.jspa?forumID=210), I have seen couple of threads where developers have a requirement to pass a pl/sql table to OA Framework Page and vice-versa.Even if people copy paste this code from google. oracle or other available sources, they are not sure what actually they are doing!
Actually the best practice for such a requirement is to use Rosetta to generate class file for the particular pl/sql pkg.But the point is Rosetta is Oracle's internal tool and Oracle does not ship it to customers.Then also,I have seen it to be used in consulting industry, very often, i don't know how :)!But if u don't have rosetta, u don't have an option that to go with jdbc, which is anyways base of Oracle and Java bridge.When talking of JDBC, there is two set of JDBC classes popular in market, one from SUN(Founder of Java)and Oracle.Oracle jdbc wrapper classes are better in the sense, that they are flexible enough to cater almost all pl/sql objects.
Ok, so if you are not using Rosetta, then how would u pass pl/sql table to Java using Oracle JDBC and vice - versa?Recently was helping a friend in this code, had to some struggle for this code , so thought to put it on my blog, so that would help other developers with similar requirement.

So, lets start:
Read comments carefully to understand the code

1)Define Object with the same structure as your table of records u need to use in ur pl/sql procedureof some pkg.Remember define it as global object type and not inside package specification, because in that case our jdbc code would not be to find this object type.
/******************************************************************************/
/*The Script used to create Object type in this example is as follows:*******/
/******************************************************************************/
create or replace type rectype as object(col1 varchar2(10),col2 Date,col3 Number);



2)Define table of object u have defined above which u need to use in ur pl/sql procedure of some pkg.Remember define it as global table type and not inside package specification, because in that case our jdbc code would not be to find this object type.
/******************************************************************************/
/*The Script used to create table of Object type is as follows:*******/
/******************************************************************************/
create or replace type rectab as table of rectype;


3)Defining package specification and procedure definition
/*********************************************************************************/
/*The Script used to create package specification in this eg.is as follows:*******/
/******************************************************************************/

create or replace package ioStructArray as
procedure testproc(iorec in rectab,orec out rectab);
end ioStructArray;
/



4)Defining package body and procedure
/*********************************************************************************/
/*The Script used to create package specification in this eg.is as follows:*******/
/******************************************************************************/
create or replace package body ioStructArray as
procedure testproc(iorec in rectab,orec out rectab) is
begin
/*see how to loop and assign values*/
for i in 1..iorec.count loop
iorec(i).col1 := orec(i).col2;
iorec(i).col2 := orec(i).col1;
end loop;
end testproc;
end ioStructArray;
/

5)Getting connection object in JDBC Code :
//Getting db connection in a jdbc
DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver());
// Connect to the database
Connection conn=DriverManager.getConnection ("jdbc:oracle:oci8:@S692815.WORLD",
"scott", "tiger");



6)If writing in AM in OAF page, code to get connection:
OADBTransactionImpl oadbtransactionimpl = (OADBTransactionImpl)getOADBTransaction();
OracleConnection conn = (OracleConnection)oadbtransactionimpl.getJdbcConnection();

7)Lets, consider a simple scenario where we have a XXVO in AM and I have to pass all VO rows data to the pl/sql procedure we just created and then receieve a table of data back and then based on it values do something in AM.Here is the Code:
//imports
import oracle.sql.*;
import oracle.jdbc.driver.OracleConnection;
import oracle.jdbc.driver.OracleCallableStatement;
import oracle.apps.fnd.framework.server.OADBTransaction;
import oracle.apps.fnd.framework.server.OADBTransactionImpl;

Public void arryToPLSQL()
{
//Getting Db connection
OADBTransactionImpl oadbtransactionimpl = (OADBTransactionImpl)getOADBTransaction();
OracleConnection conn = (OracleConnection)oadbtransactionimpl.getJdbcConnection();

//Defining variables

//oracle.sql.ARRAY we will use as out parameter from the package
//and will store pl/sql table
ARRAY message_display = null;

//ArrayList to store object of type struct
ArrayList arow= new ArrayList();

//StructDescriptor >> use to describe pl/sql object
//type in java.
StructDescriptor voRowStruct = null;

//ArrayDescriptor >> Use to describe pl/sql table
//as Array of objects in java
ArrayDescriptor arrydesc = null;

//Input array to pl/sql procedure
ARRAY p_message_list = null;

//Oracle callable statement used to execute procedure
OracleCallableStatement cStmt=null;

try
{
//initializing object types in java.
voRowStruct = StructDescriptor.createDescriptor("RECTYPE",conn);
arrydesc = ArrayDescriptor.createDescriptor("RECTAB",conn);
}

catch (Exception e)
{
throw OAException.wrapperException(e);
}

for(XXVORowImpl row = (XXVORowImpl)XXVO.first();
row!=null;
row = (XXVORowImpl)XXVO.next())
{
//We have made this method to create struct arraylist
// from which we will make ARRAY
//the reason being in java ARRAY length cannot be dynamic
//see the method defination below.
populateObjectArraylist(row,voRowStruct,arow);
}

//make array from arraylist
STRUCT [] obRows= new STRUCT[arow.size()];
for(int i=0;i < arow.size();i++)
{
obRows[i]=(STRUCT)arow.get(i);
}

try
{
p_message_list = new ARRAY(arrydesc,conn,obRows);
}
catch (Exception e)
{
throw OAException.wrapperException(e);
}

//jdbc code to execute pl/sql procedure
try
{
cStmt
=(OracleCallableStatement)conn.prepareCall("{CALL ioStructArray.testproc(:1,:2)}");
cStmt.setArray(1,p_message_list);
cStmt.registerOutParameter(2,OracleTypes.ARRAY,"RECTAB");
cStmt.execute();

//getting Array back
message_display = cStmt.getARRAY(2);
//Getting sql data types in oracle.sql.datum array
//which will typecast the object types
Datum[] arrMessage = message_display.getOracleArray();

//getting data and printing it
for (int i = 0; i < arrMessage.length; i++)
{
oracle.sql.STRUCT os = (oracle.sql.STRUCT)arrMessage[i];
Object[] a = os.getAttributes();
System.out.println("a [0 ] >>attribute1=" + a[0]);
System.out.println("a [1 ] >>attribute2=" + a[1]);
System.out.println("a [2 ] >>attribute3=" + a[2]);
//You can typecast back these objects to java object type


}

}
catch (Exception e1)
{
throw OAException.wrapperException(e1);
}
}



/*Our custom method which will populate
arraylist with struct object type
*/
public void populateObjectArraylist( XXVORowImpl row,StructDescriptor voRowStruct , ArrayList arow)
{
Object[] attribMessage = new Object[3];
String attr1 = null;
Date attr2 = null;
Number attr3 = null;

//Get value from Vo row and put in attr1,att2 and attr 3

//Putting values in object array
attribMessage[0]=attr1;
attribMessage[1]=attr2;
attribMessage[2]=attr3;

try
{
STRUCT loadedStructTime = new STRUCT(voRowStruct, conn, attribMessage);
arow.add(loadedStructTime);
}
catch (Exception e)
{
}

}

So, i hope every step is clear in the above code. I hope it helps all OAF developer community.Special Thanks to Pooja Arora for her contribution and constantly bugging me to fix this!

Sunday, December 16, 2007

PPR-- An insight !

PPR or Partial Page Rendering is one of the most attractive feature put up by Oracle in 11.5.10 release of Oracle Apps, or OA Famework.
Although most of OAF developer community use this feature, i think very few would have idea, how excatly it works in UIX.PPR uses Ajax kind of design and hence very attractive to use, because it can put dynamic features in various UIX beans, without the use of any client side script like javascript, which is otherwise a integral part of any web application. PPR events are very fast as they refresh only a particular region or protion of page and no the entire page.

Developers that want to add such behaviors to their web pages are often faced with a difficult decision. All of these actions can be implemented using a very simple solution: by refreshing the entire page in response to the user interaction. However easy, this solution is not always desirable. The full page refresh can be slow, giving the user the impression that the application is unresponsive. Another option is to implement such actions using JavaScript (or other client-side scripting technologies). This results in faster response times, at the expense of more complex, less portable code. JavaScript may be a good choice for simple actions, such as updating an image. However, for more complicated actions, such as scrolling through data in a table, writing custom JavaScript code can be a very challenging undertaking.

Oracle UIX provides another solution which avoids some of the drawbacks of the full page refresh and custom JavaScript solutions: partial page rendering (or PPR for short). The UIX partial page rendering functionality provides the ability to re-render a limited portion of a page. As in the full page render solution, PPR sends a request back to the application on the middle-tier to fetch the new contents. However, when PPR is used to update the page, only the modified contents are sent back to the browser. UIX automatically merges the new contents back into the web page. The end result is that the page is updated without custom JavaScript code, and without the loss of context that typically occurs with a full page refresh.

How Partial Page Rendering Works
The partial page rendering process breaks down into three main areas: the partial page event, the partial page rendering pass, and the partial page replacement.

The partial page event is the request that the browser sends to the application to request new contents. Partial page events are very similar to their full page event equivalents. For example, when the user navigates to a new record set in a table bean, a goto event with a value event parameter is sent to the application regardless of whether the event is a partial or full page event. There are two important differences between partial and full page events. First, partial page events specify partial page rendering-specific event parameters which are not present on the full page event equivalents. For example, partial page events may include an event parameter which identifies the set of nodes that should be re-rendered (referred to as "partial targets"). The second difference between partial page events an full page events is how the events are sent.

Unlike full page events, partial page events must be sent in a way which does not force the browser to reload the current page. To implement this capability, UIX partial page rendering uses a hidden inline frame (iframe) as a communication channel between the browser and the web application running on the middle-tier. Partial page events are sent by forcing a navigation in the hidden iframe, which in turn causes a request to be sent to the application on the middle-tier. Since the iframe is hidden, the process of sending a partial page event and rendering partial page contents can take place behind the scenes, without discarding the contents of the current page.

When the partial page event is received by the application, the application responds by determining the set of partial targets to render and performing the partial page rendering pass. The partial page rendering pass is similar to a full page rendering pass. In both cases, the UINode tree is traversed by calling render() on each node in the tree. However, in the partial page rendering case, only the contents generated by the partial targets are actually sent back to the browser. All other contents are dropped. So, although the scope of a partial page rendering pass and full page rendering pass are similar in the number of UINodes that are rendered, the partial page response is generally much smaller, since only the modified contents are sent back to the browser.

The final part of the PPR process is the partial page replacement. When the browser receives the partial page response, the new contents for each partial target node are copied from the hidden iframe into the main browser window, replacing the existing contents for each target node. So, for example, in the table navigation case, rather than replacing the entire page, just the contents of the table itself are replaced. The browser reflows in response to the modifications, displaying the new contents to the user without fully re-rendering the entire page.

To recap, the sequence of steps which occur during a partial page render are:

The initial page is rendered.
The user performs some action which triggers a partial page render, for example clicking on a link or button.
JavaScript event handlers provided by UIX force a navigation in a hidden iframe.
The partial page event is sent to the application.
The application determines whether the request is a partial page event and which partial target nodes to re-render.
The partial page rendering pass is performed.
The contents of the partial target nodes are sent back to the iframe in the browser.
The partial page replacement is performed, at which point the new contents are copied from the iframe into the main browser window.
The browser re-flows and displays the new content to the end user.
Note that the partial page rendering process requires no custom JavaScript code.
(The source of this article is Oracle UIX documentation.)

Wednesday, November 21, 2007

What the hell is JVM , Session , Cache ?

From quite some days, I find threads on OAF Forums, where people could not understand the basic terminology of J2EE like session,JVM , Oracle user session, cache etc. I think these terms are not new for people from Java background, but for people who come from pl/sql background or not from Java background, these terms might look like hammers.I remember one thread where I and Tapash were replying somebody asked whats' the difference between ICX session and http session, I wanted to reply, but I thought, replying there would make thread too long, i guess that thread already crossed 4 pages and replying there may not reach to all target audience.
So, I decided to write a small article for the same..... and in fact I must say my article is nothing but compilation of information from OAF Developer's guide , googling , metalink, blogs and lastly my knowledge....[You must be doubting on the last point.... even i am :)]

So, lets start with basic terminalogy:

About JVM
At the heart of the Java platform lies the Java Virtual Machine, or JVM. Most programming languages compile source code directly into machine code, suitable for execution on a particular microprocessor architecture. The difference with Java is that it uses bytecode - a special type of machine code.
Java bytecode executes on a special type of microprocessor. Strangely enough, there wasn't a hardware implementation of this microprocessor available when Java was first released. Instead, the processor architecture is emulated by what is known as a "virtual machine". This virtual machine is an emulation of a real Java processor - a machine within a machine (Figure One). The only difference is that the virtual machine isn't running on a CPU - it is being emulated on the CPU of the host machine.



The Java Virtual Machine is responsible for interpreting Java bytecode, and translating this into actions or operating system calls. For example, a request to establish a socket connection to a remote machine will involve an operating system call. Different operating systems handle sockets in different ways - but the programmer doesn't need to worry about such details. It is the responsibility of the JVM to handle these translations, so that the operating system and CPU architecture on which Java software is running is completely irrelevant to the developer.



The Java Virtual Machine forms part of a large system, the Java Runtime Environment (JRE). Each operating system and CPU architecture requires a different JRE. The JRE comprises a set of base classes, which are an implementation of the base Java API, as well as a JVM. The portability of Java comes from implementations on a variety of CPUs and architectures. Without an available JRE for a given environment, it is impossible to run Java software.
Differences between JVM implementations
Though implementations of Java Virtual Machines are designed to be compatible, no two JVMs are exactly alike. For example, garbage collection algorithms vary between one JVM and another, so it becomes impossible to know exactly when memory will be reclaimed. The thread scheduling algorithms are different between one JVM and another (based in part on the underlying operating system), so that it is impossible to accurately predict when one thread will be executed over another.
Initially, this is a cause for concern from programmers new to the Java language. However, it actually has very little practical bearing on Java development. Such predictions are often dangerous to make, as thread scheduling and memory usage will vary between different hardware environments anyway. The power of Java comes from not being specific about the operating system and CPU architecture - to do so reduces the portability of software.

Summary

The Java Virtual Machine provides a platform-independent way of executing code, by abstracting the differences between operating systems and CPU architectures. Java Runtime Environments are available for a wide variety of hardware and software combinations, making Java a very portable language. Programmers can concentrate on writing software, without having to be concerned with how or where it will run. The idea of virtual machines is nothing new, but Java is the most widely used virtual machine used today. Thanks to the JVM, the dream of Write Once-Run Anywhere (WORA) software has become a reality.

JVM Cache and Its impelemetation in Oracle Apps:

Qestions like what is cache? How is it related to JVM? How is caching implementated in Oracle Apps?Instead of me explaining this, it would be best if you go through the brilliant explanation by Mike Shaw on Steven Chan’s blog.Here is the link:
Mike Shaw's article about JVM Cache


HTTP SESSION

HttpSession is nothing but a java interface.The servlet container uses this interface to create a session between an HTTP client and an HTTP server.
The session persists for a specified time period, across more than one connection or page request from the user. A session usually corresponds to one user,
who may visit a site many times. The server can maintain a session in many ways such as using cookies or rewriting URLs.
This interface allows servlets to View and manipulate information about a session, such as the session identifier, creation time, and last accessed time
Bind objects to sessions, allowing user information to persist across multiple user connections.

ICX Session or Oracle Applications User Session
(Is it same as HTTP session/servelet session ?)


A http session or a servelet session usually corresponds to an application login/logout cycle, but that is not strictly true in the case of OA Framework applications.I tell u y ? When the user logs in to an OA Framework application, the OA Framework creates an AOL/J oracle.apps.fnd.common.WebAppsContext object and a browser session-based cookie that together keep track of key Oracle Applications context information like the current responsibility, organization id and various user attributes such as user name, user id,
employee id and so on.
The cookie contains an encrypted key identifier for a session row stored in the Applications database.Specifically, this is the servlet session ID which, in its decrypted form, serves as the primary key in the
ICX_SESSIONS table.(to get an idea do run Select * from ICX_SESSIONS , to get an exact idea of what information is stored in the table)
The WebAppsContext retrieves this key value after each request and uses it to query the current session state.
The Oracle Applications user session or ICX SESSION is associated and not dependent with a servlet session, because , it has its own life cycle and time-out characteristics. Generally, the Oracle Applications user session has a longer life span than the servlet session. The servlet session should time-out sooner.

User session is dependent on following profiles:

a)ICX: Limit Time :Determines the maximum Oracle Applications user session length( in
hours.

b)ICX:Session Timeout: Maximum idle time for the Oracle Applications user session
(specified in minutes).

While servelet session timeout is purely dependent on setting in Apache Jserv session timeout setting.

An Oracle Applications user session might be associated with multiple http servlet sessions. For example, the servlet session times out
while the user takes a phone call in the middle of creating an OA Framework expense report, then resumes work before the Oracle Applications user session
times out.If the Oracle Applications user session times out, aslong as the user does not close the browser window (so the browser session-based cookie isn't
lost) and no one deletes the corresponding session row in the ICX_SESSIONS table, the user can resume her transaction at the point where he stopped working
after being prompted to log back in.
Although the best practice as per Oracle standards is to sync ICX_SESSION and servelet session,till passivation feature is implenented in Oracle Apps. Passivation is still not supported in 11i and 12i.


This is straight from metalink “The ICX: Session Timeout option sets the the maximum number of minutes to wait before invalidating an idle ICX Session. The default value is null. The web server session timeout value, or more appropriately the Apache Jserv Session value is used to specify the number of milliseconds to wait before invalidating an unused session. The default value is 1800000 or 30 minutes.
We recommend that you set the ICX: Session Timeout and the Apache Jserv Session to be the same. It's better to be consistent and let the ICX session and the Apache Jserv (middle tier) session expire at the same time. If the ICX session expires before the Jserv session, the user will be presented with a login page even though the Jserv session is still active. If the user logs back in before the Jserv session expires, they will see the old state of their middle-tier transaction. This can be confusing, since from the point of view of the user there is no distinction between the ICX session and the Jserv session.
We also recommend that you do not set the Apache Jserv Session timeout to be any higher than 30 minutes. Longer idle sessions will drain the JVM resources and can also cause out of memory errors.
The session timeout for the webserver is specified via the following directive in the /Jserv/etc/zone.properties file.
session. timeout=1800000”


I think by now you must be crystal in ur understanding of basic key terms in J2EE.I would like to stress on one thing... JVM cache is shared across servelet/http sessions , and is purely dependent on first login, it can be removed progrmatically by invalidating the cache or by bouncing the apache server.

Any doubts or queries are welcome!

Friday, November 2, 2007

Setting the default selected date for an OAMessageDateFieldBean

I have seen couple of threads in recent past on OA Forums about setting default value in OAMessageDateFieldBean, so, did a little R n D :) on OAMessageDateFieldBean.

OAMessageDateFieldBean in framework, u will find its nothing but a onClick js event is called on the imageicon attached with messagetextinput bean(in case the type is Date) and OAInlineDatePickerBean is opened in a modal js window.

Setting deafult date in the OAMessageDateFieldBean, also sets the OAInlineDatePickerBean , as it takes the default value from OAMessageDateFieldBean.
So, here is code for setting/getting value both in both in OAMessageDateFieldBean and OAInlineDatePickerBean :
import java.sql.Date;
import java.text.SimpleDateFormat;
java.sql.Timestamp;

//defining format of date
SimpleDateFormat f = new SimpleDateFormat("mm/dd/yyyy");
//define date as string
String dateString = "06/30/1984";
//defining new java.sql.date
Date sqlDate=new Date(f.parse(dateString).getTime());


OAMessageDateFieldBean dateField = (OAMessageDateFieldBean)webBean.findIndexedChildRecursive();
dateField.setValue(pageContext,sqlDate);


//getting oracle.jbo.domain.Date object from OAMessageDateFieldBean
//in process form request
Timestamp ts = (Timestamp)dateField.getValue(pageContext);
System.out.println(ts.getTime());
java.sql.Date select = new java.sql.Date(ts.getTime());
oracle.jbo.domain.Date sd=new oracle.jbo.domain.Date(select);

//You can also set min Value and Max value in OAMessageDateFieldBean which
//will also be set in OAInlineDatePickerBean
//Here is code
dateField.setMinValue(minDate);
dateField.setMaxValue(maxValue);


I hope this helps all.

Tuesday, September 25, 2007

Implementing a simple watch in a OA Framework Page

I hope this is interesting ... implementing a watch in OA Framework page.There can be several other functionalities, one can do after implementing this watch.Here i am just writing a simple function for javascript watch,you can take an idea.... and change this function accordingly.

Just read this function.....

/* Here is the javascript function, which is self explainatory
Read this function carefully
to understand it.*/

function update()
{
//Define a new date object
var today=new Date();

var hours=today.getHours();
var minutes=today.getMinutes();
var seconds=today.getSeconds();

//for formatting output
if (hours<10)
hours="0"+hours;
if (minutes<10)
minutes="0"+minutes;
if (seconds<10)
seconds="0"+seconds;

//writing output to message text input
document.getElementByID('OAclockDisplay').value=hours+":"+minutes+":"+seconds;

//refreshing ever sec
setTimeout("update()",1000);
}

I hope this clear. Now here are the steps how you can put it in your OA Framework page.Add a message text input to your page, say its id is "OAclockDisplay".

Now add this code in process request of controller of page:

//storing javascript function is a string
// "\" is used as escape character
String s="function update(){var today=new Date();var hours=today.getHours();var minutes=today.getMinutes();var seconds=today.getSeconds();if(hours<10){hours=\"0\"+hours;} if(minutes<10){minutes=\"0\"+minutes;} if(seconds<10){seconds=\"0\"+seconds;} document.getElementById('OAclockDisplay').value=hours+\":\"+minutes+\":\"+seconds;setTimeout(\"update()\",1000);}";

//getting body bean
OABodyBean bodyBean = (OABodyBean)pageContext.getRootWebBean();

//attaching javascript function to page
pageContext.putJavaScriptFunction("update",s);

// calling this function on load of body bean
String javaS = "javascript:update();";
bodyBean.setOnLoad(javaS);

We are done, run this page you will be able to see a watch in oa framework page in that particular message text input.
Cheers!