How to “OSGIfy” an Oracle jdbc driver with Spring Roo

If you want to use Spring Roo to reverse engineer an existing Oracle database, you need to bundle the Oracle driver in an OSGI format (this is not required if you want to use Spring Roo with Oracle in a top down approach). For copyright reasons, the OSGI driver for Oracle is not furnished by Spring Roo. And Oracle doesn’t provide it either: I have checked on their “Metalink” support website. So, you’ll need to create it yourself. But, as many Spring Roo beginners have certainly already noticed thus far, this is not always an easy task.

I introduce here a recipe that has been tested with the Oracle jdbc driver 11.2.0.2 and with Spring Roo 1.1.4 and 1.1.5. It is susceptible to work with other versions too, however I can’t offer any guarantee of result (anyway I’m convinced you’re an adventurer and, as such, you don’t need guarantees ;-)). I’m also purposely verbose in the explanation of the process in order to give more chances to make it reproducible with other versions.

1. Download the driver from Oracle.

2. Install the driver in your local maven repository.

Maven command:
mvn install:install-file -Dfile=filename.jar -DgroupId=groupid -DartifactId=artifactId -Dversion=version -Dpackaging=jar

Example:
mvn install:install-file -Dfile=ojdbc5-11.2.0.2.jar -DgroupId=com.oracle -DartifactId=ojdbc5 -Dversion=11.2.0.2 -Dpackaging=jar

3. Create a new folder and “cd” into it. I use “C:\eclipse_workspaces\roo\osgi\” below.

4. Launch the Roo shell.

5. Create an addon wrapper for your jar. The addon wrapper command will create a maven project (pom.xml) that will be used to transform your normal driver into an OSGI driver.

Make sure the parameters match with the ones used to install the driver in your local maven repository (step 2).

Roo command:
addon create wrapper --topLevelPackage com.oracle.roo.JDBC --groupId groupid --artifactId artifactId --version version --vendorName Oracle --licenseUrl http://www.oracle.com

Example:
addon create wrapper --topLevelPackage com.oracle.roo.JDBC --groupId com.oracle --artifactId ojdbc5 --version 11.2.0.2 --vendorName Oracle --licenseUrl http://www.oracle.com

6. Quit the Roo shell and launch the maven goal mvn bundle:bundle. This command will generate the OSGI version of the driver under the target directory. Alternatively if you don’t want to quit the roo shell, you can also execute: perform command --mavenCommand bundle:bundle

7. Install the OSGI driver in Spring Roo. Run one of the following equivalent commands in the roo shell:

osgi install --url file:///C:\eclipse_workspaces\roo\osgi\target\com.oracle.roo.jdbc..jar

or

osgi start--url file:///C:\eclipse_workspaces\roo\osgi\target\com.oracle.roo.jdbc..jar

Example:
osgi install --url file:///C:\eclipse_workspaces\roo\osgi\target\com.oracle.roo.jdbc.ojdbc5-11.2.0.2.0001.jar

On successful completion, the command will return a Bundle ID that corresponds to the location of the OSGI file in the “Apache Felix” OSGI repository embedded by Spring Roo.

This is not the end yet, as you’ll probably get a strange error message when using it. So, please, keep on reading…

8. Try this new driver with Roo on an existing Oracle database:

database reverse engineer --shema xxx

If you get an error message of the style “Unresolved contraint in bundle com.springsource.oracle.jdbc”, that means your OSGI bundle has a dependency on another bundle:

Example 1:

 

[com.springsource.oracle.jdbc [66]] FrameworkEvent ERROR
org.apache.felix.log.LogException: org.osgi.framework.BundleException: Unresolved constraint in bundle com.springsource.oracle.jdb
c [66]: Unable to resolve 66.0: missing requirement [66.0] package; (&(package=javax.resource)(version>=1.5.0)(!(version>=2.0.0)))
at org.apache.felix.framework.Felix.resolveBundle(Felix.java:3409)
at org.apache.felix.framework.Felix.loadBundleClass(Felix.java:1594)
at org.apache.felix.framework.BundleImpl.loadClass(BundleImpl.java:904)
[… cont.]

In this first case, the bundle has an unsatisfied dependency on javax.resource

Example 2:

 

[com.oracle.roo.jdbc.ojdbc5 [66]] FrameworkEvent ERROR
org.apache.felix.log.LogException: org.osgi.framework.BundleException: Unresolved constraint in bundle com.oracle.roo.jdbc.ojdbc5
[66]: Unable to resolve 66.0: missing requirement [66.0] package; (package=com.sun.security.auth.module)
at org.apache.felix.framework.Felix.resolveBundle(Felix.java:3409)
at org.apache.felix.framework.Felix.loadBundleClass(Felix.java:1594)
at org.apache.felix.framework.BundleImpl.loadClass(BundleImpl.java:904)
[… cont.]

In this second case, the bundle has an unsatisfied dependency on com.sun.security.auth.module

9. Go to the SpringSource Enterprise Bundle Repository website and search for your missing dependencies. Input the full package name of the missing dependency to do the search (in our example “javax.resource” and “com.sun.security.auth.module”; the second won’t give any result so keep on reading).

10. If you find the dependency, download it and install it as an OSGI bundle in Spring Roo (see 7). If you don’t find it, try to remove the dependency from the Imports entries in the Manifest: most of the times the Manifest generated from the “addon create wrapper” command is too verbose. It is the aggregated result of the inspection of the import statements and method signatures in all the classes of the provided jar that needs to be OSGIfied.

11. Remove the faulty OSGI driver from the Felix repository:
– Use “osgi ps” to retrieve the ID of the OSGI bundle to remove.
– Use “osgi headers” to get the Bundle-SymbolicName of the corresponding OSGI bundle. Probably “com.oracle.roo.jdbc.ojdbc5” or “com.oracle.roo.jdbc.ojdbc6”.
– Use “osgi uninstall –bundleSymbolicName com.oracle.roo.jdbc.ojdbcx

Atfer removing the faulty OSGI driver, repeat steps 7, 8, 9, 10 and 11 until it works.

This entry was posted in Tips and tricks and tagged , , , , , , . Bookmark the permalink.

14 Responses to How to “OSGIfy” an Oracle jdbc driver with Spring Roo

  1. Pingback: creating OSGi enabled jar for ORACLE (for Spring Roo « Ukrainian Oracle User Group

  2. Winarto says:

    Nice article.

  3. Luke says:

    Here is the list of packages I had to remove from the manifest:

    com.sun.security.auth.module
    oracle.i18n.text
    oracle.i18n.text.converter
    oracle.ons
    oracle.security.pki
    oracle.xdb,oracle.xml.parser.v2
    sun.security.krb5
    sun.security.krb5.internal,sun.security.util

    After removing all those and adding javax.resource as specified in step 9, I FINALLY got a working version. I used ojdbc6, version 11.2.0.3.

    Thanks for the article, this ridiculous topic stumps me every time I upgrade Roo.

  4. sudhakar says:

    Beautiful !! nicely explained.
    I used oracle 10.2.0.2 version. i do not have any problem with the manifest dependency.

  5. rfoskett says:

    if it helps anyone, some simple batch commands below that might speed up bits of this. Assumes oraclexe installed below C:\oraclexe

    rem 1) setup stuff – creates directories below roo installation for OSGI wrapper
    set ROO_ADDON_DIR=%ROO_HOME%\addons
    set ORACLE_HOME=C:\oraclexe\app\oracle\product\11.2.0\server
    rmdir /S %ROO_ADDON_DIR%\com.oracle.roo.jdbc
    mkdir %ROO_ADDON_DIR%\com.oracle.roo.jdbc
    cd %ROO_ADDON_DIR%\com.oracle.roo.jdbc

    rem 2) uninstall any previous versions
    roo osgi uninstall –bundleSymbolicName com.oracle.roo.jdbc

    rem 3) install the oracle odbc driver
    mvn install:install-file -Dfile=%ORACLE_HOME%\jdbc\lib\ojdbc6.jar -DgroupId=com.oracle -DartifactId=ojdbc6 -Dversion=11.2.0.0 -Dpackaging=jar -DgeneratePom=true

    rem 4) create top level package for building OSGI wrapper
    roo project –topLevelPackage com.oracle.roo.jdbc

    rem 5) create OSGI wrrapper for Oracle JDBC pacakges
    roo addon create wrapper –topLevelPackage com.oracle.roo.jdbc –groupId com.oracle –artifactId ojdbc6 –version 11.2.0.0 –vendorName Oracle –licenseUrl http://www.oracle.com

    rem 6) add line “*,javax.management.*” to %ROO_ADDON_DIR%\com.oracle.roo.jdbc\pom.xml for maven-bundle-plugin

    rem 7) run maven command to create OSGI wrapper bundle
    mvn bundle:bundle

    rem 8) open %ROO_ADDON_DIR%\com.oracle.roo.jdbc\target\com.oracle.roo.jdbc.ojdbc6-11.2.0.0.0001.jar in 7zip and
    rem edit META-INF/MANIFEST.MF and remove following from bottom Import-Package section
    rem com.sun.security.auth.module, oracle.i18n.text, oracle.i18n.text.converter, oracle.ons,
    rem oracle.security.pki, oracle.xdb,oracle.xml.parser.v2, sun.security.krb5, sun.security.krb5.internal,sun.security.util

    rem 9) install update jar file for OSGI JDBC wrapper
    roo osgi install –url file:///%ROO_ADDON_DIR%\com.oracle.roo.jdbc\target\com.oracle.roo.jdbc.ojdbc6-11.2.0.0.0001.jar

    rem 10) if you get an javax.resource error when using database introspect command then install the OSGI package via command below
    roo osgi install –url http://ebr.springsource.com/repository/app/bundle/version/download?name=com.springsource.javax.resource&version=1.5.0&type=binary

  6. Pingback: Database Reverse Engineering With Spring Roo « Matt Brown – Journeys of a software engineer

  7. prahari says:

    Thank you Matt and rfoskett,
    Your explanation saved me lot of time and frustration.
    I am having problem at the LAST step: roo database introspect –schema xxx

    Here is the error message:

    ” Unable to get connection from driver: [jcc][t4][10509][13454][4.13.80] Connection to the data server failed. The IBM Data Server for JDBC and SQLJ license was invalid
    or was not activated for the DB2 for z/OS subsystem. If you are connecting directly to the data server and using DB2 Connect Unlimited Edition for System z, perform the
    activation step by running the activation program in the license activation kit.

    If you are using any other edition of DB2 Connect, obtain the license file, db2jcc_license_cisuz.jar, from the license activation kit, and follow the installation
    directions to include the license file in the class path. ERRORCODE=-4230, SQLSTATE=42968 ”

    I installed DB2 client version 9.7.5 and it does not come with db2jcc_license_cisuz.jar anymore as mentioned in :
    http://publib.boulder.ibm.com/infocenter/db2luw/v9r7/index.jsp?topic=%2Fcom.ibm.db2.luw.wn.doc%2Fdoc%2Fc0057378.html

    I include the only license file i have: db2jcc_license_cu.jar

    and it appears as follows in POM.XML

    db2jcc4
    9.7.5
    ${pkgVersion}.0001
    IBM

    file:///%DB2_HOME%\java\db2jcc_license_cu.jar
    com/ibm/db2/roo/jdbc
    ${project.name}

    Did not see any body having this issue on spring forums. Was wondering if you can help

    Thanks in advance
    prahari

  8. haripriya says:

    Getting a javax.management.JMException not found by [84]
    when reverse engineered

  9. Gary Klaus says:

    An easy way to avoid the dependency problem is to add this line to pom.xml under the felix plugin tag before building the bundle. It tells maven to skip the listed packages.

    !javax.resource,!javax.resource.spi,!javax.resource.spi.endpoint,!javax.resource.spi.security,!oracle.security.pki,!oracle.ons,!oracle.i18n.text,!oracle.i18n.text.converter,!oracle.xml.parser.v2,!sun.security.krb5.internal,!oracle.xdb,!com.sun.security.auth.module,!sun.security.util,!sun.security.krb5,*

    I found this solution in this github project. https://gist.github.com/skhatri/3016284

    • Gary Klaus says:

      okay, XML tags are not shown in a comment. How about this.

      <configuration>
      <instructions>
      <Import-Package>!javax.resource,!javax.resource.spi,!javax.resource.spi.endpoint,!javax.resource.spi.security,!oracle.security.pki,!oracle.ons,!oracle.i18n.text,!oracle.i18n.text.converter,!oracle.xml.parser.v2,!sun.security.krb5.internal,!oracle.xdb,!com.sun.security.auth.module,!sun.security.util,!sun.security.krb5,*</Import-Package>

  10. Johna993 says:

    Thank you for your blog article. Great. dkfaadacfdka

Leave a comment