2 Replies Latest reply on Jan 19, 2012 12:32 PM by Timothy Stewart

    Oracle JDBC ClassNotFound issues

    Timothy Stewart Newbie

      So, I have created a bundle (bundle A) which exposes a service through blueprint matching interface javax.sql.DataSource.  The bundle has the oracle jdbc jar and ucp.jar embedded in it.


      A second bundle (bundle B) creates a service reference requesting a service to match the DataSource interface.  The goal here was to create a shared datasource across the ESB.


      According to the logs, the datasource is actually created and returned, but the consuming bundle B fails with a java.lang.ClassNotFoundException: oracle.jdbc.pool.OracleDataSource.


      I have found several threads on here referring to this problem, and the recommended solution seems to be to attach a fragment bundle exporting the oracle.jdbc.pool package to the second bundle B.


      I would like to understand why a fragment bundle is the way to go.  Are there reasons these other options would not work, or are they less desirable for some reason?


      1. Embedding the oracle jdbc jar in the second bundle B?


      2. "bundlizing" the oracle jdbc jar, and importing the packages into both the first (A) and second bundle B (so we no longer embed in the first bundle)?


      3. Similar to #2, having the first bundle A export the oracle.jdbc.pool package provided by its embedded jars and importing that package with the second bundle?


      Are there classpath issues here that we get around by using a fragmented bundle (which , if I understand correctly, uses the classpath of its parent bundle)?


      Thanks for any explanation.  This seems like a common question or pitfall that might warrant a FAQ, or tutorial or example.  Then again, maybe I just haven't found it.  Most of what I have found gives a direction (which I'll try to follow or I"ll play with these other 3 things I thought of), but not really a clear understanding.


      - Tim Stewart.

        • 1. Re: Oracle JDBC ClassNotFound issues
          Freeman(Yue) Fang Master



          First of all, in most cases, the exception like

          java.lang.ClassNotFoundException: oracle.jdbc.pool.OracleDataSource.

          comes from the bundle which manage the datasource/connectionPool, which is 3rd party bundle like commons-dbcp or spring-jdbc, it's not your customer bundle, which means you are hard to change those 3rd party bundle headers, so your question 1,2,3 doesn't work.


          And please take a look at my comment here[1]




          • 2. Re: Oracle JDBC ClassNotFound issues
            Timothy Stewart Newbie

            Thanks for the reply.  I ended up doing the following:


            1. Installed oracle jdbc JAR and UCP.jar into Fuse ESB using the "wrap" option.


            2. Removed the embedded JARs from bundle A (the datasources provider bundle) and let it import the required packages from #1.  I used a DynamicImport-Package *.  This was important as multiple instances of the JARs in multiple classloaders were causing other problems.


            3. Added a DynamicImport-Package * to bundle B (and any other bundle using datasources) so that they will search for and find any necessary oracle classes from the new wrapped bundles. 


            The DynamicImport was easier because it was difficult to know which Oracle classes and packages would actually be used.  I went through several before I just put in the DynamicImport.


            Also it seems important not to have those Oracle Jar's anywhere else in the system.  Only the one wrapped bundle should contain the JARs, otherwise I was getting strange exceptions from oracle.


            Finally, I had to restart the ESB everytime I deployed.  Seemed things were not uninstalling properly and it needed to start up clean.  I don't know why this was required, but not a big deal for me.


            I think some of the other options might have had trouble because of the necessity of only loading up the oracle classes once.  I was receiving things like "Instance already created" when requesting the pool, so I would be worried about embedding those jars in multiple bundles or even attaching as a fragment to multiple bundles.


            If you had one bundle using a datasource and another bundle using a different datasource and they each had embedded or fragmented bundles maybe this would be okay; but in the case where i have multiple bundles trying to share the same datasource it seems a requirement to get those oracle jars into their own single shared bundle.


            Thanks for the answer and the help.  The problem is resolved, and I think I understand things better now that I've cleaned up my own mess.


            - Tim.