Problem with JDBC driver not being found after bundle refresh [message #659792] |
Tue, 15 March 2011 15:52 |
|
Hi all,
I am encountering a very strange error that I am unable to solve: I have a bundle making a JDBC connection that starts up successfully once, but every subsequent refresh of the bundle context results in an exception that the driver cannot be loaded. In order to make this problem reproducible I created a stripped-down Maven project which shows the problematic behavior once dropped into the container (I use STS 2.6 M02 to do this atm). The setup is a bit strange (taken from a real project) but it can be used to reproduce the exception.
The TestFactory class is a FactoryBean which takes a datasource configured in the spring context and tries to print out the DB product name. That's all . Drop it into the Virgo container (I tested it with 2.1.RELEASE and 3.0.M02) and you can see that it works initially (you need commons-dbcp-1.4.jar and commons-pool-1.5.4.jar in repository/usr for it to work). Once you redeploy the bundle (e.g. using Eclipse STS) it won't start, complaining that it cannot find the JDBC driver. I debugged into the DriverManager and it looks like there are no more registered drivers, although I don't know why. Does anyone have any idea?
Regards
Sven
[Updated on: Tue, 15 March 2011 15:54] Report message to a moderator
|
|
|
|
Re: Problem with JDBC driver not being found after bundle refresh [message #659944 is a reply to message #659937] |
Wed, 16 March 2011 09:50 |
|
Hello Glyn,
gladly . In order to prevent cluttering this post I attached the relevant log file snippets from the log.log file to this post. In the beginning you can see the initial output (with the successful deployment) and after that the output when I right-click on the bundle in the Server view and select "Redeploy" (in Eclipse).
I was also asking myself why the exception occurs several times although I perform the redeploy only once - it seems that Virgo is retrying to start the Spring context when it fails several times.
Hope that helps
Sven
-
Attachment: logoutput
(Size: 109.62KB, Downloaded 267 times)
|
|
|
|
Re: Problem with JDBC driver not being found after bundle refresh [message #659952 is a reply to message #659950] |
Wed, 16 March 2011 10:40 |
|
When I debugged the failing cases I saw that the same code was executed over and over again, resulting in multiple exceptions being reported (so it is not the same exception reported over and over again but the exceptions are thrown over and over again when the factory bean is initialized).
I already know the difference between the good and the bad case: the java.sql.DriverManager's internal "readDriver" collection no longer contains the postgres driver mapping after the refresh - that's what I don't understand because the only way this collection is modified is once the driver is unregistered (but PostgresQL's driver doesn't do this afaik).
To be honest I was unsure whether this is a problem of Virgo or my bundle or Equinox or a combination of these, that's why I posted it here. I just wanted to make sure that you did not know of some strange behavior in this area that would explain my case. My suspicions are:
* the redeployment of the bundle has some strange side effect that causes the DriverManager to be reinitialized with an empty driver collection
* my bundle's manifest is sufficiently correct to start the bundle once but fails when stopped and started over (I had this case several times with Felix and Equinox)
Anyway, I am now putting Equinox into debug mode and dive deep into the classloading of the framework and see what I can get.
Thanks for your help so far
Sven
|
|
|
|
Re: Problem with JDBC driver not being found after bundle refresh [message #660388 is a reply to message #659957] |
Fri, 18 March 2011 09:32 |
|
Further investigation revealed that the problem is related to the postgresql JDBC driver bundle(I osgified the plain JDBC jar using Bundlor and used it successfully in other scenarios).
While debugging I detected that - due to an unknown reason - the DriverManager's internal registered JDBC driver list changed. Debugging this class is difficult due to the fact that everything in it is static (another reason why I think static does not belong in an OO language, but that's another point ). Anyway, I detected that upon the first start of my bundle the internal driver list contains exactly one JDBC driver, namely my postgres driver. On all subsequent starts the list did not contain it, but it wasn't even the same list (memory-wise) than the first list. However, the list of all subsequent starts remained the same, so only the first time the bundle is started I get a different one. This can only happen in two cases:
* a Driver explicitly deregisters itself from the DriverManager (which the postgres driver doesn't)
* somehow a second DriverManager class is loaded by a different classloader *after* the Postgres JDBC driver has been loaded into memory by a classloader (postgres' driver performs registration upon loading of the class by the classloader)
Although I don't have any definite proof it seems that upon the first start of the bundle I get a different DriverManager than on subsequent starts. Then I performed a little trick: after the initial (successful) start of my bundle I explicitly refreshed the postgres bundle in the container and voila, *all* subsequent redeployments succeeded from there on.
I have a very vague suspicion but no evidence to prove it: is it possible that the first bundle start (and likewise the postgres driver that is started during bundle resolution phase) gets access to the DriverManager class that is loaded by the kernel-region Equinox, while at all subsequent starts the user-region Equinox provides the DriverManager class? I am not entirely sure my suspicion is justified because I only observed that the Equinox runtime is started two times (I detected it when I saw that my osgi.debug options only affected the kernel bundles and afterwards no additional output was printed, until I eventually also modified the org.eclipse.virgo.kernel.userregion.properties file and added additional debug options there), but I don't know if there is any relation.
Anyhow, I have a workaround for now (just refresh the postgres bundle once before performing any redeployments) and that does the trick for me.
[Updated on: Fri, 18 March 2011 09:49] Report message to a moderator
|
|
|
|
|
Powered by
FUDForum. Page generated in 0.06865 seconds