View Full Version : spring-jdbc JDBC Drivers
sarbx
Jun 25th, 2008, 01:19 AM
When using the DriverManagerDataSource from the spring-jdbc bundle, if the bundle's manifest is not manually updated to add the jdbc drivers package to the 'Import-Package' dependency list, it always fails with the exception,
Caused by: java.sql.SQLException: No suitable driver found for jdbc:derby://localhost:1527/nxp
at java.sql.DriverManager.getConnection(Unknown Source)
at java.sql.DriverManager.getConnection(Unknown Source)
at org.springframework.jdbc.datasource.DriverManagerD ataSource.getConnectionFromDriverManager(DriverMan agerDataSource.java:281)
at org.springframework.jdbc.datasource.DriverManagerD ataSource.getConnectionFromDriverManager(DriverMan agerDataSource.java:269)
at org.springframework.jdbc.datasource.DriverManagerD ataSource.getConnectionFromDriverManager(DriverMan agerDataSource.java:253)
at org.springframework.jdbc.datasource.DriverManagerD ataSource.getConnection(DriverManagerDataSource.ja va:234)
at org.eclipse.persistence.sessions.JNDIConnector.con nect(JNDIConnector.java:133)
... 63 more
[stderr] Exception [EclipseLink-4002] (Eclipse Persistence Services - 1.0 (Build SNAPSHOT - 20080604)): org.eclipse.persistence.exceptions.DatabaseExcepti on
Internal Exception: java.sql.SQLException: No suitable driver found for jdbc:derby://localhost:1527/nxp
Error Code: 0
Is this a known limitation? Is there a way to not add the jdbc driver import to the spring-jdbc bundle, but just adding it my application bundle.
Nico
Jun 25th, 2008, 01:38 AM
Hi,
One way you can do it is through the use of bundle fragments. Fragments are kind of bundles which are added at runtime to a host bundle classpath. Fragments can include Java classes and/or MANIFEST which will be added to the host bundle. So to solve your problem I can see two ways:
Create a fragment project which includes the JDBC driver classes then specify spring-jdbc or your domain bundle as the host bundle.
Create a fragment project which imports JDBC driver classes:
To do so, add:
Import-package: org.apache.derby.jdbc
to the fragment MANIFEST.MF file.
Then specify spring-jdbc or your domain bundle as the host bundle.
The second solution requires that you have JDBC driver classes available from somewhere else. You can do it by adding SpringSource Derby database bundle (http://www.springsource.com/repository/app/bundle/version/detail?name=com.springsource.org.apache.derby&version=10.3.2000001.599110) to your run platform.
I personally use the second solution for my own project and Oracle JDBC driver. This is working fine. Just make sure that you specify the correct fragment host bundle.
Marten Deinum
Jun 25th, 2008, 01:50 AM
There is also an issue with DriverManagerDataSource in OSGi environments (also it is not intended for production use). We suggest that you use the Commons DBCP or C3P0 connection pools, with those it works.
Check this JIRA issue (https://issuetracker.springsource.com/browse/PLATFORM-76).
sarbx
Jun 26th, 2008, 04:12 AM
I tried the fragment approach with all the three of them,
org.springframework.jdbc.datasource.DriverManagerD ataSource,
Fragment-Host: org.springframework.bundle.spring.jdbc
Import-Package: com.microsoft.sqlserver.jdbc,org.apache.derby.jdbc
com.mchange.v2.c3p0.ComboPooledDataSource
Fragment-Host: com.springsource.com.mchange.v2.c3p0
Import-Package: com.microsoft.sqlserver.jdbc,org.apache.derby.jdbc
org.apache.commons.dbcp.BasicDataSource
Fragment-Host: com.springsource.org.apache.commons.dbcp
Import-Package: com.microsoft.sqlserver.jdbc,org.apache.derby.jdbc
But only the DBCP data source works. Eventhough the spring-jdbc and c3p0 fragment bundles gets properly resolved, the datasource still throw java.lang.ClassNotFoundExceptio error for the JDBC drivers.
Costin Leau
Jun 27th, 2008, 01:33 AM
Interesting - I guess it depends on what classloaders are used to load the jdbc driver.
The DriverManagerDataSource uses a native method which apparently determines the caller classloader so that is likely to fail in an OSGi environment unless special care is taken.
I'm not sure about c3p0 but I guess it's something worth investigating since it's quite a popular datasource.
Marten Deinum
Jun 27th, 2008, 01:54 AM
Costin can we raise a JIRA for C3P0 in the BRITS? I'll do some investigation to see what is happening.
Costin Leau
Jun 27th, 2008, 02:19 AM
Sure - go ahead. I'm not sure whether BRITS the appropriate place but it's likely the best candidate.
Marten Deinum
Jun 27th, 2008, 02:33 AM
Thats what I was thinking also.
Issue (https://issuetracker.springsource.com/browse/BRITS-89) created.
Dave Syer
Jun 27th, 2008, 02:54 AM
Dbcp and c3p0 both already have BRITs bundles. They aren't fragments, but they work. Is there something I'm missing?
Marten Deinum
Jun 27th, 2008, 02:58 AM
Hmm maybe I forgot to ask the important question :) which version of C3P0 was used...
Edit: just did a simple test with the petclinic sample but cannot get it to work with C3P0, it works only with the commons DBCP... The only thing I changed was the MANIFEST to include the c3p0 stuff, installed c3p0 from BRITS, created a datasource based on C3P0, deploy, as soon as we query database, failure.
[2008-06-27 10:30:34.878] nousRunner$PoolThread-#2 com.mchange.v2.resourcepool.BasicResourcePool.unkn own W com.mchange.v2.resourcepool.BasicResourcePool$Acqu ireTask@1ca265 -- Acquisition Attempt Failed!!! Clearing pending acquires. While trying to acquire a needed new resource, we failed to succeed more than the maximum number of allowed acquisition attempts (30). Last acquisition attempt exception:
java.sql.SQLException: No suitable driver
So it looks like an issue to me...
sarbx
Jun 27th, 2008, 03:34 AM
The one I'm using,
<groupId>com.mchange.c3p0</groupId>
<artifactId>com.springsource.com.mchange.v2.c3p0</artifactId>
<packaging>jar</packaging>
<version>0.9.1.2</version>
I did get them from the springsource repository. From what Dave is saying, if they are in the springsource BRITS then they should behave properly in a OSGi environment ?
Dave Syer
Jun 27th, 2008, 04:08 AM
I get the same. Makes you wonder why it is in BRITS if it doesn't work. I know we had to patch the DBCP jar so it didn't use Class.forName(). Looks like we haven't done the same job on c3p0.
markous
Jul 10th, 2008, 03:53 PM
The reason is because we are only passing the driver classname to the connection pool in the mchange bundle and not the actual instance of the driver. Mchange does not import any sql drivers, and ComboPooledDataSource only have a setProviderClass method. One way of fixing it is add Require-Bundle in the mchange manifest to import the sql drivers, but that is no the right way to fix it. The ComboPooledDataSource should have a setDriver(Driver) method.
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<property name="driverClass" value="com.mysql.jdbc.Driver"/>
<property name="jdbcUrl" value="jdbc:mysql://${jdbc_host_account}:${jdbc_port_account}/${jdbc_schema_account}"/>
<property name="user" value="${jdbc_user_account}"/>
<property name="password" value="${jdbc_pass_account}"/>
<property name="idleConnectionTestPeriod" value="1800"/>
<property name="maxIdleTime" value="3600"/>
<property name="maxConnectionAge" value="7200"/>
<property name="minPoolSize" value="10"/>
<property name="acquireIncrement" value="10"/>
<property name="maxPoolSize" value="40"/>
</bean>
Powered by vBulletin® Version 4.2.1 Copyright © 2013 vBulletin Solutions, Inc. All rights reserved.