How to use Derby Client in Felix?
I want to run Derby Client from within an OSGi bundle. The bundle gets built by Maven so I added a dependency to org.apache.derby:derbyclient
. At runtime I get the following exception: java.sql.SQLException: No suitable driver found for jdbc:derby://localhost:1527/testdb
.
Interestingly the whole thing works when I use the embedded driver and a dependency to开发者_开发技巧 org.apache.derby.derby
. I just don't see the difference between those two.
What am I doing wrong and how can I fix it?
Some tidbits:
- After some advice I found on the Internet I set the following OSGi header:
DynamicImport-Package: *
. This fixed problems with the embedded driver but the client still fails. - The version of Derby I use is 10.7.1.1 which should be OSGi enabled (at least it has OSGi headers).
In OSGi it is recommended to not use the DrivverManager to get a connection. The better way is to use a DataSource.
So for derby client you could use this:
ClientDataSource ds = new ClientDataSource();
... // set properties here
Connection connection = dataSource.getConnection();
As the DataSource approach does not fiddle with the classloader it is much more reliable in OSGi.
Additionally it is a good practice to separate the DataSource from your client code and bind it as an OSGi service. This allows to keep the dependency to the database impl out of your code.
The easiest approach is to use pax-jdbc-config and let it create the DataSource for you from a configuration. In your own code you then just bind the DataSource as a service and are fine.
The current release version of pax-jdbc does not yet support the derbyclient but I just added this to the master. So the next release should contain it.
Okay, although not even half an hour passed since I asked the question I found a solution. I don't know how clean it is but it seems to get the job done:
ClassLoader ctxtCl = Thread.currentThread().getContextClassLoader();
try {
Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
try {
Class.forName("org.apache.derby.jdbc.ClientDriver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
dbConnection = DriverManager.getConnection("jdbc:derby://localhost:1527/testdb");
} catch (SQLException e) {
/* log, etc. */
} finally {
Thread.currentThread().setContextClassLoader(ctxtCl);
}
精彩评论