This is an automated email from the ASF dual-hosted git repository.

ggregory pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-dbcp.git

commit dc2c59ac652e1923b2e7f163ebacc3c1315e5314
Author: Gary D. Gregory <garydgreg...@gmail.com>
AuthorDate: Mon May 26 11:36:35 2025 -0400

    Add 
org.apache.commons.dbcp2.datasources.PooledConnectionManager.setPassword(char[])
---
 src/changes/changes.xml                            |  1 +
 .../dbcp2/datasources/CPDSConnectionFactory.java   |  1 +
 .../dbcp2/datasources/InstanceKeyDataSource.java   |  2 +-
 .../datasources/KeyedCPDSConnectionFactory.java    |  8 +++
 .../dbcp2/datasources/PooledConnectionManager.java | 29 ++++-----
 .../datasources/PooledConnectionManagerTest.java   | 70 ++++++++++++++++++++++
 .../datasources/TestCPDSConnectionFactory.java     | 10 +++-
 7 files changed, 105 insertions(+), 16 deletions(-)

diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 4234a424..85a9cdf5 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -109,6 +109,7 @@ The <action> type attribute can be add,update,fix,remove.
       <action type="fix" dev="ggregory" due-to="Gary Gregory">Fix SpotBugs 
[ERROR] Medium: Shared primitive variable "poolStatements" in one thread may 
not yield the value of the most recent write from another thread 
[org.apache.commons.dbcp2.PoolableConnectionFactory] 
AT_STALE_THREAD_WRITE_OF_PRIMITIVE.</action>
       <action type="fix" dev="ggregory" due-to="Gary Gregory">Fix SpotBugs 
[ERROR] Medium: Shared primitive variable "rollbackOnReturn" in one thread may 
not yield the value of the most recent write from another thread 
[org.apache.commons.dbcp2.PoolableConnectionFactory] 
AT_STALE_THREAD_WRITE_OF_PRIMITIVE.</action>
       <!-- ADD -->
+      <action type="add" dev="ggregory" due-to="Gary Gregory">Add 
org.apache.commons.dbcp2.datasources.PooledConnectionManager.setPassword(char[]).</action>
       <!-- UPDATE -->
       <action type="update" dev="ggregory" due-to="Gary Gregory">Bump 
org.apache.commons:commons-parent from 78 to 81.</action>
       <action type="update" dev="ggregory" due-to="Gary Gregory">Bump 
org.apache.commons:commons-pool2 from 2.12.0 to 2.12.1 #474.</action>
diff --git 
a/src/main/java/org/apache/commons/dbcp2/datasources/CPDSConnectionFactory.java 
b/src/main/java/org/apache/commons/dbcp2/datasources/CPDSConnectionFactory.java
index eae72bc4..276e1546 100644
--- 
a/src/main/java/org/apache/commons/dbcp2/datasources/CPDSConnectionFactory.java
+++ 
b/src/main/java/org/apache/commons/dbcp2/datasources/CPDSConnectionFactory.java
@@ -228,6 +228,7 @@ final class CPDSConnectionFactory extends 
AbstractConnectionFactory
      * @param userPassword
      *            new password
      */
+    @Override
     public synchronized void setPassword(final char[] userPassword) {
         this.userPassKey = new UserPassKey(userPassKey.getUserName(), 
userPassword);
     }
diff --git 
a/src/main/java/org/apache/commons/dbcp2/datasources/InstanceKeyDataSource.java 
b/src/main/java/org/apache/commons/dbcp2/datasources/InstanceKeyDataSource.java
index d3bf08eb..73c6b814 100644
--- 
a/src/main/java/org/apache/commons/dbcp2/datasources/InstanceKeyDataSource.java
+++ 
b/src/main/java/org/apache/commons/dbcp2/datasources/InstanceKeyDataSource.java
@@ -271,7 +271,7 @@ public abstract class InstanceKeyDataSource implements 
DataSource, Referenceable
             // Destroy and remove from pool
             manager.invalidate(info.getPooledConnection());
             // Reset the password on the factory if using CPDSConnectionFactory
-            manager.setPassword(upkey.getPassword());
+            manager.setPassword(upkey.getPasswordCharArray());
             info = null;
             for (int i = 0; i < 10; i++) { // Bound the number of retries - 
only needed if bad instances return
                 try {
diff --git 
a/src/main/java/org/apache/commons/dbcp2/datasources/KeyedCPDSConnectionFactory.java
 
b/src/main/java/org/apache/commons/dbcp2/datasources/KeyedCPDSConnectionFactory.java
index 1f2e6373..9464aca2 100644
--- 
a/src/main/java/org/apache/commons/dbcp2/datasources/KeyedCPDSConnectionFactory.java
+++ 
b/src/main/java/org/apache/commons/dbcp2/datasources/KeyedCPDSConnectionFactory.java
@@ -212,6 +212,14 @@ final class KeyedCPDSConnectionFactory extends 
AbstractConnectionFactory
         validateLifetime(pooledObject);
     }
 
+    /**
+     * Does nothing. This factory does not cache user credentials.
+     */
+    @Override
+    public void setPassword(final char[] password) {
+        // Does nothing. This factory does not cache user credentials.
+    }
+
     /**
      * Does nothing. This factory does not cache user credentials.
      */
diff --git 
a/src/main/java/org/apache/commons/dbcp2/datasources/PooledConnectionManager.java
 
b/src/main/java/org/apache/commons/dbcp2/datasources/PooledConnectionManager.java
index 2dfde18f..b7f288cf 100644
--- 
a/src/main/java/org/apache/commons/dbcp2/datasources/PooledConnectionManager.java
+++ 
b/src/main/java/org/apache/commons/dbcp2/datasources/PooledConnectionManager.java
@@ -14,6 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.apache.commons.dbcp2.datasources;
 
 import java.sql.SQLException;
@@ -31,9 +32,9 @@ interface PooledConnectionManager {
      * Closes the connection pool associated with the given user.
      *
      * @param userName
-     *            user name
+     *            user name.
      * @throws SQLException
-     *             if an error occurs closing idle connections in the pool
+     *             if an error occurs closing idle connections in the pool.
      */
     void closePool(String userName) throws SQLException;
 
@@ -41,27 +42,27 @@ interface PooledConnectionManager {
      * Closes the PooledConnection and remove it from the connection pool to 
which it belongs, adjusting pool counters.
      *
      * @param pc
-     *            PooledConnection to be invalidated
+     *            PooledConnection to be invalidated.
      * @throws SQLException
-     *             if an SQL error occurs closing the connection
+     *             if an SQL error occurs closing the connection.
      */
     void invalidate(PooledConnection pc) throws SQLException;
 
-//    /**
-//     * Sets the database password used when creating connections.
-//     *
-//     * @param password password used when authenticating to the database
-//     * @since 2.10.0
-//     */
-//     default void setPassword(char[] password) {
-//         setPassword(String.copyValueOf(password));
-//     }
+    /**
+     * Sets the database password used when creating connections.
+     *
+     * @param password password used when authenticating to the database.
+     * @since 2.14.0
+     */
+     default void setPassword(final char[] password) {
+         setPassword(String.copyValueOf(password));
+     }
 
     /**
      * Sets the database password used when creating connections.
      *
      * @param password
-     *            password used when authenticating to the database
+     *            password used when authenticating to the database.
      */
     void setPassword(String password);
 
diff --git 
a/src/test/java/org/apache/commons/dbcp2/datasources/PooledConnectionManagerTest.java
 
b/src/test/java/org/apache/commons/dbcp2/datasources/PooledConnectionManagerTest.java
new file mode 100644
index 00000000..7353db99
--- /dev/null
+++ 
b/src/test/java/org/apache/commons/dbcp2/datasources/PooledConnectionManagerTest.java
@@ -0,0 +1,70 @@
+/*
+ * 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
+ *
+ *      https://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.commons.dbcp2.datasources;
+
+import static org.junit.jupiter.api.Assertions.assertArrayEquals;
+
+import java.sql.SQLException;
+
+import javax.sql.PooledConnection;
+
+import org.junit.jupiter.api.Test;
+
+/*
+ * Tests {@link PooledConnectionManager}.
+ */
+public class PooledConnectionManagerTest {
+
+    static class Fixture implements PooledConnectionManager {
+
+        private char[] password;
+
+        @Override
+        public void closePool(final String userName) throws SQLException {
+            // empty
+        }
+
+        char[] getPassword() {
+            return password;
+        }
+
+        @Override
+        public void invalidate(final PooledConnection pc) throws SQLException {
+            // empty
+        }
+
+        @Override
+        public void setPassword(final String password) {
+            this.password = password.toCharArray();
+        }
+    }
+
+    @Test
+    public void testSetPasswordCharArray() {
+        final Fixture fixture = new Fixture();
+        fixture.setPassword("p".toCharArray());
+        assertArrayEquals("p".toCharArray(), fixture.getPassword());
+    }
+
+    @Test
+    public void testSetPasswordString() {
+        final Fixture fixture = new Fixture();
+        fixture.setPassword("p");
+        assertArrayEquals("p".toCharArray(), fixture.getPassword());
+    }
+}
diff --git 
a/src/test/java/org/apache/commons/dbcp2/datasources/TestCPDSConnectionFactory.java
 
b/src/test/java/org/apache/commons/dbcp2/datasources/TestCPDSConnectionFactory.java
index 41642886..7183a48e 100644
--- 
a/src/test/java/org/apache/commons/dbcp2/datasources/TestCPDSConnectionFactory.java
+++ 
b/src/test/java/org/apache/commons/dbcp2/datasources/TestCPDSConnectionFactory.java
@@ -130,7 +130,7 @@ public class TestCPDSConnectionFactory {
     }
 
     @Test
-    public void testSetPasswordThenModCharArray() {
+    public void testSetPasswordCharArray() {
         final CPDSConnectionFactory factory = new CPDSConnectionFactory(cpds, 
null, Duration.ofMillis(-1), false, "userName", "password".toCharArray());
         final char[] pwd = { 'a' };
         factory.setPassword(pwd);
@@ -139,6 +139,14 @@ public class TestCPDSConnectionFactory {
         assertEquals("a", String.valueOf(factory.getPasswordCharArray()));
     }
 
+    @Test
+    public void testSetPasswordString() {
+        final CPDSConnectionFactory factory = new CPDSConnectionFactory(cpds, 
null, Duration.ofMillis(-1), false, "userName", "password".toCharArray());
+        final String pwd = "a";
+        factory.setPassword(pwd);
+        assertEquals("a", String.valueOf(factory.getPasswordCharArray()));
+    }
+
     /**
      * JIRA DBCP-216
      *

Reply via email to