OSGi vs C3P0
Posted on August 18, 2008 by Tommy McGuireContinuing the OSGi saga...
The web application framework I am building attempts to leverage an existing configuration framework, which has caused me a bit of a headache. The configuration framework is built around a set of database tables holding the configuration information and provides a one-stop source for all of it, including basic configuration data, JDBC DataSource connections, LDAP connections, etc., etc., etc. (And ultimately including the log tables written from Log4j.)
The one-stop is the initial database connection to get to the configuration data. My headache starts with the framework, which uses a c3p0 JDBC connection pool (see also this), which in turn includes the wondrous JDBC-driver-from-class-name thingy. Coupled with the wondrous OSGi class loader hacks, the result is an almost certain headache. Here is my aspirin:
- I bundlized (or used off-the-shelf bundles for) the JDBC drivers: MySQL, Oracle, SQLServer. ("Bundled" does not feel like the right verb.)
- I got the c3p0 bundle from the SpringSource Enterprise Bundle Repository, which was where I also got the Oracle JDBC driver bundle (and the required javax.resource bundle).
- I created a fragment bundle to provide an attachment between the JDBC driver bundles and c3p0. This fragment consists only of the MANIFEST.MF file, which itself really only consists of the following lines:
When this fragment bundle is resolved, it links to the c3p0 bundle and effectively adds the Import-Package header to the c3p0 bundle. As a result, the c3p0 bundle imports the listed packages from the respective JDBC driver bundles, making the driver classes available to whichever variant of Class.forName() c3p0 uses; ideally, not Class.forName, which has issues.
- I installed all of the above in the SpringSource Application Platform's repository/bundles/usr directory, where they are available to the S2AP OSGi runtime.
- I fired up S2AP.
- I deployed the bundlized version of my config framework in the S2AP pickup directory, which caused it to begin running and to export it's data service interface into the OSGi service registry.
- I deployed my test bundle to the S2AP hot-deployment pickup directory. This bundle imports the services, connects to the default datasource, and runs a basic query. Success!
There may well be a better way of doing this, but the minor configuration bundle attached to c3p0 seems acceptable.
Edit: I just looked at this post and realized I never mentioned why it worked.
Ps. If you need it, this is the MANIFEST.MF of the c3p0 fragment:
Bundle-Name: NASA Frameweork Core C3P0 Config Fragment
Pps. That may not be the c3p0 from the SpringSource repository; modify the bundle symbolic name in the Fragment-Host header as needed.
I wrap my project in OSGi bundle(just call my first start method from Activator.start()). In my project I use ORM ActiveObjects and c3p0 pool. All of project dependencies (jar librarys) are in class path. If I run my project with c3p0 it is takes about 5 minutes to 1 query to DB. Without c3p0 it is works correctly. In what is a problem? Thanks a lot!
To tell you the truth, I am afraid I do not have a whole lot of experience with c3p0. I have used it a bit, but the system that uses the c3p0 pools was written by someone else and all I did was to OSGi-ify it. I also have no idea what an ORM ActiveObject is.
It sounds like you have the right set-up, and if it works at all, then OSGi is probably not the problem. (Now, if you had gotten a ClassNotFound exception....)
I suspect there is a problem in your c3p0 configuration. You might try that configuration without OSGi, or find someone who knows more about c3p0. Sorry.