Skip to content

Conversation

@Aggarwal-Raghav
Copy link
Contributor

@Aggarwal-Raghav Aggarwal-Raghav commented Nov 21, 2025

What changes were proposed in this pull request?

HIVE-29258

Why are the changes needed?

This PR removes explicit Class.forName calls, leveraging the JDBC 4.0+ Service Provider Interface (SPI) for automatic driver discovery. The DriverManager now utilizes ServiceLoader to locate drivers defined in META-INF/services and registers them dynamically.

Does this PR introduce any user-facing change?

NO

How was this patch tested?

Ran the affected files UT locally and will see CI outcome.

Copy link
Contributor

@okumin okumin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can amend some points, following SonarQube.

I wonder if we can remove some more. Probably, the answer is no.

% git grep 'Class.forName' | grep Driver
beeline/src/java/org/apache/hive/beeline/BeeLine.java:        Driver driver = (Driver) Class.forName(clazzName, true,
beeline/src/java/org/apache/hive/beeline/Commands.java:        Driver driver = (Driver) Class.forName(name).newInstance();
beeline/src/java/org/apache/hive/beeline/DatabaseConnection.java:            (Driver) Class.forName(clazzName, true, Thread.currentThread().getContextClassLoader())
jdbc-handler/src/main/java/org/apache/hive/storage/jdbc/JdbcStorageHandler.java:      classesToLoad.add(Class.forName("com.mysql.jdbc.Driver"));
jdbc-handler/src/main/java/org/apache/hive/storage/jdbc/JdbcStorageHandler.java:      classesToLoad.add(Class.forName("org.postgresql.Driver"));
jdbc-handler/src/main/java/org/apache/hive/storage/jdbc/JdbcStorageHandler.java:      classesToLoad.add(Class.forName("oracle.jdbc.OracleDriver"));
jdbc-handler/src/main/java/org/apache/hive/storage/jdbc/JdbcStorageHandler.java:      classesToLoad.add(Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver"));
jdbc-handler/src/main/java/org/apache/hive/storage/jdbc/JdbcStorageHandler.java:      classesToLoad.add(Class.forName("com.ibm.db2.jcc.DB2Driver"));
ql/src/java/org/apache/hadoop/hive/ql/DriverFactory.java:          Class<?> cls = Class.forName(name);
ql/src/test/org/apache/hadoop/hive/ql/TestDriverFactory.java:          Class<?> cls = Class.forName(name);

If we can reduce the usage, is it possible to remove CONNECTION_DRIVER in HiveConf and MetastoreConf?

public void setUpBefore() throws Exception {
if (miniHS2 == null) {
Class.forName(MiniHS2.getJdbcDriverName());

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change

An extra line has been added to some files and not been added to some files. I prefer to have no extra lines consistently

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed.

}
try {
LOG.info("Going to load JDBC driver {}", driverName);
driver = (Driver) Class.forName(driverName).newInstance();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This might change the behavior of L67 because this.driver is never assigned now

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed driver , connString as class attributes. Made connString local to method getConnection()

@Aggarwal-Raghav
Copy link
Contributor Author

We can amend some points, following SonarQube.

I wonder if we can remove some more. Probably, the answer is no.

% git grep 'Class.forName' | grep Driver
beeline/src/java/org/apache/hive/beeline/BeeLine.java:        Driver driver = (Driver) Class.forName(clazzName, true,
beeline/src/java/org/apache/hive/beeline/Commands.java:        Driver driver = (Driver) Class.forName(name).newInstance();
beeline/src/java/org/apache/hive/beeline/DatabaseConnection.java:            (Driver) Class.forName(clazzName, true, Thread.currentThread().getContextClassLoader())
jdbc-handler/src/main/java/org/apache/hive/storage/jdbc/JdbcStorageHandler.java:      classesToLoad.add(Class.forName("com.mysql.jdbc.Driver"));
jdbc-handler/src/main/java/org/apache/hive/storage/jdbc/JdbcStorageHandler.java:      classesToLoad.add(Class.forName("org.postgresql.Driver"));
jdbc-handler/src/main/java/org/apache/hive/storage/jdbc/JdbcStorageHandler.java:      classesToLoad.add(Class.forName("oracle.jdbc.OracleDriver"));
jdbc-handler/src/main/java/org/apache/hive/storage/jdbc/JdbcStorageHandler.java:      classesToLoad.add(Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver"));
jdbc-handler/src/main/java/org/apache/hive/storage/jdbc/JdbcStorageHandler.java:      classesToLoad.add(Class.forName("com.ibm.db2.jcc.DB2Driver"));
ql/src/java/org/apache/hadoop/hive/ql/DriverFactory.java:          Class<?> cls = Class.forName(name);
ql/src/test/org/apache/hadoop/hive/ql/TestDriverFactory.java:          Class<?> cls = Class.forName(name);

If we can reduce the usage, is it possible to remove CONNECTION_DRIVER in HiveConf and MetastoreConf?

Have removed reflection code changes from BeeLine.java, Commands.java, DatabaseConnection.java. Please review it. Changes in JdbcStorageHandler.java, DriverFactory.java are not specific to DriverManager and are outside the scope of PR IMO.

Copy link
Contributor

@okumin okumin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm feeling now MetastoreConf.ConfVars.CONNECTION_DRIVER is used only for logging purposes, and keeping it might cause a confusion; what if CONNECTION_DRIVER is for Postgres but the connection URL is for MySQL?
I wonder if we can remote it and HiveConf.ConfVars.METASTORE_CONNECTION_DRIVER in this pull request, or if it's impossible, or if we should separatre a pull request


public DatabaseConnection(BeeLine beeLine, String driver, String url,
Properties info) throws SQLException {
public DatabaseConnection(BeeLine beeLine, String url, Properties info) throws SQLException {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Aggarwal-Raghav
Copy link
Contributor Author

I'm feeling now MetastoreConf.ConfVars.CONNECTION_DRIVER is used only for logging purposes, and keeping it might cause a confusion; what if CONNECTION_DRIVER is for Postgres but the connection URL is for MySQL? I wonder if we can remote it and HiveConf.ConfVars.METASTORE_CONNECTION_DRIVER in this pull request, or if it's impossible, or if we should separatre a pull request

@okumin , thanks for the thorough review. What you mentioned is correct but I'm not sure, it will be that easy to remove CONNECTION_DRIVER config from HiveConf

HiveConf => Used, despite being Deprecated


MetaStoreConf=> Used in QTests (possible + achievable but requires cleanup from lot of places which is outside scope of this PR)

I'm hoping we can target this in separate JIRA. I have filed JIRA HIVE-29289 sometime back . Maybe as part of that cleanup as a follow-up I can try this.
Also, the recent sonarcloud was there before my changes as well and I was hoping it can be ignored if no changes in this PR are required. Running CI again doesn't seems ok to me. Let me know your thoughts on this part.

} else {
beeLine.output(beeLine.getColorBuffer().red(msg.getMono()));
}
} catch (Throwable t) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is the catch (Throwable t) still required?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have mixed opinion on this.
As jdbcCompliant(), getMajorVersion(), getMinorVersion() don't have checked exception but there is a possibility that a faulty/3rd party driver in classpath can through Exception at runtime. Hence, I was inclined to keep it. Let me know if you think otherwise.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think jdbcCompliant(), getMajorVersion(), getMinorVersion() these APIs throw any RuntimeExceptions from driver. Anyway its not a major issue, you can take a call.


public DatabaseConnection(BeeLine beeLine, String driver, String url,
Properties info) throws SQLException {
public DatabaseConnection(BeeLine beeLine, String url, Properties info) throws SQLException {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From the DatabaseConnection constructor code it won't throw any exception so throws SQLException can be removed.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is what sonaType also flagged. will fix this.

e);
}
connString = MetastoreConf.getVar(conf, MetastoreConf.ConfVars.CONNECT_URL_KEY);
String driverName = MetastoreConf.getVar(conf, MetastoreConf.ConfVars.CONNECTION_DRIVER);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here we are reading the drivername from config and not using it. If not configured throwing exception for the config which we are not using, I feel this is not correct.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure. will remove driverName from here.

if (connStr != null) {
String[] c = connStr.split(";");
if (c.length >= 1) {
driver = c[0];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if driver name is not expected in the connStr then connStr.split(";"); need to be adjusted accordingly.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

connStr is coming a method argument and I'm not changing the logic of how the connStr is passed by caller i.e.
connStr = driver_class_name;jdbc_url;user;password will remain same. So, there is no need to update connStr.split(";")

@sonarqubecloud
Copy link

Copy link
Contributor

@okumin okumin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants