Saturday, June 6, 2009

Error while running a OAF page with 12.1.1 (jdeveloper patch 8431482

We recetly migrated to newly released on Oracle apps R12.1.1.We tried using jdeveloper with patch 8431482 which is mentioned in metalink Doc Id 416708.1.We got following error stack:
Error Page
Exception Details.
oracle.apps.fnd.framework.OAException: Application: FND, Message Name: FND_GENERIC_MESSAGE. Tokens: MESSAGE = java.lang.NullPointerException;
at oracle.apps.fnd.framework.OAException.wrapperException(Unknown Source)
at oracle.apps.fnd.framework.CreateIcxSession.getEncryptedSessId(Unknown Source)
at oracle.apps.fnd.framework.CreateIcxSession.createSession(Unknown Source)
at _runregion._jspService(_runregion.java:132)
at com.orionserver.http.OrionHttpJspPage.service(OrionHttpJspPage.java:59)
at oracle.jsp.runtimev2.JspPageTable.service(JspPageTable.java:462)
at oracle.jsp.runtimev2.JspServlet.internalService(JspServlet.java:594)
at oracle.jsp.runtimev2.JspServlet.service(JspServlet.java:518)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:856)
at com.evermind.server.http.ServletRequestDispatcher.invoke(ServletRequestDispatcher.java:713)
at com.evermind.server.http.ServletRequestDispatcher.forwardInternal(ServletRequestDispatcher.java:370)
at com.evermind.server.http.HttpRequestHandler.doProcessRequest(HttpRequestHandler.java:871)
at com.evermind.server.http.HttpRequestHandler.processRequest(HttpRequestHandler.java:453)
at com.evermind.server.http.HttpRequestHandler.serveOneRequest(HttpRequestHandler.java:221)
at com.evermind.server.http.HttpRequestHandler.run(HttpRequestHandler.java:122)
at com.evermind.server.http.HttpRequestHandler.run(HttpRequestHandler.java:111)
at oracle.oc4j.network.ServerSocketReadHandler$SafeRunnable.run(ServerSocketReadHandler.java:260)
at oracle.oc4j.network.ServerSocketAcceptHandler.procClientSocket(ServerSocketAcceptHandler.java:239)
at oracle.oc4j.network.ServerSocketAcceptHandler.access$700(ServerSocketAcceptHandler.java:34)
at oracle.oc4j.network.ServerSocketAcceptHandler$AcceptHandlerHorse.run(ServerSocketAcceptHandler.java:880)
at com.evermind.util.ReleasableResourcePooledExecutor$MyWorker.run(ReleasableResourcePooledExecutor.java:298)
at java.lang.Thread.run(Thread.java:595)
## Detail 0 ##
java.lang.NullPointerException
at oracle.apps.fnd.security.SessionManager.recordSuccess(SessionManager.java:3820)
at oracle.apps.fnd.security.SessionManager.validateLogin(SessionManager.java:2082)
at oracle.apps.fnd.security.SessionManager.validateLogin(SessionManager.java:1946)
at oracle.apps.fnd.framework.CreateIcxSession.getEncryptedSessId(Unknown Source)
at oracle.apps.fnd.framework.CreateIcxSession.createSession(Unknown Source)
at _runregion._jspService(_runregion.java:132)
at com.orionserver.http.OrionHttpJspPage.service(OrionHttpJspPage.java:59)
at oracle.jsp.runtimev2.JspPageTable.service(JspPageTable.java:462)
at oracle.jsp.runtimev2.JspServlet.internalService(JspServlet.java:594)
at oracle.jsp.runtimev2.JspServlet.service(JspServlet.java:518)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:856)
at com.evermind.server.http.ServletRequestDispatcher.invoke(ServletRequestDispatcher.java:713)
at com.evermind.server.http.ServletRequestDispatcher.forwardInternal(ServletRequestDispatcher.java:370)
at com.evermind.server.http.HttpRequestHandler.doProcessRequest(HttpRequestHandler.java:871)
at com.evermind.server.http.HttpRequestHandler.processRequest(HttpRequestHandler.java:453)
at com.evermind.server.http.HttpRequestHandler.serveOneRequest(HttpRequestHandler.java:221)
at com.evermind.server.http.HttpRequestHandler.run(HttpRequestHandler.java:122)
at com.evermind.server.http.HttpRequestHandler.run(HttpRequestHandler.java:111)
at oracle.oc4j.network.ServerSocketReadHandler$SafeRunnable.run(ServerSocketReadHandler.java:260)
at oracle.oc4j.network.ServerSocketAcceptHandler.procClientSocket(ServerSocketAcceptHandler.java:239)
at oracle.oc4j.network.ServerSocketAcceptHandler.access$700(ServerSocketAcceptHandler.java:34)
at oracle.oc4j.network.ServerSocketAcceptHandler$AcceptHandlerHorse.run(ServerSocketAcceptHandler.java:880)
at com.evermind.util.ReleasableResourcePooledExecutor$MyWorker.run(ReleasableResourcePooledExecutor.java:298)
at java.lang.Thread.run(Thread.java:595)
java.lang.NullPointerException
at oracle.apps.fnd.security.SessionManager.recordSuccess(SessionManager.java:3820)
at oracle.apps.fnd.security.SessionManager.validateLogin(SessionManager.java:2082)
at oracle.apps.fnd.security.SessionManager.validateLogin(SessionManager.java:1946)
at oracle.apps.fnd.framework.CreateIcxSession.getEncryptedSessId(Unknown Source)
at oracle.apps.fnd.framework.CreateIcxSession.createSession(Unknown Source)
at _runregion._jspService(_runregion.java:132)
at com.orionserver.http.OrionHttpJspPage.service(OrionHttpJspPage.java:59)
at oracle.jsp.runtimev2.JspPageTable.service(JspPageTable.java:462)
at oracle.jsp.runtimev2.JspServlet.internalService(JspServlet.java:594)
at oracle.jsp.runtimev2.JspServlet.service(JspServlet.java:518)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:856)
at com.evermind.server.http.ServletRequestDispatcher.invoke(ServletRequestDispatcher.java:713)
at com.evermind.server.http.ServletRequestDispatcher.forwardInternal(ServletRequestDispatcher.java:370)
at com.evermind.server.http.HttpRequestHandler.doProcessRequest(HttpRequestHandler.java:871)
at com.evermind.server.http.HttpRequestHandler.processRequest(HttpRequestHandler.java:453)
at com.evermind.server.http.HttpRequestHandler.serveOneRequest(HttpRequestHandler.java:221)
at com.evermind.server.http.HttpRequestHandler.run(HttpRequestHandler.java:122)
at com.evermind.server.http.HttpRequestHandler.run(HttpRequestHandler.java:111)
at oracle.oc4j.network.ServerSocketReadHandler$SafeRunnable.run(ServerSocketReadHandler.java:260)
at oracle.oc4j.network.ServerSocketAcceptHandler.procClientSocket(ServerSocketAcceptHandler.java:239)
at oracle.oc4j.network.ServerSocketAcceptHandler.access$700(ServerSocketAcceptHandler.java:34)
at oracle.oc4j.network.ServerSocketAcceptHandler$AcceptHandlerHorse.run(ServerSocketAcceptHandler.java:880)
at com.evermind.util.ReleasableResourcePooledExecutor$MyWorker.run(ReleasableResourcePooledExecutor.java:298)
at java.lang.Thread.run(Thread.java:595)

We raised an SR with Oracle and they have responded back saying : Set profile "Sign-On:Notification" to "No" at site level, which resloves the issue and jdev works fine.
Hope this helps all, which are trying to use patch 8431482 for Apps 12.1.1.

Friday, June 5, 2009

Custom Logging in Java Layer in Oracle Applications R12

Hi All,
I have often felt for years simple SOP (System.out.Println) is the best way of debugging in java/j2ee applications. I have the evil habit.. of putting lots of SOPs while writing code for OAF or ADF or simple j2ee applications. I generally create a method with sop in it eg:

private void putLog(Object o)
{
System.out.println(o);
}

and call it with the code wherever required. The benefit is at the point of deployment of code, i just need to change this method from sop to writeDiagnostics().The worst part of diagnostic logging is when you enable logging on the Applications... "Show Log On Screen", it shows so many logs apart from my custom log statements, that its really difficult to debug.

The other standard way of debugging java code on server is using OACore log in OC4J server.In R12,
Goto $ORA_CONFIG_HOME/10.1.3/opmn/conf
take the backup of opmn.xml
edit opmn.xml for data id="java-options" and add the following:
-DAFLOG_ENABLED=true -DAFLOG_LEVEL=statement
-DAFLOG_MODULE=fnd%
-DAFLOG_FILENAME=/tmp/aflog.txt -Djbo.debugoutput=console

The log message should get written in,
$INST_TOP/logs/ora/10.1.3/opmn/oacore_default_group_1/oacorestd.out

But for this my code should contain SOPs, which is also a problem, because I don't wanna SOPs in my code after deployment on server, as SOPs have huge impact on performance.

So, I need a way (probably a magic .... :) )that my debug statements become SOPs when I run my code in jdeveloper automatically, and when I run the same code in server, these statements should go in a text file if I enable logging on server, lets' say we make it dependent on a profile , so that I can also disable these statements/logging in production just by changing profile value.

Ok so make this magic or logic happen I used a trick and have written a custom logger class with static methods, let see how this class works.Ok for making this logging happen follow these steps:

STEP1
-------------
Copy this class and put in any pkg under custom directory in java top, like I have used package xx.oracle.apps.ak.logging. Replace this pkg name with the pkg u want to put this class in.

package xx.oracle.apps.ak.logging;

import java.awt.Toolkit;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintStream;
import oracle.apps.fnd.framework.OAException;
import oracle.apps.fnd.framework.server.OADBTransaction;
import oracle.apps.fnd.framework.webui.OAPageContext;
import java.io.PrintWriter;
import oracle.apps.fnd.common.WebAppsContext;
public class XxLogger
{
public XxLogger()
{
}

public static void putLog(OADBTransaction ot, Object o)
{
printLog(ot, null, null, null, o);
}

public static void putLog(OAPageContext pageContext, Object o)
{
printLog(null, null, pageContext, null, o);

}

public static void putLog(WebAppsContext ctx, Object o)
{
printLog(null, ctx, null, null, o);

}

public static void printLog(OADBTransaction ot, WebAppsContext ctx,
OAPageContext pageContext, Exception exp,
Object o)
{
FileOutputStream outFile = null;
try
{
//this line should throw headless exception on server
//due to opmn.xml configuration for oc4j node.
//and would work fine in local jdev
Toolkit.getDefaultToolkit().getScreenSize();
if (o == null)
{
exp.printStackTrace();
}
else
{
System.out.println(o);
}
}
catch (Exception e)
{
try
{
String profile = null;
if (ot != null)
{
profile = ot.getProfile("XX_LOG");
}
else if (pageContext != null)
{
profile = pageContext.getProfile("XX_LOG");
}
else if (ctx != null)
{
profile = ctx.getProfileStore().getProfile("XX_LOG");
}
if ((profile == null) || ("".equals(profile)))
{
//No logging

}
else
{
outFile = new FileOutputStream(profile + "/xx_log.log", true);
PrintStream ps = new PrintStream(outFile);

if (exp != null)
{
ps.append(new java.util.Date().toString() + " : " +
"*************************************Exception Details*****************************");
ps.append(" \n ");
exp.printStackTrace(ps);
ps.append("*************************************Exception Details End *****************************");

}
else
{
ps.append(new java.util.Date().toString() + " : " + o);
}
ps.append(" \n ");
}
}
catch (FileNotFoundException f)
{
// TODO
e.printStackTrace();
}
}
}


public static void printStack(OADBTransaction ot, Exception e)
{
printLog(ot, null, null, e, null);
}


public static void printStack(WebAppsContext ctx, Exception e)
{
printLog(null, ctx, null, e, null);
}


public static void printStack(OAPageContext pageContext, Exception e)
{
printLog(null, null, pageContext, e, null);
}

}

STEP2
----------
Now create a custom profile which will store path of log file we want to get generated,please note if this profile value is null then no log will be generated.Replace the profile name with "XX_LOG" in the code at all 3 places.

STEP3
========
set the profile value to the path where you wanna log file to be generated.Also please note you would have to manually create "xx_log.log" file there for the first time(for that just create a simple fie and rename as "xx_log.log"), this I have done purposely in code, so that even if by mistake profile value is not null in production, no log should be generated.

STEP 4
===========
Use this logging in OAF/JTT/JTF/JSP file :

In CO
========
XxLogger.putLog(OAPageContext pageContext, Object o)

In AM,VO,EO
============
XxLogger.putLog(OADBTransaction ot, Object o)


In JTT/JTF
============
import oracle.apps.fnd.common.WebRequestUtil;
import oracle.apps.fnd.common.WebAppsContext;
WebAppsContext ctx = WebRequestUtil.validateContext(request, response);
XxLogger.putLog(WebAppsContext ctx, Object o)

STEP 5
===========
For printing stacktrace of exceptions :


In CO
========
XxLogger.printStack(OAPageContext pageContext, Exception e)

In AM,VO,EO
============
XxLogger.printStack(OADBTransaction ot, Exception e)


In JTT/JTF
============
import oracle.apps.fnd.common.WebRequestUtil;
import oracle.apps.fnd.common.WebAppsContext;
WebAppsContext ctx = WebRequestUtil.validateContext(request, response);
XxLogger.printStack(WebAppsContext ctx, Exception e)


We are done the log would now be generated at the position marked in profile and the these messages will automatically converted to SOPs when you run your code in local jdev

Advantages of this logging
=============================
1) You don't need to change your code again and again while working in local or deployed on server.
2) If the development is done in a team, everybody in the team can set the profile at his/her user level so that different log is generated for each user.
3)This code when run in jdeveloper without any change all putLog() and printStack() statements will convert into System.out.println.
4) On server if profile value is set to null , no log is generated, else if some location is set, log is generated there.
5) Same class can be used in all OAF AND JSP components.
6) All methods putLog and printStack are static, so you need not instanciate the class, direct call of method will work.
7) Sometimes while working at offshore, you don't have access to DBA, who can enable log.... :) this is my personal one... u might not face it.

Logic of how code works
=========================
If you have read the code of class , in all the methods code essentially calls printLog method, which has the first line as

Toolkit.getDefaultToolkit().getScreenSize();
This line throws headless exception on server mainly because opmn.xml file configuration by default throws headless exception if any JAVA awt api is called, but this line works fine in jdev, so we utilise this logic to identify whether the code is running on server or jdev. Accordingly it writes the statements in a file, if file is enabled or else calls SOP in jdev.

Monday, April 6, 2009

MOAC(Multi Org Access Control) in OA Framework

Hi All,
After a long time a small and crisp article of how you can set MOAC in your custom OAF code. With release of R12 Oracle EBS has introduced a security feature in apps for multi -org access. Lets have a quick introduction of what is MOAC all abaout :

What is MOAC ?
---------------
The Access Control feature in Release 12 allows the user to enter or query records in one or more operating units without changing application responsibility. It is the system administrator’s discretion to either implement the feature or use the same multiple organizations profile option setting available before Release 12 by using the single operating unit mode (i.e. one operating unit for a responsibility).
In Release 12, the multiple organizations context value is no longer initialized by the FND_GLOBAL.APPS_INITIALIZE routine thereby reducing unnecessary context setting and resource consumption for applications that do not use operating unit context for data security.
To use the single operating unit mode, you must set the value for the "Initialization SQL Statement – Custom profile" to "mo_global.init('S',null);". This initializes the operating unit context based on the "MO: Operating Unit" profile option and the "MO: Security Profile" profile option must not be set.
Fresh install of Release 12 Application is enabled with multiple organizations, however, the system administrator must create operating units to use multi organizations sensitive application products. The user can create new operating units in the Accounting Setup Manager page in addition to HRMS’s Define Organizations page.


MOAC Implementation In Apps
-----------------------------
A new or fresh installation of an Oracle Applications instance does not automatically enable multiple organizations. Typically, the system administrator defines "MO: Operating Unit" profile at Responsibility and/or User level. The "organization_id" of the "MO: Operating Unit" profile option value filters the transactional data. The CLIENT_INFO application context space stores the multiple organizations context value.
Multi-Org views use the following WHERE clause to filter application records:
'org_id = substrb(userenv(''CLIENT_INFO''),1,10)'

MOAC in terms of OAF:
----------------------
Its very natural while developing extension or developing OAF custom pages , you may require quering of views, synonyms which use MOAC via VO.Also, it is possible that you might be calling some standard Oracle PL/SQL APIs which usually need MOAC context to be set.

Every transaction that requires multiple organizations must call the Multiple Organizations initialization in the root Application Module (AM).
Use the following declarative mechanism to initialize the multiple organizations settings for application teams to implement multiple organizations:
1. To enable multiple organizations for the root application module , go to the BC4J Application Module wizard - Properties section and specify the property as MULTIORG_ENABLED and value as either S (single operating unit mode) or M (Multiple operating unit mode).
2. Click Add, then Apply or OK.
On specifying this property, the OA Framework automatically initializes the multiple organizations context at the following appropriate program event points:
1. When reserving or activating the application module.
2. When initializing or validating the Oracle Applications user session.
You initialize the context once for each transaction and session and not instantiate for every page. If your transaction retains the root AM, then the above steps are the easiest to initialize multiple organizations.

If a transaction has multiple pages and the root AM is not retained, then you must call the method OADBTransaction.setMultiOrgAccess to initialize the multiple organizations context to help the user select an operating unit for a transaction.Here is how u can code in AM
OADBTransactionImpl trx = (OADBTransactionImpl)getOADBTransaction(); getOADBTransaction().setMultiOrgAccess(String.valueOf(trx.getOrgId()),String.valueOf(trx.getSecurityProfileId()),trx.getApplicationShortName());



If the operating unit the user selected must appear in the subsequent pages, then pass the curr_org_id to the page and use OADBTransaction.setMultiOrgPolicyContext method to set the operating unit context for the pages that need multiple organizations.
OADBTransactionImpl trx = (OADBTransactionImpl)getOADBTransaction();
getOADBTransaction().setMultiOrgPolicyContext("S",trx.getMultiOrgCurrentOrgId());

Wednesday, January 7, 2009

ADF 10g : How to show faces message both globally and below the UI component.

Hi all,
Welcome again, after a long time I am finally back on blogging.. in the time of economy recession!I think I was not able to update my blog from almost last 7-8 months because of various resons, joining new company, working new technologies of Oracle Fusion and working on multiple projects simultaneously.

In the past 6 months i have worked as an architect on two ADF 10G projects. When I compare ADF with my OA Framework experience, I find ADF to be much more challenging as well as flexible to mold as per the requirement in your project.

From now I would be coming up with small articles on ADF which will be helpful, to develop useful APIs by product architects, so that other developers would be able to use them , without worrying about the actual implementation.

One task in ADF which looks very easy, is showing of different jsf messages.One great feature of ADF is that Faces messages can be shown globally at the top of page, as well as just below the UI ADF bean, which is very illustrative for users.

CASE I:Showing Global Message in an ADF page
-----------------------------------------------
1)af:messages tag is used for showing global messages in an ADF page.This tag is created automatically whenever you drop an input widget from the
Data Control Palette. However, if you need to insert the tag, simply insert the
following code within the afh:body tag:


2. In the Property Inspector set the following attributes:
■ globalOnly: By default ADF Faces displays global messages (i.e., messages
that are not associated with components) followed by individual component
messages. If you wish to display only global messages in the box, set this
attribute to true. Component messages will continue to display with the
associated component.
■ message: The main message text that displays just below the message box
title, above the list of individual messages.
■ text: The text that overrides the default title of the message box.

Code for displaying global Faces message :
//You need to enter error description
String error_decp="";
//You need to enter error detail
String error_detail="";
//Get current instance of faces context
FacesContext fc = FacesContext.getCurrentInstance();
//Creating faces message with description and detail
FacesMessage message = new FacesMessage(error_descp, error_detail);
//setting severity of message,i.e. message type
message.setSeverity(FacesMessage.SEVERITY_ERROR);
//Adding message to faces context.
fc.addMessage(null, message);

CASE II:Showing Faces Message in an ADF UI COMPONENT along with global error message:
-----------------------------------------------------------------------------

a)JSF Validator :
-------------------
This approcah is typically used when you have same kind of validation repeatdly in your code. Lets take a very generic example you need to verify that the entered number should have precision of 2 decimal places, i.e. whatever number user enters should have 2 digits after decimal.You can write a jsf validator for this register in the application and use in any othe pages. If you are new to JSF validator just search google you will find numerous examples of how to write a JSF validator.



b) Directly adding message with UI component based of custom code in backing bean:
--------------------------------------------------------------------------------

i)In complex data UI components like table:
--------------------------------------------
String global_error=""; //Error that need to be shown at top of the page
String component_error="";//Error that need to be shown on the component
String formId="";// Id of Form bean
String TableId="";//Id of table bean
String rowIndex="";//String value of row index
String message="";//message type

FacesContext fc = FacesContext.getCurrentInstance();
FacesMessage message = new FacesMessage(global_error, component_error);
message.setSeverity(FacesMessage.SEVERITY_ERROR);
fc.addMessage(formId+":"+TableId+":"+String.valueOf(rowIndex)+":"+ComponentId, message);


ii)In simple data UI components like input text:
---------------------------------------------
FacesContext fc = FacesContext.getCurrentInstance();
FacesMessage message = new FacesMessage(global_error, component_error);
message.setSeverity(FacesMessage.SEVERITY_ERROR);
fc.addMessage(formId+":"+ComponentId, message);

I hope the above article has provided a brief description about how to show global and UI specific messages , you can use in ADF via JSF APIs.

Wednesday, July 16, 2008

Hide "Privacy Link" and "Copy right information" from dialog page!

Explaination By Kali:

Try the following,
Login with the user who has functional administrator and goto pesonalization tab,
query the document path,
/oracle/apps/fnd/framework/webui/OAFooter
press go, once you get the doc name /oracle/apps/fnd/framework/webui/OAFooter
click on Personalize Page icon,

Clear all other default values and uncheck the site check box,
and select OAFWK_DIALOG_PG in Function.
Then apply,

You will get personalization struction the /oracle/apps/fnd/framework/webui/OAFooter at Function OAFWK_DIALOG_PG level,

Now change the rendered propertly to false for Privacy Link and Copy right.

Then check the dialog page.

Sunday, July 6, 2008

Creation Of the Anonymous page Introduction( By Kalimuthu Vellaichamy,Senior Consultant,Oracle )

1.1 Purpose
This document explains the OAFramework (ver 5.7 H for Apps 11.5.9 and 5.10 for Apps 11.5.10) Anonymous User page (like registration page) development and deployment in an instance and pack for the other instances.
This document assumes that the reader has a basic knowledge of OA Frmework page creation and deployment.

1.2 Background
This document should be used for creating Guest User pages and all type of registration pages. When this document fails to cover a topic, recommendations from OA Framework Development Team should be followed. If you have a Guest user page to display that does not require a user to log in.

1.3 Related Documents
1. OA Framework Developers’ Guide
2 Creation Of the Anonymous page

2.1 New page with anonymous user setup.

To create a page with anonymous setup we should have a standard OAFramework page with all the components required for the page.
We have to create the function for this page.
Let us consider a Registration page NewEmpRegistrationPG.xml and the registered function for this page is NEW_EMP_REGN.
We have to change the following properties for the MainRN for the page.
Rendered: ${oa.FunctionSecurity. NEW_EMP_REGN}
Security Mode: selfSecured



Use the following command to upload the page to the instance,
java oracle.jrad.tools.xml.importer.XMLImporter -username -password -dbconnection "(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=)(PORT=))(CONNECT_DATA=(SID=)))" -rootdir ./ -rootPackage

Example.
java oracle.jrad.tools.xml.importer.XMLImporter NewEmpRegistrationPG.xml -username apps -password apps -dbconnection "(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=I3SN021E.idc.oracle.com)(PORT=1610))(CONNECT_DATA=(SID=scmtrng)))" -rootdir ./ -rootPackage /xxt/oracle/apps/pon/registration/webui

2.2 Create a function for the new page
Use functional administrator (Self Service) or using system administrator (Forms) responsibility and create a function for the uploaded page.






After the function creation we have to add this function to a menu and the menu has to be granted to GUEST user.

2.3 Add the function to a new menu
Use fuctional administrator responsibility to create a new Menu. Add the created function with this new menu.





Now we are ready with the menu that is having a function, which points to a page which we want to access without the user log in.
If you want to give access to more than one page you can add, as many functions to the menu, like below.




2.4 Create Grant for the created menu.
To create Grant for the menu we have created now, use Security Tab in the functional administrator responsibility. Follow the below mentioned steps.




Step I: Log on to Application with Functional Administrator Responsibility and click on functional administrator responsibility. Click on “Create Grant” button (To create a Global Grant)




Step II: Enter the Grant Name and select Grantee Type as “All Users” and click “Next”



Step III: Enter the User Menu Name of the newly created Menu and click “Next”


Step IV : Click “Finish” button


Step V: Again click on “Create Grant” (To create Guest Grant)



Step VI : Enter the Grant Name and select Grantee Type as “Specific User”. The page refreshes to display a new field called “Grantee” (If the page fails to refresh click “Next” button to go to the next screen and click “Back” button on the next screen to come back to this screen)
Enter “GUEST” in the “Grantee” field and click “Next”



Step VII: Enter the User Menu Name of the newly created Menu and click “Next”




Step VIII : Click “Finish” button



Step IX: Grant creations successfully completed.

3 Download and Upload the Grant
Following command used to download the created Grant.
FNDLOAD apps/apps 0 Y DOWNLOAD $FND_TOP/patch/115/import/afsload.lct XXTGUESTGRT_US.ldt GRANT GNT_MENU_NAME= NEW_EMP_REGN_MENU
To upload this grant into a new instance upload the page and the menu as usual and upload the Grant for the menu using the following command.
Following command used to upload the downloaded Grant.
FNDLOAD apps/apps 0 Y UPLOAD $FND_TOP/patch/115/import/afsload.lct XXTGUESTGRT_US.ldt
No we can access the newly created page without login into the applications using the following URL.
http://: /OA_HTML/OA.jsp?OAFunc=NEW_EMP_REGN

Tuesday, July 1, 2008

Disable Browser Back Button in OAF

Hi all,
These days I am so muh busy with SOA, ADF and Bpel projects that I do not get time to write articles. But recently helped a friend in old team for fixing browser back button in one of his OAF transaction pages which was creating error in his page.

Basically a small trick used in various J2EE projects in javascript helps to sort of nullify the browser back button in oaf page. This is what you need to do,
Put following code in process request of OAF page :
OABodyBean bodyBean = (OABodyBean) OAPageContext.getRootWebBean();
String javaS = “javascript:window.history.forward(1);”;
bodyBean.setOnLoad(javaS);


Actually window.history.forward(1) would push the current page ahead in the "visited pages history". A negative number like -1 would restore the previous visited page from browser's cache. Zero is relative to the current (displayed) page. Positive numbers would navigate forward.
If the page number (positive) does not exist in history, your browser will create an entry "copying" the current page to it and setting it as the current entry, so that the previous and actual are the same.

Using window.history.forward(1) does not disable "Back button". The button will work BUT as this script runs on page loading, it will send you "ahead" the history, which stored URL (or page) is the same. So it works like a "Refresh" button, without actually refreshing content from server, but just restoring from cache.
Hope this helps all.