Hi,
I've been using the Derby Embedded driver in an environment where it is
unsafe to have the JDBC drivers registered with java.sql.DriverManager
(reasons are later in this email). I'm trying to use the Network Server
to make these embedded databases available to other processes for
inspection.
I've found that the Network Server doesn't work in such an environment
because NetworkServerControlImpl loads the embedded driver from
DriverManager in order to access the actual databases that it is
serving.
Would it be acceptable to introduce a plugin point to allow the Embedded
Driver to be loaded in some other fashion? I've attached a patch which
solves this problem for me but would like to know if this is consistent
with the direction of the project?
The reason we can't use DriverManager is that we're running a OSGi /
J2EE hybrid environment where access to databases (and hence the
drivers) are managed by a particular set of services. Having these
drivers registered with the DriverManager breaks the ability to re-start
and re-deploy these bundles cleanly as it can result in hanging
references to the drivers. Because of this the database management
service explicitly clears all Drivers registered with the DriverManager.
There is an OSGi Service which provides equivalent methods, but the
static access provided by DriverManager is unavailable in this
environment.
Thanks in Advance
Ed
--
________________________________________________________________________
Ed Costello Design
Engineer
[email protected]
P: +64 9 638 0600 Ext
3232
F: +64 9 638 0699
www.orionhealth.com
This e-mail and any attachments are intended only for the person to whom
it is addressed and may contain privileged, proprietary, or other data
protected from disclosure under applicable law. If you are not the
addressee or the person responsible for delivering this to the addressee
you are hereby notified that reading, copying or distributing this
transmission is prohibited. If you have received this e-mail in error,
please telephone us immediately and remove all copies of it from your
system. Thank you for your co-operation.
>From 0729b639eb06a987c10e4e61ae565f5bd5e574ce Mon Sep 17 00:00:00 2001
From: Ed Costello <[email protected]>
Date: Wed, 18 May 2011 08:54:57 +1200
Subject: [PATCH] Abstract Driver Location behind Driver locator interface
---
.../org/apache/derby/impl/drda/DriverLocator.java | 34 ++++++++++++++++++++
.../impl/drda/DriverManagerDriverLocator.java | 28 ++++++++++++++++
.../derby/impl/drda/NetworkServerControlImpl.java | 24 +++++++++++++-
3 files changed, 84 insertions(+), 2 deletions(-)
create mode 100644 java/drda/org/apache/derby/impl/drda/DriverLocator.java
create mode 100644 java/drda/org/apache/derby/impl/drda/DriverManagerDriverLocator.java
diff --git a/java/drda/org/apache/derby/impl/drda/DriverLocator.java b/java/drda/org/apache/derby/impl/drda/DriverLocator.java
new file mode 100644
index 0000000..920eb67
--- /dev/null
+++ b/java/drda/org/apache/derby/impl/drda/DriverLocator.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) Orchestral Developments Ltd (2001 - 2011).
+ *
+ * This document is copyright. Except for the purpose of fair reviewing, no part
+ * of this publication may be reproduced or transmitted in any form or by any
+ * means, electronic or mechanical, including photocopying, recording, or any
+ * information storage and retrieval system, without permission in writing from
+ * the publisher. Infringers of copyright render themselves liable for
+ * prosecution.
+ */
+package org.apache.derby.impl.drda;
+
+import java.sql.Driver;
+import java.sql.SQLException;
+
+/**
+ * Plugin interface for lookup up JDBC Driver's by URL. This is used to decouple the Derby Network Server from the
+ * {@link java.sql.DriverManager} so that it can be used in scenarios where the embedded driver is not available from the driver manager.
+ */
+public interface DriverLocator {
+
+ /**
+ * Tries to find a driver that can interpret the supplied URL.
+ *
+ * @param url
+ * the URL of a database
+ * @return a Driver that can understand the given URL. null if no Driver
+ * understands the URL
+ * @throws SQLException
+ * if there is any kind of Database Access problem
+ * @see java.sql.DriverManager#getDriver(String)
+ */
+ Driver getDriver(String url) throws SQLException;
+}
diff --git a/java/drda/org/apache/derby/impl/drda/DriverManagerDriverLocator.java b/java/drda/org/apache/derby/impl/drda/DriverManagerDriverLocator.java
new file mode 100644
index 0000000..4b6d9a0
--- /dev/null
+++ b/java/drda/org/apache/derby/impl/drda/DriverManagerDriverLocator.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) Orchestral Developments Ltd (2001 - 2011).
+ *
+ * This document is copyright. Except for the purpose of fair reviewing, no part
+ * of this publication may be reproduced or transmitted in any form or by any
+ * means, electronic or mechanical, including photocopying, recording, or any
+ * information storage and retrieval system, without permission in writing from
+ * the publisher. Infringers of copyright render themselves liable for
+ * prosecution.
+ */
+package org.apache.derby.impl.drda;
+
+import java.sql.Driver;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+
+
+/**
+ * Default implementation of {@link DriverLocator} that simply delegates the call to {@link DriverManager}.
+ */
+class DriverManagerDriverLocator implements DriverLocator {
+
+ public Driver getDriver(String url) throws SQLException
+ {
+ return DriverManager.getDriver(url);
+ }
+
+}
diff --git a/java/drda/org/apache/derby/impl/drda/NetworkServerControlImpl.java b/java/drda/org/apache/derby/impl/drda/NetworkServerControlImpl.java
index 56fc3d6..3152ecd 100644
--- a/java/drda/org/apache/derby/impl/drda/NetworkServerControlImpl.java
+++ b/java/drda/org/apache/derby/impl/drda/NetworkServerControlImpl.java
@@ -207,6 +207,12 @@ public final class NetworkServerControlImpl {
7 // XAMGR
};
+
+ // The driver locator used to find the embedded driver to connect
+ // to the underlying derby databases. This can be changed to allow
+ // the embedded driver to be obtained from somewhere other than the
+ // DriverManager
+ private static DriverLocator driverLocator = new DriverManagerDriverLocator();
protected PrintWriter logWriter; // console
protected PrintWriter cloudscapeLogWriter; // derby.log
@@ -433,6 +439,20 @@ public final class NetworkServerControlImpl {
this.passwordArg = password;
}
+ /**
+ * Set the driver locator used to find the derby embedded driver to
+ * connect to the underlying databases. By default the derby embedded
+ * driver is obtained from {@link java.sql.DriverManager} so this only
+ * needs to be changed if the embedded driver is not registered
+ * with the DriverManager.
+ *
+ * @param driverLocator the driver locator to use; must must not be null
+ */
+ public static void setDriverLocator(DriverLocator driverLocator)
+ {
+ NetworkServerControlImpl.driverLocator = driverLocator;
+ }
+
private void init() throws Exception
{
@@ -997,7 +1017,7 @@ public final class NetworkServerControlImpl {
// start the server.
Class.forName(CLOUDSCAPE_DRIVER).newInstance();
- cloudscapeDriver = DriverManager.getDriver(Attribute.PROTOCOL);
+ cloudscapeDriver = driverLocator.getDriver(Attribute.PROTOCOL);
}
catch (Exception e) {
@@ -3761,7 +3781,7 @@ public final class NetworkServerControlImpl {
try {
//Note, we add database to the url so that we can allow additional
//url attributes
- Connection conn = DriverManager.getConnection(Attribute.PROTOCOL+database, p);
+ Connection conn = driverLocator.getDriver(Attribute.PROTOCOL).connect(Attribute.PROTOCOL+database, p);
// send warnings
SQLWarning warn = conn.getWarnings();
if (warn != null)
--
1.7.1