提交 b903a314 authored 作者: Thomas Mueller's avatar Thomas Mueller

Connection pool / DataSource: a NullPointerException was thrown when using a…

Connection pool / DataSource: a NullPointerException was thrown when using a database URL that doesn't start with "jdbc:h2:".
上级 db4ce37e
...@@ -196,7 +196,7 @@ public class JdbcConnectionPool implements DataSource, ConnectionEventListener { ...@@ -196,7 +196,7 @@ public class JdbcConnectionPool implements DataSource, ConnectionEventListener {
*/ */
public Connection getConnection() throws SQLException { public Connection getConnection() throws SQLException {
long max = System.currentTimeMillis() + timeout * 1000; long max = System.currentTimeMillis() + timeout * 1000;
while (System.currentTimeMillis() <= max) { do {
synchronized (this) { synchronized (this) {
if (activeConnections < maxConnections) { if (activeConnections < maxConnections) {
return getConnectionNow(); return getConnectionNow();
...@@ -207,7 +207,7 @@ public class JdbcConnectionPool implements DataSource, ConnectionEventListener { ...@@ -207,7 +207,7 @@ public class JdbcConnectionPool implements DataSource, ConnectionEventListener {
// ignore // ignore
} }
} }
} } while (System.currentTimeMillis() <= max);
throw new SQLException("Login timeout", "08001", 8001); throw new SQLException("Login timeout", "08001", 8001);
} }
......
...@@ -177,7 +177,13 @@ implements XADataSource, DataSource, ConnectionPoolDataSource, Serializable, Ref ...@@ -177,7 +177,13 @@ implements XADataSource, DataSource, ConnectionPoolDataSource, Serializable, Ref
Properties info = new Properties(); Properties info = new Properties();
info.setProperty("user", user); info.setProperty("user", user);
info.put("password", password); info.put("password", password);
return (JdbcConnection) Driver.load().connect(url, info); Connection conn = Driver.load().connect(url, info);
if (conn == null) {
throw new SQLException("No suitable driver found for " + url, "08001", 8001);
} else if (!(conn instanceof JdbcConnection)) {
throw new SQLException("Unsupported connection type " + conn.getClass().getName(), "08001", 8001);
}
return (JdbcConnection) conn;
} }
/** /**
...@@ -308,7 +314,7 @@ implements XADataSource, DataSource, ConnectionPoolDataSource, Serializable, Ref ...@@ -308,7 +314,7 @@ implements XADataSource, DataSource, ConnectionPoolDataSource, Serializable, Ref
public XAConnection getXAConnection() throws SQLException { public XAConnection getXAConnection() throws SQLException {
debugCodeCall("getXAConnection"); debugCodeCall("getXAConnection");
int id = getNextId(XA_DATA_SOURCE); int id = getNextId(XA_DATA_SOURCE);
return new JdbcXAConnection(factory, id, url, userName, passwordChars); return new JdbcXAConnection(factory, id, getJdbcConnection(userName, StringUtils.cloneCharArray(passwordChars)));
} }
//## Java 1.4 end ## //## Java 1.4 end ##
...@@ -326,7 +332,7 @@ implements XADataSource, DataSource, ConnectionPoolDataSource, Serializable, Ref ...@@ -326,7 +332,7 @@ implements XADataSource, DataSource, ConnectionPoolDataSource, Serializable, Ref
debugCode("getXAConnection("+quote(user)+", \"\");"); debugCode("getXAConnection("+quote(user)+", \"\");");
} }
int id = getNextId(XA_DATA_SOURCE); int id = getNextId(XA_DATA_SOURCE);
return new JdbcXAConnection(factory, id, url, user, convertToCharArray(password)); return new JdbcXAConnection(factory, id, getJdbcConnection(user, convertToCharArray(password)));
} }
//## Java 1.4 end ## //## Java 1.4 end ##
......
...@@ -12,14 +12,12 @@ import java.sql.ResultSet; ...@@ -12,14 +12,12 @@ import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.sql.Statement; import java.sql.Statement;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Properties;
import javax.sql.ConnectionEvent; import javax.sql.ConnectionEvent;
import javax.sql.ConnectionEventListener; import javax.sql.ConnectionEventListener;
import javax.sql.XAConnection; import javax.sql.XAConnection;
import javax.transaction.xa.XAException; import javax.transaction.xa.XAException;
import javax.transaction.xa.XAResource; import javax.transaction.xa.XAResource;
import javax.transaction.xa.Xid; import javax.transaction.xa.Xid;
import org.h2.Driver;
import org.h2.constant.ErrorCode; import org.h2.constant.ErrorCode;
import org.h2.constant.SysProperties; import org.h2.constant.SysProperties;
import org.h2.jdbc.JdbcConnection; import org.h2.jdbc.JdbcConnection;
...@@ -51,7 +49,6 @@ implements XAConnection, XAResource ...@@ -51,7 +49,6 @@ implements XAConnection, XAResource
private static int nextTransactionId; private static int nextTransactionId;
private JdbcDataSourceFactory factory; private JdbcDataSourceFactory factory;
private String url, user;
// This connection is kept open as long as the XAConnection is alive // This connection is kept open as long as the XAConnection is alive
private JdbcConnection physicalConn; private JdbcConnection physicalConn;
...@@ -66,15 +63,10 @@ implements XAConnection, XAResource ...@@ -66,15 +63,10 @@ implements XAConnection, XAResource
org.h2.Driver.load(); org.h2.Driver.load();
} }
JdbcXAConnection(JdbcDataSourceFactory factory, int id, String url, String user, char[] password) throws SQLException { JdbcXAConnection(JdbcDataSourceFactory factory, int id, JdbcConnection physicalConn) throws SQLException {
this.factory = factory; this.factory = factory;
setTrace(factory.getTrace(), TraceObject.XA_DATA_SOURCE, id); setTrace(factory.getTrace(), TraceObject.XA_DATA_SOURCE, id);
this.url = url; this.physicalConn = physicalConn;
this.user = user;
Properties info = new Properties();
info.setProperty("user", user);
info.put("password", StringUtils.cloneCharArray(password));
physicalConn = (JdbcConnection) Driver.load().connect(url, info);
} }
//## Java 1.4 end ## //## Java 1.4 end ##
...@@ -422,7 +414,7 @@ implements XAConnection, XAResource ...@@ -422,7 +414,7 @@ implements XAConnection, XAResource
*/ */
//## Java 1.4 begin ## //## Java 1.4 begin ##
public String toString() { public String toString() {
return getTraceObjectName() + ": url=" + url + " user=" + user; return getTraceObjectName() + ": " + physicalConn;
} }
private XAException convertException(SQLException e) { private XAException convertException(SQLException e) {
......
...@@ -34,6 +34,7 @@ public class TestConnectionPool extends TestBase { ...@@ -34,6 +34,7 @@ public class TestConnectionPool extends TestBase {
public void test() throws Exception { public void test() throws Exception {
deleteDb("connectionPool"); deleteDb("connectionPool");
testWrongUrl();
testTimeout(); testTimeout();
testUncommittedTransaction(); testUncommittedTransaction();
testPerformance(); testPerformance();
...@@ -43,11 +44,22 @@ public class TestConnectionPool extends TestBase { ...@@ -43,11 +44,22 @@ public class TestConnectionPool extends TestBase {
deleteDb("connectionPool"); deleteDb("connectionPool");
} }
private void testWrongUrl() throws SQLException {
JdbcConnectionPool cp = JdbcConnectionPool.create("jdbc:wrong:url", "", "");
try {
cp.getConnection();
} catch (SQLException e) {
assertEquals(8001, e.getErrorCode());
}
cp.dispose();
}
private void testTimeout() throws Exception { private void testTimeout() throws Exception {
String url = getURL("connectionPool", true), user = getUser(), password = getPassword(); String url = getURL("connectionPool", true), user = getUser(), password = getPassword();
final JdbcConnectionPool man = JdbcConnectionPool.create(url, user, password); final JdbcConnectionPool man = JdbcConnectionPool.create(url, user, password);
man.setLoginTimeout(1); man.setLoginTimeout(1);
man.setMaxConnections(2); man.setMaxConnections(2);
// connection 1 (of 2)
Connection conn = man.getConnection(); Connection conn = man.getConnection();
Task t = new Task() { Task t = new Task() {
public void call() { public void call() {
...@@ -61,10 +73,13 @@ public class TestConnectionPool extends TestBase { ...@@ -61,10 +73,13 @@ public class TestConnectionPool extends TestBase {
t.execute(); t.execute();
long time = System.currentTimeMillis(); long time = System.currentTimeMillis();
try { try {
// connection 2 (of 1 or 2) may fail
man.getConnection(); man.getConnection();
// connection 3 (of 1 or 2) must fail
man.getConnection(); man.getConnection();
fail(); fail();
} catch (SQLException e) { } catch (SQLException e) {
assertTrue(e.toString().toLowerCase().indexOf("timeout") >= 0);
time = System.currentTimeMillis() - time; time = System.currentTimeMillis() - time;
assertTrue("timeout after " + time + " ms", time > 1000); assertTrue("timeout after " + time + " ms", time > 1000);
} finally { } finally {
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论