This is an automated email from the ASF dual-hosted git repository.
pvillard pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/nifi.git
The following commit(s) were added to refs/heads/main by this push:
new c96c958a57 NIFI-15372: Ensure Driver is Deregistered when DBCP Service
is removed.
c96c958a57 is described below
commit c96c958a57c8b04587179f01fb8d2ae461117a15
Author: Bob Paulin <[email protected]>
AuthorDate: Thu Dec 18 18:15:08 2025 -0600
NIFI-15372: Ensure Driver is Deregistered when DBCP Service is removed.
Signed-off-by: Pierre Villard <[email protected]>
This closes #10670.
---
.../org/apache/nifi/dbcp/DBCPConnectionPool.java | 22 ++++++++++++++++++++--
.../java/org/apache/nifi/dbcp/DBCPServiceTest.java | 12 ++++++++++++
2 files changed, 32 insertions(+), 2 deletions(-)
diff --git
a/nifi-extension-bundles/nifi-standard-services/nifi-dbcp-service-bundle/nifi-dbcp-service/src/main/java/org/apache/nifi/dbcp/DBCPConnectionPool.java
b/nifi-extension-bundles/nifi-standard-services/nifi-dbcp-service-bundle/nifi-dbcp-service/src/main/java/org/apache/nifi/dbcp/DBCPConnectionPool.java
index ec967bd230..9241834986 100644
---
a/nifi-extension-bundles/nifi-standard-services/nifi-dbcp-service-bundle/nifi-dbcp-service/src/main/java/org/apache/nifi/dbcp/DBCPConnectionPool.java
+++
b/nifi-extension-bundles/nifi-standard-services/nifi-dbcp-service-bundle/nifi-dbcp-service/src/main/java/org/apache/nifi/dbcp/DBCPConnectionPool.java
@@ -34,6 +34,7 @@ import org.apache.nifi.annotation.behavior.Restriction;
import org.apache.nifi.annotation.behavior.SupportsSensitiveDynamicProperties;
import org.apache.nifi.annotation.documentation.CapabilityDescription;
import org.apache.nifi.annotation.documentation.Tags;
+import org.apache.nifi.annotation.lifecycle.OnRemoved;
import org.apache.nifi.components.PropertyDescriptor;
import org.apache.nifi.components.PropertyValue;
import org.apache.nifi.components.RequiredPermission;
@@ -103,6 +104,9 @@ public class DBCPConnectionPool extends
AbstractDBCPConnectionPool implements DB
*/
protected static final String SENSITIVE_PROPERTY_PREFIX = "SENSITIVE.";
+ // Hold an instance of the registered driver so we can properly
de-register it.
+ private volatile Driver registeredDriver;
+
private static final List<PropertyDescriptor> PROPERTY_DESCRIPTORS =
List.of(
DATABASE_URL,
DB_DRIVERNAME,
@@ -261,9 +265,13 @@ public class DBCPConnectionPool extends
AbstractDBCPConnectionPool implements DB
return DriverManager.getDriver(url);
} catch (final SQLException e) {
// In case the driver is not registered by the implementation, we
explicitly try to register it.
+ // deregister existing driver
try {
- final Driver driver = (Driver)
clazz.getDeclaredConstructor().newInstance();
- DriverManager.registerDriver(driver);
+ if (registeredDriver != null) {
+ DriverManager.deregisterDriver(registeredDriver);
+ }
+ registeredDriver = (Driver)
clazz.getDeclaredConstructor().newInstance();
+ DriverManager.registerDriver(registeredDriver);
return DriverManager.getDriver(url);
} catch (final SQLException e2) {
throw new ProcessException("No suitable driver for the given
Database Connection URL", e2);
@@ -272,4 +280,14 @@ public class DBCPConnectionPool extends
AbstractDBCPConnectionPool implements DB
}
}
}
+
+ @OnRemoved
+ public void onRemove() {
+ try {
+ // We need to deregister the driver to allow the
InstanceClassLoader to be garbage collected.
+ DriverManager.deregisterDriver(registeredDriver);
+ } catch (SQLException e) {
+ getLogger().warn("Driver could not be deregistered. This may cause
a memory leak.", e);
+ }
+ }
}
diff --git
a/nifi-extension-bundles/nifi-standard-services/nifi-dbcp-service-bundle/nifi-dbcp-service/src/test/java/org/apache/nifi/dbcp/DBCPServiceTest.java
b/nifi-extension-bundles/nifi-standard-services/nifi-dbcp-service-bundle/nifi-dbcp-service/src/test/java/org/apache/nifi/dbcp/DBCPServiceTest.java
index 3c6e976ea3..2250adbdb7 100644
---
a/nifi-extension-bundles/nifi-standard-services/nifi-dbcp-service-bundle/nifi-dbcp-service/src/test/java/org/apache/nifi/dbcp/DBCPServiceTest.java
+++
b/nifi-extension-bundles/nifi-standard-services/nifi-dbcp-service-bundle/nifi-dbcp-service/src/test/java/org/apache/nifi/dbcp/DBCPServiceTest.java
@@ -27,6 +27,7 @@ import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Collection;
+import java.util.Collections;
import java.util.Map;
import java.util.UUID;
import org.apache.nifi.components.ConfigVerificationResult;
@@ -177,6 +178,17 @@ public class DBCPServiceTest {
}
}
+ @Test
+ public void testDeregisterDriver() throws SQLException {
+ runner.enableControllerService(service);
+ runner.assertValid(service);
+ final int serviceRunningNumberOfDrivers =
Collections.list(DriverManager.getDrivers()).size();
+ runner.disableControllerService(service);
+ runner.removeControllerService(service);
+ final int expectedDriversAfterRemove = serviceRunningNumberOfDrivers -
1;
+ assertEquals(expectedDriversAfterRemove,
Collections.list(DriverManager.getDrivers()).size(), "Driver should be
deregistered on remove");
+ }
+
@Test
public void testGetConnectionMaxTotalConnectionsExceeded() {
runner.setProperty(service, DBCPProperties.MAX_TOTAL_CONNECTIONS, "1");