Site navigation (main menu).

Blog

Java Concurrent Programs made easy

It is a little known fact that Concurrent Manager Executables can be written in Java, as well as all the traditional languages such as PL/SQL. I believe that this functionality was introduced in 11.5.9, but very little fuss has been made of it. I first came across it while reading Tim Dexter’s excellent BI Publisher Blog in his article How To – Java Concurrent Programs.

Tim’s article is very good and I don’t intend to just repeat everything that he has written. However, I will cover the basics. Oracle have provided the Java Interface oracle.apps.fnd.cp.request.JavaConcurrentProgram; to create your Java Concurrent Program you will need to create a class that implements this interface, ensuring that the abstract method runProgram() is implemented. For example:

package abc.apps.oracle.xyz;

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

public class CpTest implements JavaConcurrentProgram
{
  public void runProgram(CpContext cpContext)
  {
    // your code here
  }
}

The CpContext object gives you access a whole variety of useful things, including the database connection, the Log and Output files and all the parameter values from the Submit Request screen. However, the some of the information about the Concurrent Program can be a little awkward to access.

To make life easier, I have created an abstract class containing a whole set of useful utility functions, designed to make writing a Java Concurrent Program a lot easier. The only thing you have to do is implement the abstract method main() and ConcProgram will do the rest. For example:

package abc.apps.oracle.xyz;

import com.oaframework.toolkit.util.ConcProgram;
import com.oaframework.toolkit.util.ConcProgramException;

public class CpTest2 extends ConcProgram
{
  public void main() throws ConcProgramException
  {
    try
    {
      // your code here
      setNormalCompletion("OK");
    }
    catch (Exception ex)
    {
      writeLog"Exception " + ex.getClass().getName() + " caught in " + this.getClass().getName());
      throw new ConcProgramException(getContext(), ex);
    }
  }
}

ConcProgram provides all the methods that you need to manage your Java Concurrent Program. The full list of methods is below:

public String getParameter(String paramName)
public String getParameter(String paramName, String defaultValue)
public Number getNumberParameter(String paramName)

public CpContext getContext()

public int getRequestId()
public String getUserName()
public int getUserId()
public String getRespName()
public int getRespId()

public void writeOut(String message)
public void writeLog(String message)

public void setNormalCompletion(String message)
public void setWarningCompletion(String message)
public void setErrorCompletion(String message)

The getParameter() and getNumberParameter() methods hide the complexity of the standard mechanism which the Oracle supplied class uses to pass the Concurrent Request parameters. The writeOut() and writeLog() methods write a message to the Concurrent Manager Output and Log files respectively. The various set…Completion() methods are used to indicate the status of the job and to pass a message back Concurrent Manager.

If you want to access the database from within your Java Concurrent Program, you have two options. One way is to obtain the JDBC Connection from the CpContext object, using the getJDBCConnection() method. However, within E-Business Suite the preference is to use BC4J. You can create your BC4J objects in JDeveloper in the same way that you would for an OA Framework application. The following piece of code shows how a BC4J View object can be used in your Java Concurrent Program:

package abc.apps.oracle.xyz;

import abc.apps.oracle.xyz.server.PurchasingAMImpl;
import abc.apps.oracle.xyz.server.PurchaseOrderVOImpl;
import abc.apps.oracle.xyz.server.PurchaseOrderVORowImpl;
import com.oaframework.toolkit.util.ConcProgram;
import com.oaframework.toolkit.util.ConcProgramException;
import oracle.apps.fnd.framework.OAApplicationModuleFactory;

public class CpTest3 extends ConcProgram
{
  private static String amDefName = "abc.apps.oracle.xyz.server.PurchasingAM";

  public void main() throws ConcProgramException
  {
    try
    {
      PurchasingAMImpl am = (PurchasingAMImpl)OAApplicationModuleFactory.createRootOAApplicationModule(getContext(), amDefName);
      am.initPurchaseOrderVO(getParameter("p_vendor_id"));

      PurchaseOrderVOImpl vo = am.getPurchaseOrderVO();
      int rowCount = vo.getRowCount();

      if (rowCount > 0)
      {
        RowSetIterator rsi = vo.createRowSetIterator("po");
        rsi.setRangeStart(0);
        rsi.setRangeSize(rowCount);

        for (i=0; i<rowCount; i++)
        {
          PurchaseOrderVORowImpl vor = (PurchaseOrderVORowImpl)rsi.getRowAtRangeIndex(i);
          sendEmail(vor);
        }
      }

      setNormalCompletion("OK");
    }
    catch (Exception ex)
    {
      writeLog"Exception " + ex.getClass().getName() + " caught in " + this.getClass().getName());
      throw new ConcProgramException(getContext(), ex);
    }
  }
}

If you want to use the ConcProgram class yourself, you can download it as part of the OA Framework Toolkit, from http://sourceforge.net/projects/oaftoolkit. However, if you don’t want the whole Toolkit, a ZIP file containing ConcProgram and ConcProgramException can be downloaded from our Downloads section.

27 Aug, 2009 by

E-Business Suite

Comments are now closed... Please contact us if you have any queries.