Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » Virgo » Problem with JDBC driver not being found after bundle refresh
Problem with JDBC driver not being found after bundle refresh [message #659792] Tue, 15 March 2011 15:52 Go to next message
Sven Panko is currently offline Sven Panko
Messages: 13
Registered: February 2011
Location: Germany
Junior Member
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 Smile. 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 #659937 is a reply to message #659792] Wed, 16 March 2011 09:13 Go to previous messageGo to next message
Glyn Normington is currently offline Glyn Normington
Messages: 1222
Registered: July 2009
Senior Member
Please post the diagnostics for "Once you redeploy the bundle (e.g. using Eclipse STS) it won't start, complaining that it cannot find the JDBC driver."
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 Go to previous messageGo to next message
Sven Panko is currently offline Sven Panko
Messages: 13
Registered: February 2011
Location: Germany
Junior Member
Hello Glyn,

gladly Smile. 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 81 times)
Re: Problem with JDBC driver not being found after bundle refresh [message #659950 is a reply to message #659944] Wed, 16 March 2011 10:28 Go to previous messageGo to next message
Glyn Normington is currently offline Glyn Normington
Messages: 1222
Registered: July 2009
Senior Member
Thanks for the logging output. I suspect the multiple stack traces in the log are due to the same exception percolating its way up the stack.

The problem is probably related to resource lookup or class loading after the update. So I guess there's something wrong with the wiring after the refresh.

To debug this, I would debug through the successful case to get an idea of how the driver manager finds drivers and in particular what resource lookups or class loads are an essential part of this. Then debug through the failing case and play "spot the difference".

But before getting into that level of detail, it may be worth simply comparing the wiring of the relevant bundles in the successful and failing cases. You can use the Virgo admin console (OSGi state view) or the Equinox console to do this.

If you can't find the problem, please raise a bug so it will go on the backlog for us to look at. I'm afraid we don't have much resource for helping users investigate problems, so we have to try to teach you to do it yourselves and use bug reports to prioritise. I'm sure you understand.
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 Go to previous messageGo to next message
Sven Panko is currently offline Sven Panko
Messages: 13
Registered: February 2011
Location: Germany
Junior Member
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 #659957 is a reply to message #659952] Wed, 16 March 2011 11:16 Go to previous messageGo to next message
Glyn Normington is currently offline Glyn Normington
Messages: 1222
Registered: July 2009
Senior Member
Thanks for the clarification about exception throwing. I guess there is retry logic somewhere like Commons DBCP as Virgo does not retry bundle start.

I'm certainly not aware of behaviour in Virgo which would give rise to the symptoms you are seeing.

Good luck debugging...

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 Go to previous messageGo to next message
Sven Panko is currently offline Sven Panko
Messages: 13
Registered: February 2011
Location: Germany
Junior Member
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 Confused). 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

Re: Problem with JDBC driver not being found after bundle refresh [message #660391 is a reply to message #660388] Fri, 18 March 2011 09:39 Go to previous messageGo to next message
Glyn Normington is currently offline Glyn Normington
Messages: 1222
Registered: July 2009
Senior Member
Well done!

I hope your suspicion is wrong because that would seem to indicate Virgo misbehaving. To check it out, you could use the class loading debugging commands in the Equinox console described in Hristo's blog. You'll be able to see which bundles in the system can load the DriverManager class and pin down whether it is coming from the kernel or the user region in both the successful and the failing cases.

Anyway, I'm glad you found a workaround.
Re: Problem with JDBC driver not being found after bundle refresh [message #660392 is a reply to message #660391] Fri, 18 March 2011 09:47 Go to previous message
Sven Panko is currently offline Sven Panko
Messages: 13
Registered: February 2011
Location: Germany
Junior Member
I haven't tried that because I was unsure how to exactly detect where the classes are coming from (even a desperate attempt to use jmap to get a heapdump and inspect the dominators failed because Virgo did not respond well to jmap's connection attempts). Anyway I will give it a try as soon as I have some time.

Thanks for the hint.
Previous Topic:Milestone 3.0.0.M03 available
Next Topic:Problem w/ Virgo 'updated manifest' after deployment
Goto Forum:
  


Current Time: Thu Oct 02 16:45:03 GMT 2014

Powered by FUDForum. Page generated in 0.02418 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software