JBPM Reporting can make use of JNDI datasources.

Once a JNDI datasource (say jdbc/testDS1) has been defined on Tomcat, the following needs to be added to the report definition as a datasource:

<property name="odaJndiName">java:comp/env/jdbc/testDS1</property>

There is a problem with this though.

Since Tomcat is not EE compliant with respect to JNDI, our report is no longer portable to a real J2EE application server without modification of the JNDI reference.

With BIRT on Tomcat we appear to be locked into using the Tomcat JNDI context – which forces the non standard JNDI URL above.

It would be ideal to be able to use a different JNDI context – bypassing Tomcat completely. In the context of this post series, it would be optimal to use the bitronix.tm.jndi.BitronixInitialContextFactory.

Our target configuration for the report is to have the following JNDI specification work:

<property name="odaJndiName">jdbc/testDS1</property>

In order to do this – some functionality within BIRT may be leveraged – with a minor fix as follows.

Required software / tools:


i) Create the file:

${CATALINA_HOME}/webapps/gwt-console-server/WEB-INF/classes/jndi.properties

With contents:

java.naming.factory.initial = bitronix.tm.jndi.BitronixInitialContextFactory

ii) Now patch the following jar:

${CATALINA_HOME}\webapps\gwt-console-server\WEB-INF\lib\org.eclipse.birt.runtime_3.7.0.v20110615-1818.jar

a) Create a copy of org.eclipse.birt.runtime_3.7.0.v20110615-1818.jar in workspace area, rename to org.eclipse.birt.runtime_3.7.0.v20110615-1818.zip and unzip.

b) Remove the jar signing (you are encouraged to resign following the fix below – but this is not necessary):

Delete files:

org.eclipse.birt.runtime_3.7.0.v20110615-1818/META-INF/ECLIPSEF.RSA org.eclipse.birt.runtime_3.7.0.v20110615-1818/META-INF/ECLIPSEF.SF

Replace contents of MANIFEST.MF with the following:

Manifest-Version: 1.0  
Bundle-Vendor: Eclipse.org  
Bundle-Name: BIRT Runtime SDK 
Bundle-SymbolicName: org.eclipse.birt.runtime 
Bundle-Version: 3.7.0.v20110615-1818 

We are going to patch the following class: JndiDataSource.class

c) In Eclipse create a new Java Project, add all jars included in ${CATALINA_HOME}\webapps\gwt-console-server\WEB-INF\lib to the buildpath (classpath).

Create the following package under src:

org.eclipse.birt.report.data.oda.jdbc

Create new class: JndiDataSource

d) In the unzipped jar, locate JndiDataSource.class and decompile.

Copy the decompiled code to Eclipse / JndiDataSource

e) Add:

import java.io.InputStream;

f) Replace the method getDriverJndiProperties() with the following:

 
protected Properties getDriverJndiProperties() 
{ 
/* File jndiPropFile = getDriverJndiPropertyFile(); 
   if (jndiPropFile == null) { return null; } 
*/ 
   Properties jndiProps = new Properties(); 
// FileInputStream inputStream = null; 
   InputStream inputStream = null; 
   if (sm_logger.isLoggable(Level.INFO)) 
      sm_logger.info("getDriverJndiProperties(): Loading " + JNDI_PROPERTIES + " from classpath"); 
   try { 
 // inputStream = new FileInputStream(jndiPropFile); 
    inputStream = this.getClass().getClassLoader().getResourceAsStream(JNDI_PROPERTIES); 
    jndiProps.load(inputStream); 
   } 
   catch (Exception ex) 
   { 
      if (sm_logger.isLoggable(Level.INFO)) 
         sm_logger.info("getDriverJndiProperties(): " + ex.toString()); jndiProps = null; 
   } 
   if (inputStream != null) 
   { 
      try { 
         inputStream.close(); 
      } 
      catch (IOException e) 
      { 
         if (sm_logger.isLoggable(Level.INFO)) 
            sm_logger.info("getDriverJndiProperties(): " + e.toString()); 
         inputStream = null; 
      } 
   }

   if (sm_logger.isLoggable(Level.CONFIG))
   {
      int propertyCount = jndiProps == null ? 0 : jndiProps.size();
      sm_logger.config("Driver JNDI property count: " + propertyCount);
   }

   return jndiProps;
}

This fixes the BIRT functionality for loading jndi.properties. Once in place, when a JNDI datasource is specified, BIRT will check the classpath for a jndi.properties file, and will load if found.

g) Build the project.

h) Replace the JndiDataSource.class in the unzipped jar with the Eclipse output.

i) Rebuild the jar with name:

org.eclipse.birt.runtime_3.7.0.v20110615-1818.patched.jar

j) Replace:

 ${CATALINA_HOME}\webapps\gwt-console-server\WEB-INF\lib\org.eclipse.birt.runtime_3.7.0.v20110615-1818.patched.jar 

With:

 org.eclipse.birt.runtime_3.7.0.v20110615-1818.patched.jar 

k) Restart Tomcat.

With the above configuration, BIRT will now use the java naming factory specified in jndi.properties – if jndi.properties is present, and if a naming factory is specified.

In the context of this series, the following JNDI can be used:

<property name="odaJndiName">jdbc/testDS1</property>
Advertisements