[fix](JdbcExecutor) fix that JdbcExecutor did not load the class jar (#14598)

JdbcExecutor did not load jdbc driver jar, so add classloader to load jdbc jar.
This commit is contained in:
Tiewei Fang
2022-11-26 23:53:05 +08:00
committed by GitHub
parent a877c8e50d
commit 36419fae48
4 changed files with 30 additions and 10 deletions

View File

@ -122,6 +122,7 @@ Status JdbcConnector::open(RuntimeState* state, bool read) {
ctor_params.__set_jdbc_user(_conn_param.user);
ctor_params.__set_jdbc_password(_conn_param.passwd);
ctor_params.__set_jdbc_driver_class(_conn_param.driver_class);
ctor_params.__set_driver_path(local_location);
ctor_params.__set_batch_size(read ? state->batch_size() : 0);
ctor_params.__set_op(read ? TJdbcOperation::READ : TJdbcOperation::WRITE);

View File

@ -29,9 +29,10 @@ import org.apache.thrift.TDeserializer;
import org.apache.thrift.TException;
import org.apache.thrift.protocol.TBinaryProtocol;
import java.io.FileNotFoundException;
import java.net.MalformedURLException;
import java.sql.Connection;
import java.sql.Date;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
@ -61,8 +62,8 @@ public class JdbcExecutor {
} catch (TException e) {
throw new InternalException(e.getMessage());
}
init(request.statement, request.batch_size, request.jdbc_driver_class, request.jdbc_url, request.jdbc_user,
request.jdbc_password, request.op);
init(request.driver_path, request.statement, request.batch_size, request.jdbc_driver_class,
request.jdbc_url, request.jdbc_user, request.jdbc_password, request.op);
}
public void close() throws Exception {
@ -198,9 +199,13 @@ public class JdbcExecutor {
return time;
}
private void init(String sql, int batchSize, String driverClass, String jdbcUrl, String jdbcUser,
private void init(String driverUrl, String sql, int batchSize, String driverClass, String jdbcUrl, String jdbcUser,
String jdbcPassword, TJdbcOperation op) throws UdfRuntimeException {
try {
ClassLoader parent = getClass().getClassLoader();
ClassLoader classLoader = UdfUtils.getClassLoader(driverUrl, parent);
Class.forName(driverClass, true, classLoader);
Thread.currentThread().setContextClassLoader(classLoader);
HikariConfig config = new HikariConfig();
config.setDriverClassName(driverClass);
config.setJdbcUrl(jdbcUrl);
@ -210,7 +215,6 @@ public class JdbcExecutor {
dataSource = new HikariDataSource(config);
conn = dataSource.getConnection();
conn = DriverManager.getConnection(jdbcUrl, jdbcUser, jdbcPassword);
if (op == TJdbcOperation.READ) {
Preconditions.checkArgument(sql != null);
stmt = conn.prepareStatement(sql, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
@ -218,6 +222,12 @@ public class JdbcExecutor {
} else {
stmt = conn.createStatement();
}
} catch (FileNotFoundException e) {
throw new UdfRuntimeException("Can not find driver file: " + driverUrl, e);
} catch (MalformedURLException e) {
throw new UdfRuntimeException("MalformedURLException to load class about " + driverUrl, e);
} catch (ClassNotFoundException e) {
throw new UdfRuntimeException("Loading JDBC class error ClassNotFoundException about " + driverClass, e);
} catch (SQLException e) {
throw new UdfRuntimeException("Initialize datasource failed: ", e);
}

View File

@ -33,6 +33,7 @@ import org.apache.log4j.Logger;
import sun.misc.Unsafe;
import java.io.File;
import java.io.FileNotFoundException;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.math.BigInteger;
@ -213,8 +214,13 @@ public class UdfUtils {
}
}
public static URLClassLoader getClassLoader(String jarPath, ClassLoader parent) throws MalformedURLException {
URL url = new File(jarPath).toURI().toURL();
public static URLClassLoader getClassLoader(String jarPath, ClassLoader parent)
throws MalformedURLException, FileNotFoundException {
File file = new File(jarPath);
if (!file.exists()) {
throw new FileNotFoundException("Can not find local file: " + jarPath);
}
URL url = file.toURI().toURL();
return URLClassLoader.newInstance(new URL[] {url}, parent);
}

View File

@ -368,18 +368,21 @@ struct TJdbcExecutorCtorParams {
// "jdbc:mysql://127.0.0.1:3307/test";
2: optional string jdbc_url
//root
// root
3: optional string jdbc_user
//password
// password
4: optional string jdbc_password
//"com.mysql.jdbc.Driver"
// "com.mysql.jdbc.Driver"
5: optional string jdbc_driver_class
6: optional i32 batch_size
7: optional TJdbcOperation op
// "/home/user/mysql-connector-java-5.1.47.jar"
8: optional string driver_path
}
struct TJavaUdfExecutorCtorParams {