Skip to content

Commit

Permalink
[FLINK-19435][connectors/jdbc] Fix deadlock when loading different sq…
Browse files Browse the repository at this point in the history
…l driver classes concurrently using Class.forName

This closes #14361
  • Loading branch information
kezhuw authored and wuchong committed Dec 21, 2020
1 parent 7ca2dd3 commit 84ed653
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,12 @@ public void configure(Configuration parameters) {
public void openInputFormat() {
//called once per inputFormat (on open)
try {
// Load DriverManager first to avoid deadlock between DriverManager's
// static initialization block and specific driver class's static
// initialization block.
//
// See comments in SimpleJdbcConnectionProvider for more details.
DriverManager.getDrivers();
Class.forName(drivername);
if (username == null) {
dbConn = DriverManager.getConnection(dbURL);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,18 @@ public class SimpleJdbcConnectionProvider implements JdbcConnectionProvider, Ser

private transient volatile Connection connection;

static {
// Load DriverManager first to avoid deadlock between DriverManager's
// static initialization block and specific driver class's static
// initialization block when two different driver classes are loading
// concurrently using Class.forName while DriverManager is uninitialized
// before.
//
// This could happen in JDK 8 but not above as driver loading has been
// moved out of DriverManager's static initialization block since JDK 9.
DriverManager.getDrivers();
}

public SimpleJdbcConnectionProvider(JdbcConnectionOptions jdbcOptions) {
this.jdbcOptions = jdbcOptions;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,12 @@ private Row convertToRowFromResultSet(ResultSet resultSet) throws SQLException {
}

private void establishConnectionAndStatement() throws SQLException, ClassNotFoundException {
// Load DriverManager first to avoid deadlock between DriverManager's
// static initialization block and specific driver class's static
// initialization block.
//
// See comments in SimpleJdbcConnectionProvider for more details.
DriverManager.getDrivers();
Class.forName(drivername);
if (username == null) {
dbConn = DriverManager.getConnection(dbURL);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,12 @@ public void eval(Object... keys) {
}

private void establishConnectionAndStatement() throws SQLException, ClassNotFoundException {
// Load DriverManager first to avoid deadlock between DriverManager's
// static initialization block and specific driver class's static
// initialization block.
//
// See comments in SimpleJdbcConnectionProvider for more details.
DriverManager.getDrivers();
Class.forName(drivername);
if (username == null) {
dbConn = DriverManager.getConnection(dbURL);
Expand Down

0 comments on commit 84ed653

Please sign in to comment.