Custom XPATH Function in BPEL

Oracle BPEL has a very robust XPATH and XQuery implementation with very rich list of predefined XPATH functions that can be used to build complex transformations and expressions within the BPEL flow. But some times these predefined functions may not be enough to implement complex requirements that may need some complex programming.
Developer can define XPATH custom functions as extensions to predefined list of XPATH functions that can cater for a complex programming requirement, this custom function can be reused across BPEL processes deployed in the BPEL domain.
Implementation Custom XPATH Function
The implementation of the custom function is defined by 3 main steps

  • Custom Function Development
  • BPEL Service Configuration
  • JDeveloper Configuration
These steps are discussed in details with an example in following sections. The Development steps involved implementation of predefined java interface . Once build you can register this function implementation with the BPEL server for it to be used in the processes. It is important to note that in a clustered architecture, custom function is required to be registered to every BPEL domain. Lastly to allow JDeveloper offer this function as part of expression builders and transformation, it needs to be registered to JDeveloper as well.

Sample UseCase
The Custom Function development is discussed based on an example use case. You are writing a billing system that get the order details as input are creates a bill. This involved calculating VAT as part of the BPEL process. The Process Developer initially thought of using embedding JAVA in the process, But the Process Architect has advised that they create an XPATH extension function as similar feature is required across other processes.
Process Architect has defined following requirement for the developer.
'Define an XPATH function that can take an input string, element or node and calculate VAT value at 15%. The function should then return VAT value as float.'

XPATH Function Development
The development of custom function requires creation of java application project in JDeveloper, which will result in jar deployment of the function.

  1. Start JDeveloper & create an Application called CustomXPathFunctions based JAVA Application template.
  2. sc1.png
  3. Assign application package prefix ''
  4. Use the Project properties to set the build path libraries for the project to all the jar files located at %ORACLE_AS%\bpel\lib
  5. sc5.png
  6. Create Java class CalculateVAT in package
  7. sc2.png
    (See Appendix A for the sample code)
  8. Implement interface,xml.xpath.IXPathFunction
  9. Implement your business logic in the method call(IXPathContext context, List list)
  10. (Note: make sure to compile this class using jdk 1.5)
  11. Create a new jar deployment profile called "CustomXPathFunctions.deploy" for the project to create a jar file
  12. sc8.png
  13. Note that you will have a project structure as show in next diagram
  14. sc3.png
  15. Configure the jar deployment profile to create the jar file is required location
  16. sc4.png
  17. Right click on CustomXPathFunctions.deploy and select Deploy to jar to get java class exported as a CustomXPathFunctions.jar file

The jar file produces from the above steps can be used to deploy on BPEL domains so the custom functions can be used in BPEL processes. To enable JDeveloper to use the Custom function during process development follow the next section.

JDeveloper Configuration for custom function
JDeveloper can be configured to use the custom function in Expression builder.
Pre-requisite: Custom class jar file, you can use CustomXPathFunctions.jar file you created out of step

  1. Copy the exported CustomXPathFunctions.jar file to %JDEV_HOME%\jdev\lib\patches
  2. backup the file %JDEV_HOME%/integration/lib/bpm-ide-common.jar and then copy to a temp directory.
  3. Unjar the file %tempDir%/bpm-ide-common.jar with the following command

  4. jar -xvf bpm-ide-common.jar oracle/tip/tools/ide/common/resource/PreBuiltExtensionFunctions.xml

  5. Now edit the inflated PreBuiltExtensionFunctions.xml file and add the entry as the last element just before &grt;/extension-functions&lst;:(Note: This new function will appear in "Advance Functions" category in the "Expression Builder". It should also be noted that a logical namespace must be defined for the function)

  6.   <functions xmlns:xpfunc='' >
        <function name='xpfunc:calculateVAT' as='double'>
          <param name='sum' as='double' required='yes'/>
            <pcui:mapper palettePage='Advanced Functions'/>

  7. Now update the jar file with the command:

  8. jar -uf bpm-ide-common.jar oracle/tip/tools/ide/common/resource/PreBuiltExtensionFunctions.xml

  9. Finally put the jar file back into %JDEV_HOME%/integration/lib/ directory.
  10. Restart JDeveloper
  11. Check if the function appears in Expression Builder
  12. sc7.png

Register Custom Function with BPEL Engine
The Custom Function needs to be registered with the BPEL Server before it can be used in the BPEL processes.
Pre-requisite: you can use "com" folder found in your %project_home%/classes based on step 1.
  1. Edit the file %SOA_HOME%\bpel\system\config\xpath-functions.xml and add the text as last element just before ""

  2.   <function id="calculateVAT" arity="1">
          <property id="namespace-uri">
          <property id="namespace-prefix">

    (Note in the above example arity is set to 1 as the number of mandatory input parameter is 1. But if you needed two mandatory parameters then set arity="2")
  3. Copy com folder from %project_home%/classes containing your function class in the location %SOA_HOME%\bpel\system\classes with its packa structure intact. You should get following structure
  4. sc6.png
  5. Restart the Oracle AS
  6. Test the function implementation in BPEL process



      import java.util.List;
      import org.w3c.dom.Element;
      import org.w3c.dom.Node;
      import org.w3c.dom.Text;
      import java.util.ArrayList;

      * @author
      * @since 30-jun-2009

      public class CalculateVAT {

        public Object call(IXPathContext arg0, List list)
            throws XPathFunctionException {
          if (list.size() != 1)
            throw new XPathFunctionException("calculateVAT(userName) needs 1 arguments");
          // Get value of input parameters
          Object p1 = list.get(0);
          String sp1 = getParamValue(p1);
          // Convert to Date objects and pass in to function
          double sum = Double.parseFloat(sp1);
          double vat = sum * 0.15;
          return Double.valueOf(vat);


        private String getParamValue(Object param) {
          String value;
          if (param instanceof Element) {
            Node n = (Node)param;
            value = n.getFirstChild().getNodeValue();
          } else if (param instanceof Text) {
            Node n = (Node)param;
            value = n.getNodeValue();
          } else {
            value = String.valueOf(param);
          return value;



Wonderful insight

Posted by renaissance clothing for sale on May 06, 2010 at 10:14 AM BST #

Well, the post is actually the freshest on this laudable topic. I concur with your conclusions and will thirstily look forward to your future updates.

Posted by shaiya gold on August 02, 2010 at 07:33 PM BST #

Lovely to read!

Posted by I on November 02, 2010 at 03:21 PM GMT #

Post a Comment:
  • HTML Syntax: NOT allowed

Tech tweets are technical ideas and solutions that I might have recently come across while working on Oracle Fusion Middleware.


« April 2014