You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nifi.apache.org by ma...@apache.org on 2015/05/20 18:42:25 UTC
[5/9] incubator-nifi git commit: JDBC driver can be loaded from
external location using URLClassLoader
JDBC driver can be loaded from external location using URLClassLoader
Signed-off-by: Toivo Adams <to...@gmail.com>
Signed-off-by: Mark Payne <ma...@hotmail.com>
Project: http://git-wip-us.apache.org/repos/asf/incubator-nifi/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-nifi/commit/1682d62d
Tree: http://git-wip-us.apache.org/repos/asf/incubator-nifi/tree/1682d62d
Diff: http://git-wip-us.apache.org/repos/asf/incubator-nifi/diff/1682d62d
Branch: refs/heads/develop
Commit: 1682d62d7f46ba854f77923352a77ff9f6a1b746
Parents: 864e099
Author: Toivo Adams <to...@gmail.com>
Authored: Sat Mar 14 12:34:40 2015 +0200
Committer: Mark Payne <ma...@hotmail.com>
Committed: Wed May 20 08:35:55 2015 -0400
----------------------------------------------------------------------
.../apache/nifi/dbcp/DBCPConnectionPool.java | 23 ++++--
.../java/org/apache/nifi/dbcp/DriverShim.java | 74 ++++++++++++++++++++
.../org/apache/nifi/dbcp/DBCPServiceTest.java | 35 +++++----
3 files changed, 113 insertions(+), 19 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/1682d62d/nifi/nifi-nar-bundles/nifi-standard-services/nifi-dbcp-service-bundle/nifi-dbcp-service/src/main/java/org/apache/nifi/dbcp/DBCPConnectionPool.java
----------------------------------------------------------------------
diff --git a/nifi/nifi-nar-bundles/nifi-standard-services/nifi-dbcp-service-bundle/nifi-dbcp-service/src/main/java/org/apache/nifi/dbcp/DBCPConnectionPool.java b/nifi/nifi-nar-bundles/nifi-standard-services/nifi-dbcp-service-bundle/nifi-dbcp-service/src/main/java/org/apache/nifi/dbcp/DBCPConnectionPool.java
index c2511c3..e2c0fea 100644
--- a/nifi/nifi-nar-bundles/nifi-standard-services/nifi-dbcp-service-bundle/nifi-dbcp-service/src/main/java/org/apache/nifi/dbcp/DBCPConnectionPool.java
+++ b/nifi/nifi-nar-bundles/nifi-standard-services/nifi-dbcp-service-bundle/nifi-dbcp-service/src/main/java/org/apache/nifi/dbcp/DBCPConnectionPool.java
@@ -20,6 +20,8 @@ import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.sql.Connection;
+import java.sql.Driver;
+import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collections;
@@ -184,7 +186,7 @@ public class DBCPConnectionPool extends AbstractControllerService implements DBC
// Optional driver URL, when exist, this URL will be used to locate driver jar file location
String urlString = context.getProperty(DB_DRIVER_JAR_URL).getValue();
- dataSource.setDriverClassLoader( getDriverClassLoader(urlString) );
+ dataSource.setDriverClassLoader( getDriverClassLoader(urlString, drv) );
String dburl = dbsystem.buildUrl(host, port, dbname);
@@ -210,14 +212,27 @@ public class DBCPConnectionPool extends AbstractControllerService implements DBC
* using Thread.currentThread().getContextClassLoader();
* will ensure that you are using the ClassLoader for you NAR.
* @throws InitializationException
- */
- protected ClassLoader getDriverClassLoader(String urlString) throws InitializationException {
+ */
+ protected ClassLoader getDriverClassLoader(String urlString, String drvName) throws InitializationException {
if (urlString!=null && urlString.length()>0) {
try {
URL[] urls = new URL[] { new URL(urlString) };
- return new URLClassLoader(urls);
+ URLClassLoader ucl = new URLClassLoader(urls);
+
+ // Workaround which allows to use URLClassLoader for JDBC driver loading.
+ // (Because the DriverManager will refuse to use a driver not loaded by the system ClassLoader.)
+ Class<?> clazz = Class.forName(drvName, true, ucl);
+ if (clazz==null)
+ throw new InitializationException("Can't load Database Driver " + drvName);
+ Driver driver = (Driver) clazz.newInstance();
+ DriverManager.registerDriver( new DriverShim(driver) );
+
+ return ucl;
+
} catch (MalformedURLException e) {
throw new InitializationException("Invalid Database Driver Jar Url", e);
+ } catch (Exception e) {
+ throw new InitializationException("Can't load Database Driver", e);
}
}
else
http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/1682d62d/nifi/nifi-nar-bundles/nifi-standard-services/nifi-dbcp-service-bundle/nifi-dbcp-service/src/main/java/org/apache/nifi/dbcp/DriverShim.java
----------------------------------------------------------------------
diff --git a/nifi/nifi-nar-bundles/nifi-standard-services/nifi-dbcp-service-bundle/nifi-dbcp-service/src/main/java/org/apache/nifi/dbcp/DriverShim.java b/nifi/nifi-nar-bundles/nifi-standard-services/nifi-dbcp-service-bundle/nifi-dbcp-service/src/main/java/org/apache/nifi/dbcp/DriverShim.java
new file mode 100644
index 0000000..8905d9d
--- /dev/null
+++ b/nifi/nifi-nar-bundles/nifi-standard-services/nifi-dbcp-service-bundle/nifi-dbcp-service/src/main/java/org/apache/nifi/dbcp/DriverShim.java
@@ -0,0 +1,74 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.dbcp;
+
+import java.sql.Connection;
+import java.sql.Driver;
+import java.sql.DriverPropertyInfo;
+import java.sql.SQLException;
+import java.sql.SQLFeatureNotSupportedException;
+import java.util.Properties;
+import java.util.logging.Logger;
+
+/**
+ * Workaround which allows to use URLClassLoader for JDBC driver loading.
+ * (Because the DriverManager will refuse to use a driver not loaded by the system ClassLoader.)
+ *
+ */
+class DriverShim implements Driver {
+ private Driver driver;
+
+ DriverShim(Driver d) {
+ this.driver = d;
+ }
+
+ @Override
+ public boolean acceptsURL(String u) throws SQLException {
+ return this.driver.acceptsURL(u);
+ }
+
+ @Override
+ public Connection connect(String u, Properties p) throws SQLException {
+ return this.driver.connect(u, p);
+ }
+
+ @Override
+ public int getMajorVersion() {
+ return this.driver.getMajorVersion();
+ }
+
+ @Override
+ public int getMinorVersion() {
+ return this.driver.getMinorVersion();
+ }
+
+ @Override
+ public DriverPropertyInfo[] getPropertyInfo(String u, Properties p) throws SQLException {
+ return this.driver.getPropertyInfo(u, p);
+ }
+
+ @Override
+ public boolean jdbcCompliant() {
+ return this.driver.jdbcCompliant();
+ }
+
+ @Override
+ public Logger getParentLogger() throws SQLFeatureNotSupportedException {
+ return driver.getParentLogger();
+ }
+
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/1682d62d/nifi/nifi-nar-bundles/nifi-standard-services/nifi-dbcp-service-bundle/nifi-dbcp-service/src/test/java/org/apache/nifi/dbcp/DBCPServiceTest.java
----------------------------------------------------------------------
diff --git a/nifi/nifi-nar-bundles/nifi-standard-services/nifi-dbcp-service-bundle/nifi-dbcp-service/src/test/java/org/apache/nifi/dbcp/DBCPServiceTest.java b/nifi/nifi-nar-bundles/nifi-standard-services/nifi-dbcp-service-bundle/nifi-dbcp-service/src/test/java/org/apache/nifi/dbcp/DBCPServiceTest.java
index 07d1398..cb9c208 100644
--- a/nifi/nifi-nar-bundles/nifi-standard-services/nifi-dbcp-service-bundle/nifi-dbcp-service/src/test/java/org/apache/nifi/dbcp/DBCPServiceTest.java
+++ b/nifi/nifi-nar-bundles/nifi-standard-services/nifi-dbcp-service-bundle/nifi-dbcp-service/src/test/java/org/apache/nifi/dbcp/DBCPServiceTest.java
@@ -51,7 +51,7 @@ public class DBCPServiceTest {
* Unknown database system.
*
*/
-// @Test
+ @Test
public void testUnknownDatabaseSystem() throws InitializationException {
final TestRunner runner = TestRunners.newTestRunner(TestProcessor.class);
final DBCPConnectionPool service = new DBCPConnectionPool();
@@ -64,7 +64,7 @@ public class DBCPServiceTest {
/**
* Missing property values.
*/
-// @Test
+ @Test
public void testMissingPropertyValues() throws InitializationException {
final TestRunner runner = TestRunners.newTestRunner(TestProcessor.class);
final DBCPConnectionPool service = new DBCPConnectionPool();
@@ -78,7 +78,7 @@ public class DBCPServiceTest {
* Connect, create table, insert, select, drop table.
*
*/
-// @Test
+ @Test
public void testCreateInsertSelect() throws InitializationException, SQLException {
final TestRunner runner = TestRunners.newTestRunner(TestProcessor.class);
final DBCPConnectionPool service = new DBCPConnectionPool();
@@ -120,7 +120,7 @@ public class DBCPServiceTest {
* Connect, create table, insert, select, drop table.
*
*/
-// @Test
+ @Test
public void testExternalJDBCDriverUsage() throws InitializationException, SQLException {
final TestRunner runner = TestRunners.newTestRunner(TestProcessor.class);
final DBCPConnectionPool service = new DBCPConnectionPool();
@@ -136,7 +136,7 @@ public class DBCPServiceTest {
runner.setProperty(service, DBCPConnectionPool.DB_DRIVER_JAR_URL, "file:///var/tmp/mariadb-java-client-1.1.7.jar");
- runner.setProperty(service, DBCPConnectionPool.DB_HOST, "127.0.0.1"); // localhost
+ runner.setProperty(service, DBCPConnectionPool.DB_HOST, "localhost"); // localhost
runner.setProperty(service, DBCPConnectionPool.DB_NAME, "testdb");
runner.setProperty(service, DBCPConnectionPool.DB_USER, "tester");
runner.setProperty(service, DBCPConnectionPool.DB_PASSWORD, "testerp");
@@ -163,7 +163,7 @@ public class DBCPServiceTest {
* Get many times, after a while pool should not contain any available connection
* and getConnection should fail.
*/
-// @Test
+ @Test
public void testExhaustPool() throws InitializationException, SQLException {
final TestRunner runner = TestRunners.newTestRunner(TestProcessor.class);
final DBCPConnectionPool service = new DBCPConnectionPool();
@@ -197,7 +197,7 @@ public class DBCPServiceTest {
* Get many times, release immediately
* and getConnection should not fail.
*/
-// @Test
+ @Test
public void testGetManyNormal() throws InitializationException, SQLException {
final TestRunner runner = TestRunners.newTestRunner(TestProcessor.class);
final DBCPConnectionPool service = new DBCPConnectionPool();
@@ -226,7 +226,7 @@ public class DBCPServiceTest {
}
-// @Test
+ @Test
public void testDriverLoad() throws ClassNotFoundException {
Class<?> clazz = Class.forName("org.apache.derby.jdbc.EmbeddedDriver");
assertNotNull(clazz);
@@ -244,29 +244,36 @@ public class DBCPServiceTest {
ClassLoader parent = Thread.currentThread().getContextClassLoader();
URLClassLoader ucl = new URLClassLoader(urls,parent);
+// URLClassLoader ucl = new URLClassLoader(urls);
Class<?> clazz = Class.forName("org.mariadb.jdbc.Driver", true, ucl);
assertNotNull(clazz);
Driver driver = (Driver) clazz.newInstance();
+ Driver shim = new DriverShim(driver);
+ DriverManager.registerDriver( shim );
// Driver is found when using URL ClassLoader
assertTrue( isDriverAllowed(driver, ucl) );
// Driver is not found when using parent ClassLoader
// unfortunately DriverManager will use caller ClassLoadar and driver is not found !!!
- assertTrue( isDriverAllowed(driver, parent) );
+// assertTrue( isDriverAllowed(driver, parent) );
-// DriverManager.registerDriver( (Driver) clazz.newInstance());
Enumeration<Driver> drivers = DriverManager.getDrivers();
while (drivers.hasMoreElements()) {
driver = (Driver) drivers.nextElement();
System.out.println(driver);
}
+
+ Driver driver2 = DriverManager.getDriver("jdbc:mariadb://localhost:3306/testdb");
+ assertNotNull(driver2);
+ Connection connection = DriverManager.getConnection("jdbc:mariadb://localhost:3306/testdb","tester","testerp");
+ assertNotNull(connection);
+ connection.close();
- // Driver driver = DriverManager.getDriver("jdbc:mariadb://127.0.0.1:3306/testdb");
- // assertNotNull(driver);
+ DriverManager.deregisterDriver(shim);
}
@@ -299,7 +306,7 @@ public class DBCPServiceTest {
}
//==================================== problem solving - no suitable driver found, mariadb =========================================
-
+ // method isDriverAllowed is from DriverManager
private static boolean isDriverAllowed(Driver driver, ClassLoader classLoader) {
boolean result = false;
if(driver != null) {
@@ -318,6 +325,4 @@ public class DBCPServiceTest {
}
-
-
}