Sei sulla pagina 1di 6

How-to - Java Concurrent Programs

By Tim Dexter-Oracle on May 01, 2007


I talk about java concurrent programs quite a lot on this blog, if you want have publisher interact with the
EBS concurrent manager you typically need to write a java concurrent program (JCP) ... I have been
scouring the user docs for EBS and can not find a reference to them ... that leaves you folks stuck. Rather
sneakily and maybe lazily I have lifted the 'How-to' doc from the ATG pages ... thanks to Venkat from the
Concurrent Processing team. Without further ado ...
Overview
Concurrent Processing provides an interface avaConcurrentProgram? with abstract method
runProgram() which passes the concurrent processing context pContext?. The concurrent program
developer will implement all of their business logic for a concurrent program in runProgram(). The main()
method, implemented by AOL, will call runProgram() after performing all of the required initialization for
the concurrent program, including establishing a database connection, initializing the required contexts,
and setting up the log and output files. CpContext will have the request specific log and output file input
methods. The class name with the main method will be registered as the java executable file name in the
register executable form or by using pl/sql API.
Developer has to register the full package path for the class in register executable form. For example, if
wip product creates a class in $WIP_TOP/java/shopfloor/server/BackgroundProgram.class, this is then
registered with the package location racle/apps/wip/shopfloor/server/BackgroundProgram.class?.
Developer will register ackgroundProgram? as the executable file name and
racle.apps.wip.shopfloor.server? as the package path in the register executable form. Developer has to
follow the java notation to register the package path location, ?.? to denote the directory instead of ?/? in
UNIX.
Java Concurrent Program parameters must register with token names in the parameter screen of the
register concurrent programs form. Developer can get the value of the parameter for a given token name
in the java concurrent program. These token names will be used in passing the parameter values as
parameter string to the concurrent program from the command line for testing the java concurrent
program.
Developer should set the status and completion text for the java program by using the setCompletion()
method provided by AOL. The runProgram() method should call setCompletion() method to report the
program completion status to the Concurrent Manager. The program may set its completion status to
Normal, Warning or Error. Completion text is optional.

Steps in writing Java Concurrent Program

Template Program:

Copy the template Java Concurrent Program from $FND_TOP/java/cp/request/Template.java to your


directory and start coding according to your requirement. Change file name and class name to your
required name as Java Concurrent Program name.
================= Template.java===========================
package oracle.apps.fnd.cp.request;

// Change the package name to the required one.


// import all the other required classes/packages.
import oracle.apps.fnd.util.*;
import oracle.apps.fnd.cp.request.*;
// Change the name of the class from Template to your
// concurrent program class name
public class Template implements JavaConcurrentProgram
{
/** Optionally provide class constructor without any arguments.
* If you provide any arguments to the class constructor then while
* running the program will fail.
*/
public void runProgram(CpContext pCpContext)
{
ReqCompletion lRC = pCpContext.getReqCompletion();
String CompletionText = "";
/* Code your program logic here.
* Use getJDBCConnection method to get the connection
* object for any JDBC operations.
* Use CpContext provided commit,rollback methods to
* commit/rollback data base transactions.
* Don't forget to release the connection before returning
* from this method.
*/

/* Call setCompletion method to set the request completion


* status and completion text.
* Status values are ReqCompletion.NORMAL,ReqCompletion.WARNING,
* ReqCompletion.ERROR.
* Use Completion text message of length 240 characters.
* If it is more than 240 then full string will appear in
* log file and truncated 240 characters will be used as
* request completion text.
*/
lRC.setCompletion(ReqCompletion.NORMAL, CompletionText);

}
}
==================End of Template.java===========================

program Logic

Implement the runProgram with your Java Concurrent Program business logic. runProgram() gets the
CpContext . CpContext is a subclass of AOL/J AppsContext which provides the request specific member
classes LogFile to write to request log file, OutFile to write to request output file and ReqCompletion to set
the completion status of the request.
Program Parameters
CpContext uses the AOL/J utility Parameter List to pass the parameters to the Java Concurrent Program.
Please refer AOL/J Parameter list to get the Parameter List name, value pairs. You will be referring

parameter list name as the parameter name and corresponding value as the parameter value in the Java
Concurrent Program. You have to register the parameter names as token name in the register concurrent
program form Parameter screen.
Database Operations
Use getJDBCConnection method to get the connection object for any JDBC operations within program and
release the connection to the AppsContext connection pool. Use CpContext's commit(), rollback() methods
to commit or rollback the transactions in the database. These methods will set the program proffered
rollback segments after commit or rollback segments for the rest of the database transaction in the Java
Concurrent Program.
Setting request Completion Status
Call setCompletion() method of the ReqCompletion object which is a member of CpContext before
returning from your Java Concurrent Program to set the completion status for the program and optional
completion text.

Register executable

Register your Java Concurrent Program class name as execution_file_name and package name in
execution_file_path in register concurrent executables form.

Register Concurrent Program

Register you Java Concurrent Program as concurrent program in the register concurrent program form.
Register all the parameters that you want to pass to the program in the parameter screen of this form.
Register the Parameter List names referred in the program as the token names in the parameter screen.

Test Program from OS Prompt

You can test your Java Concurrent Program from OS prompt by using the following syntax:
jre -Ddbcfile=<dbc filename with full path>
[ -Drequest.logfile=<logfile name> ]
[ -Drequest.requestid=<request id> ]
[ -Drequest.outfile=<output file name> ]
[ -Drequest.userid=<user id> ]
[ -Drequest.respapplid=<resp appl id> ]
[ -Drequest.respid=<resp id> ]
[ -Drequest.secgrpid=<sec grp id> ]
[ -Drequest.enabletrace=<Y/N> ]
oracle.apps.fnd.cp.request.Run <program/class name>
[<parameters>]
Example:
jre -Ddbcfile=/d2/fnd/secure/appsnode_appdb.dbc
-Dreqeust.requestid=23453 -Drequest.logfile=./myreq.log
oracle.apps.fnd.cp.request.Run oracle.apps.wip.program.MyProg
"TOKEN1=value1:TOKEN2=value2"

If you don't specify the 'request.logfile' with -D option then the all the log file information will be printed to
the standard output. Specify the 'request.requestid' to rerun already completed request. You can specify
the all the application user specific context values with -D to get the specific user context to the program
when run from the OS prompt. Pass all the parameters if any by using the AOL/J Parameter list syntax.

Sample Program

package oracle.apps.fnd.cp.request;
import java.io.*;
import java.sql.*;
import oracle.apps.fnd.util.*;
public class AvailableProg implements JavaConcurrentProgram
{
String applName;
public AvailableProg()
{
// if no parameter value is specified for
// APPLNAME then use FND as default value
applName = "FND";
}
public void runProgram(CpContext pCpContext)
{
// get the JDBC connection object
Connection mJConn = pCpContext.getJDBCConnection();
// get parameter list object from CpContext
ParameterList lPara = pCpContext.getParameterList();
// get ReqCompletion object from CpContext
ReqCompletion lRC = pCpContext.getReqCompletion();
String lQuery =
" select substr(user_concurrent_program_name,1,70) , " +
" decode(enabled_flag,'Y','Enabled','N','Disabled') " +
" from fnd_concurrent_programs_vl cp, fnd_application_vl a " +
" where cp.application_id
= a.application_id " +
" and a.application_short_name = ? " +
" order by 1 " ;
// check for the APPLNAME parameter token name and if it there get
// value and use it as the application short name in the query
while (lPara.hasMoreElements())
{
NameValueType aNVT = lPara.nextParameter();
if ( aNVT.getName().equals("APPLNAME") )
applName = aNVT.getValue();
}
try
{

PreparedStatement lStmt = mJConn.prepareStatement(lQuery);


lStmt.setString(1, applName );
ResultSet lRs = lStmt.executeQuery();
// get OutFile object from CpContext
OutFile lOF = pCpContext.getOutFile();
// get LogFile object from CpContext
LogFile lLF = pCpContext.getLogFile();

lLF.writeln("Generating Programs for Application : " + applName,


LogFile.STATEMENT);
lOF.writeln(
"
Available Concurrent Programs for Application " +
applName );
lOF.writeln(
"Concurrent Program Name
Enabled");
lOF.writeln(
"----------------------------------------------" );
while( lRs.next() )
{
lOF.writeln(lRs.getString(1) + "

" + lRs.getString(2) );

}
lLF.writeln("Generated Programs for Application : " + applName,
LogFile.STATEMENT);
lStmt.close();
lRC.setCompletion(ReqCompletion.NORMAL, "Request Completed Normal");

}
catch (SQLException e)
{
lRC.setCompletion(ReqCompletion.ERROR, e.toString());
}
finally
{
pCpContext.releaseJDBCConnection();
}
}

NOTE: If you're creating a BC4J Application Module in a concurrent program and are passing CpContext
object to it, you should NOT call releaseJDBCConnection() on CpContext while it is still in use by the BC4J
AM. You should clean up after the AM properly by calling am.remove().

Some Q & A

Q. How can I run my Java Concurrent Program from OS prompt?


A. To run a Java Concurrent Program from the OS prompt the syntax is as follows:
Please note that there is no newline between different -D options and arguments to jre.
jre -Ddbcfile=<dbc filename with full path>
[ -Drequest.logfile=<logfile name> ]
[ -Drequest.requestid=<request id> ]
[ -Drequest.outfile=<output file name> ]
[ -Drequest.userid=<user id> ]
[ -Drequest.respappid=<resp appl id> ]
[ -Drequest.respid=<resp id> ]
[ -Drequest.secgrpid=<sec grp id> ]
[ -Drequest.enabletrace=<Y/N> ]
oracle.apps.fnd.cp.request.Run <program/class name>
[<parameters>]
Example:
jre -Ddbcfile=/d2/fnd/secure/appsnode_appdb.dbc
-Dreqeust.requestid=23453 -Drequest.logfile=./myreq.log
oracle.apps.fnd.cp.request.Run oracle.apps.wip.program.MyProg
"TOKEN1=value1:TOKEN2=value2"
Q. Can I use Constructor for my Java Concurrent Program class?
A. You can use the constructor without any arguments to it.
Example:
class MyProg implements JavaConcurrentProgram
{
// DO NOT USE MyProg(String arg1, int arg2...)
public void MyProg()
{
...
}
public void runProgram(CpContext pCpContext)
{
....
}
}
Q. Can my JCP class Constructor accept arguments?
A. NO, do not use any class constructor with arguments. Refer above Example.
Q. How to pass parameters to my Java Concurrent Program?
A. Java Concurrent Program uses AOL/J Parameter List utility APIs for parameter management. To pass
parameters to Java Concurrent Program you have to register those parameters with token name by using
the "Register Concurrent Program". In the JCP you can access the registered token name in the AOL/J
ParameterList API and get corresponding value to get the value of the parameter. Refer AOL/J
ParameterList API for more information.
Q. Can I use different output file name than the standard name?
A. Yes, you can use different output file name by calling the setOutFile method of OutFile class.
Q. What will happen if I don't call setCompletion method of ReqCompletion?
A. Your request run by using this program will complete with error.