Description:
When using the random load balancing strategy and starting with two servers which are both unavailable, I get an IndexOutOfBoundsException when removing a server from the whiteList in the following code:
Integer whiteListIndex = (Integer) whiteListMap
.get(hostPortSpec);
// exclude this host from being picked again
if (whiteListIndex != null) {
whiteList.remove(whiteListIndex.intValue());
}
It appears that this is happening because the whiteList entries are being culled (affecting the index locations), but the whiteListMap is not updated.
Stack trace:
java.lang.IndexOutOfBoundsException: Index: 1, Size: 1
at java.util.ArrayList.RangeCheck(ArrayList.java:546)
at java.util.ArrayList.remove(ArrayList.java:389)
at com.mysql.jdbc.RandomBalanceStrategy.pickConnection(RandomBalanceStrategy.java:85)
at com.mysql.jdbc.LoadBalancingConnectionProxy.pickNewConnection(LoadBalancingConnectionProxy.java:357)
at com.mysql.jdbc.LoadBalancingConnectionProxy.<init>(LoadBalancingConnectionProxy.java:183)
at com.mysql.jdbc.NonRegisteringDriver.connectLoadBalanced(NonRegisteringDriver.java:327)
at com.mysql.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:268)
at java.sql.DriverManager.getConnection(DriverManager.java:525)
at java.sql.DriverManager.getConnection(DriverManager.java:171)
How to repeat:
public static void main(String[] args) {
Map m = new HashMap();
Long l = (Long) m.get("test");
try {
Class.forName ("com.mysql.jdbc.Driver");
Connection conn = DriverManager.getConnection ( "jdbc:mysql:loadbalance://localhost:3310,localhost:3311/test", "root", null);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Suggested fix:
Maintain whiteListMap when hosts are deleted from whiteList.