How-to - Java Concurrent Programs

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.

Hope its useful ... I have a copy of the javadoc posted here.

Comments:

Hi Sunil

I guess that if you get the fnd classes from java_top onto your machine and then point jdev to it as a library. I have not tried it yet but you should then be able to run the conc program from your desktop.

Tim 

Posted by Tim Dexter on May 02, 2007 at 06:55 AM MDT #

Tim, Is there a way to test a program from within JDeveloper on a PC instead of on the server? Also, thanks for including Template.java in the article. I could not find it under $FND_TOP on my installation. The closest was the complied Template.class under $OA_JAVA. Sunil

Posted by Sunil Desai on May 02, 2007 at 09:30 AM MDT #

HI ALL, Can any one help me out bellow query: I have a java concurrent program will 15 parameters,out of 15 five parameters contains values rest of them are null.how can i pass parameters through OS and if parameter contains varchar2 value. What is the process of running the java concurrent program. i had using the program like this' java -Ddbcfile=$FND_SECURE/SALES.dbc -Drequest.outfile=./outfile -Drequest.userid=1318 -Drequest.respappid=200 -Drequest.respid=50554 oracle.apps.fnd.cp.request.Run oracle.apps.xdo.oa.cp.JCP4XDODataEngine "TOKEN1=Vision Operations:TOKEN2=Liabilities Payables, Vision Services (USA):TOKEN3=Payables:TOKEN4=01-JAN-1999:TOKEN5=3G Communications, Inc.:TOKEN6=No:TOKEN7=No:TOKEN8=Year to Date" is this correct or need i to change above one? If ran this this will create request in fnd_concurrent_requests of only for rerunning the concurrent program. If i get the information i am very lucky. Thanks in advance Nav

Posted by NAV on September 15, 2008 at 09:21 PM MDT #

Hi All: where can download all necessary libs to compile an class to use in concurrent program if I don´t have installed Oracle? Thanks in advance

Posted by rubens on April 23, 2009 at 01:38 AM MDT #

I was curious if there's a way to invoke a web service using Java Concurrent Program? Could anyone please point me to an example? I could not find it... Thanks, Hyon

Posted by Hyon Lee on June 22, 2009 at 10:25 AM MDT #

Hi Tim, I am trying to add a new font to the PO Output for Communication report in Oracle, but so far have been unsuccessful. Since the report uses an XSL-FO template, I assumed simply adding the font using XML Publisher Administrator would do the trick, but it didn't. After I added the font using XML Publisher Admin, I can use the font in test RTF and XSL-FO templates in test reports but it does not work in the PO Output for Communication report. I even substituted the working XSL-FO template in the PO Output for Communication report, and then the font is no longer applied (even though it worked in a different report). The only difference I can see is that my test reports were based on Oracle Reports, while the PO Output for Communication report is a Java Concurrent Program. It seems to me that I need to set the font up differently for it to work with a Java Concurrent Program, but I don’t know how. Any help you can provide is greatly appreciated. Thanks, Suzanne

Posted by Suzanne on July 08, 2009 at 01:57 AM MDT #

Hi, I am writing a Java concurrent program and my java class calls another class and i want to write to logfile from the inner class. can you please help me how to do that... Thanks,

Posted by Kalyan on September 23, 2009 at 07:07 PM MDT #

I am coming into the Java Concurrent Program from an EBS background. I have a registered Java Concurrent Program that got created with a patch. I am trying to locate the java, associated with the registered executable, on the file system. Since it is registered as an Inventory program, then where can I find the java file?

Posted by Cynthia Stein on May 18, 2011 at 05:33 AM MDT #

Thanks, It was very helpful

Posted by Neil Ghosh on July 26, 2011 at 06:43 PM MDT #

I have a requirement of a Java concurrent program which will invoke my XML Publisher Data Definition and Template Definition and create the PDF file output. However this process should not submit a concurrent request.

Any Clues

Posted by Niladri on August 04, 2011 at 01:58 AM MDT #

Cynthia, Did you get any reply to your query or you figure out yourself? I am in the same situation. Pls any body could help us to locate the java, associated with the registered executable, on the file system? Where can one find the java file?

Thanks in advance.

Raj

Posted by raj on November 30, 2011 at 06:25 AM MST #

Hey Raj and Cynthia did any one of you both got answer for your query. If yes please share with me. I AM IN A URGENT NEED FOR THE SAME.

Thanks,
Riya

Posted by guest on January 18, 2012 at 10:06 PM MST #

Hi Raj and to Riya, I did find a .class file associated with my concurrent program. It is binary object code however. Here is how to find it. This one was created with an Agile PLM patch, for EBS, so you may or may not have it.
Your Concurrent Program name, for instance "Publish Engineering Change Order Updates" queried up in the Concurrent/Program/Define screen from System Administator, yields a Short Name of INV_EBI_PUBLISH_ECO. Then querying that up in the Concurrent/Program/Executable form as the Short Name field, yeilds the "Execution File Name" and the "Execution File Path", in this case "PublishService" and "oracle.apps.inv.ebi.cp" respectively. From there you go to the OS for the application tier of EBS, to $JAVA_TOP logical drive, which may be something like /localapps/prodcomn/java/, and from there cd to the directory above, substituting the . with / , so "cd oracle/apps/inv/ebi/cp" and you should have a .classfile there that matched the "Execution File Name", so in this case "PublishService.class" Again it is a binary file for me, but that is it's location...
Maybe helpful...
Cheers,
Cindi

Posted by guest on January 19, 2012 at 03:12 AM MST #

Hello Everybody,

I have implemented one Oracle Java Concurrent program but it depends on 6 custom libraries.. I tried putting dependency using concurrent program options but length is very less and its not accepting 6 jars. Could you please let me know how to add the dependency jars to run.

Posted by Ramadevi on February 14, 2012 at 11:48 PM MST #

I have implemented one oracle java concurrent program in Jdeveloper and compiled by adding custom jars and moved to DB m/c. This program needs 6 custom library jars to run.. I moved my class file, dependent jars to Java_top directories. I created a concurrent program to run this Class file. I tried adding 6 jar paths to concurrent program Options but length is very less and couldn't able to add 6 jar files. Could you please some one help me how to add dependent jars in class path to RUN without issues.

Posted by guest on February 14, 2012 at 11:52 PM MST #

How to compile the program on unix apps server?
Please speicify the command

Posted by guest on January 23, 2013 at 09:23 AM MST #

Since the options field on the Define program is too small to take a full custom classpath, how do you put a JCP in a custom classpath?
Where do you add this classpath?

or

In the third para of the article, it is menationed
"if wip product creates a class in $WIP_TOP/java/shopfloor/server/BackgroundProgram.class, this is then registered with the package location"
who resiters this and how?

Posted by guest on October 18, 2013 at 05:13 PM MDT #

Since the options field on the Define program is too small to take a full custom classpath, how do you put a JCP in a custom classpath?

Where do you add this classpath?

In the third para of the article, it is mentioned
"if wip product creates a class in $WIP_TOP..., this is then registered with the package location"
who registers this and how?

Posted by guest on October 18, 2013 at 05:16 PM MDT #

Post a Comment:
  • HTML Syntax: NOT allowed
About

Follow bipublisher on Twitter Find Us on Facebook BI Publisher Youtube ChannelDiscussion Forum

Join our BI Publisher community to get the most and keep updated with the latest news, How-to, Solutions! Share your feedback and let us hear your voice @bipublisher on Twitter, on our official Facebook page, and Youtube!

Search

Archives
« April 2014
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today