4 Steps to Writing Your First Java Concurrent Program

July 29, 2013
Michael S.

1st_Screen_Shot_-_Java_Concurrent

Writing your first Java Concurrent Program can be intimidating.  You could probably accomplish the same result using a combination of UNIX shell scripting, SQL and PL/SQL, right?  But when an opportunity arose recently for me to embed REST API calls that returned JSON objects, the answer was to do this within a Java environment.

I have, at times, been fatigued by the complexity of the Oracle code.  In fairness, metalink note [ID 827563.1] – yes, I said metalink – does provide a good explanation of the structure and requirements, but I will boil those down even further here.

First, a little background.  Oracle provides an interface with a method called runProgram(CpContext), which is where you need to embed your code.  This method is called from a main thread after program start and initialization.  The CpContext passed as a parameter to this method – and hence to your code – provides access to many of the variables needed to complete your solution, like .log and .out files and a JDBC connection to the database where this program will be run.

To be able to run your program, you need to define a Concurrent Executable and Concurrent Program and provide some indication of where your code resides.  Assuming you already know how to define a Program and Executable, I will cover the registration process for the path to your program.

So, here it is – my 4-step outline of how to approach writing a Java Concurrent Program:

1. Introduce some simple changes to the template provided below
2. Compile and deploy your code to the server where your EBS resides
3. Define the Executable and Program
4. Start having fun!

Template Program

The metalink note adds several comments that clutter the high-level view.  Below is my representation of the program, but note that my package statement is only significant from the perspective that the package and class name will be required during the Executable and Program definition.  Here is the code:

package dak.jcp.test;

import oracle.apps.fnd.common.Context;

import oracle.apps.fnd.common.VersionInfo;

import oracle.apps.fnd.cp.request.CpContext;

import oracle.apps.fnd.cp.request.*;

import oracle.apps.fnd.util.*;

import java.sql.*;

   public class TestJCP implements JavaConcurrentProgram {

      OutFile out;

      LogFile log;

      public void runProgram(CpContext ctx) {

         Connection conn = null;

         try {

            out = ctx.getOutFile();

            log = ctx.getLogFile();

            ParameterList parms = ctx.getParameterList();

            conn = ctx.getJDBCConnection();

            int userId = ctx.getReqDetails().getUserInfo().getUserId();

         // insert your code here

            log.write("Hello World", 0);

            out.write("Hello World");

            ctx.getReqCompletion().setCompletion(ReqCompletion.NORMAL, "Completed.");

         } catch (Exception e) {

            out.writeln("Exception during PPS Reconciliation...n" + e.getMessage());

            ctx.getReqCompletion().setCompletion(ReqCompletion.ERROR, "Completed.");

         } finally {

            try { conn.rollback(); } catch (SQLException e) {}

         }

      }

   }

Compile your program with the following command:

javac –d $JAVA_TOP TestJCP.java

This will effectively put your compiled program in the CLASSPATH for the EBS middle-tier Java Runtime.

If, however, you are inclined to locate your code in a custom location – perhaps within a .jar file or in a directory structure outside the Oracle application tier (a practice I fully endorse!) – then perform the steps that I will cover in a second blog post.  For now, let’s just keep it simple.

Debug your program as needed. To run your program, you have two options:

1) Use the following syntax to run your code directly from UNIX:

java -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>]

2) Define the Executable and Program, point it to your new code and try running via Standard Request Submission form.  Oddly, I find this second option easier.

Defining Your Executable and Program

Now, login to EBS as developer or System Administrator and define an Executable similar to the following:

1st_Screen_Shot_-_Java_Concurrent

The Execution File Name is the name of your class, and the Execution File Path is the package reference from your program.

Next, define a Concurrent Program like this:

2nd_Screen_Shot_-_Java_Concurrent

Lastly, be sure to add the Concurrent Program to the appropriate Request Group so you can run it.

Now, run it!

The Execution

Although not terribly exciting, your output should take the following form:

Output File:

3rd_Screen_Shot_-_Java_Concurrent

Log File:

4th_Screen_Shot_-_Java_Concurrent

If you have any questions, post them in the comments below.  I’d love to hear your experiences with Java Concurrent Program.