An Oracle blog about BI Publisher

BIP Extensions

I have recently seen a spate of requests for new functions to be built into BIP - we have enhancements coming out of our ears. For those of you that can not wait and have a little java experience or even have access to a java resource read on.

Before I get into the meat of this entry - Oracle will not support you if you choose to use the following methods described. At least I dont think they will - please dont log a TAR if you get stuck :o)

As many of you know, that RTF template you develop is converted to an XSLFO stylesheet and the Oracle XSL transformation engine is then used to apply said template to XML data - so at the heart of the whole engine is an XSL transformer. The Oracle implementation provides a framework that allows you to extend the XSLT engine to create your own functions. We even make use of it in our xdoxslt: functions. I have mounted a cut down version of the XDK dev guide here - it just contains the java section. Useful to understand whats going on in the XSLT engine - check out the 'Programming with Oracle XSLT Extensions' section.

So how do I do it?
From a high level, you create a java class with a method that will process the incoming data and return a result to the transformation engine to be rendered. To then use the new function, your extensions need to be declared in the template as a namespace and the new function name called using the namespace prefix. For example 


where 'bipext' is the namespace and welcomeMsg is method to be called. Of course your java class needs to be in the classpath of the publisher engine to be picked up. 

Let's keep it simple to start with, I have created a very simple class that has only a single method:

package oracle.bip.extensions;

public class BIPExtensions {
    public BIPExtensions() {

  public static final String welcomeMsg(String name)
               return("Hello " + name+" !");

The welcomeMsg method takes a string input value and returns a string, 'Hello <<name>> !' to be rendered in the output - yes, its very simple - not Hello World thou you have to admit :0)

Couple of other points to notice:

  1. The package path is important - we'll use this in the namespace declaration.

  2. The 'welcomeMsg' method is 'static' - the Oracle XDK can handle both static and non-static methods - they explain further in their documentation here.

We now have our java class and method, it needs to be placed into the classpath for the engine - I'll come back to this, so lets assume its done.

Now we need to declare that we want to use our new extensions in our template. We just declare these as a namespace:


notice that 'bipext' is going to be the prefix we'll use, you can have your own. In the URI we must have :


followed by the package path using period (.) separators and then the class name that holds the extension method(s).

Once, that is done we can call the function in the template.


of course 'Tim' could be replaced with an element name - just so long as its a string or can be interpreted as such.
When the template is applied and the extension is called we get back

'Welcome Tim !'

and its inserted into our output.

Being able to test your functions relies on your class being in that all important classpath - if you are using JDeveloper or similar its simple enough to get your class archive in - just ensure its above the xmlparserv2XXX.jar and xdoparser.jar in the list.  
Using Template Builder for MSWord is a little more tricky and requires what can only be described as 'a bit of hacking' - but with some care you can test them. Template Builder does not support setting a classpath or registering new java functions - yet. The only way around it is to get you class into the xdocore.jar in the /jlib directory under the plugin install. If you are up for it ...

  1. Make a copy and back up the original xdocore.jar and rename it

  2. Using winzip or similar open the jar up

  3. Now you need to merge the extension class into the jar(zip) file - just make sure you preserve that directory path in the archive. In our case, 'oracle.bip.extensions.BIPExtensions.class'. In the visual zippers this is drag an drop but you may need to work out the command line syntax - sorry, Im lazy and use a UI.

  4. Close the archive

Hacking done - you're now ready to test the function using the Template Builder. Now remember, you get into a mess, just back up to step 1 again - remember support do not want a ticket asking about how to unhack Template Builder and dont tell em Tim told you to do it :o)

Once you're happy with the template, deploy it and your class to the server and you're good to go.

Now, here we tackled the simple stuff - you, Im sure will get very creative - got common functions all your templates need and can not be satisfied in a sub template? build an extension - the possibilities are endless and I can hear the cogs whirring from here. If you come up with a hot extension and want to share it, send it in and I'll post it here.

Join the discussion

Comments ( 4 )
  • Frank Menne Friday, November 23, 2007
    Hi !
    I implemented this function successfully, but I am unable to pass "real report parameters" into this Java - Commandline:
    <? sql: ExecSql('select ', ' @PICK_SLIP_NUMBER ' ,'from dual ') ?>
    any ideas ?
  • Tung Ho Monday, March 23, 2009
    I have done with your instruction. It's Ok with PREVIEW on Ms Word, but we don't now how to deploy to BIP, pls help me.
    1. How to package my classes ?
    *.class is OK ? or need to package as *.JAR ?
    2. Where to deploy my package on BIP ?
    --> to classpath or lib folder on BIP ?
    Thanks for your help.
  • Brett Wednesday, June 10, 2009
    Wonderful article. I got this working last night to create a class that will translate an Oracle date in the standard DD-MON-YY format to a MSFT format YYYY-MM-DD so that we can format dates without a lot of substr logic in the template.
    Endless possibilities. I sincerely hope that some thought is given to adding an extension JAR to XMLPublisher etc so that clients can do so without changing core jar files.
    Awesome blog.
  • guest Tuesday, May 17, 2011
    A cleaner way is to create a bat file that references the missing jar while starting up word. For example
    REM Start of bat file
    echo %1
    set _JAVA_OPTIONS=-Xbootclasspath/a:<Path to the Jar file>\BIPExtension.jar;
    "<Path to winword.exe file>\Office12\Winword.exe" %1
    REM END of Bat file
Please enter your name.Please provide a valid email address.Please enter a comment.CAPTCHA challenge response provided was incorrect. Please try again.