大数据平台底层技术 - JAVA - 如何动态加载不同版本的 HIVE JDBC 驱动程序 - 一文读懂 JAVA 类加载机制 2
最编程
2024-03-09 10:29:22
...
package com.hundsun;
import org.apache.hadoop.conf.Configuration;
import org.apache.hive.jdbc.HiveDriver;
import java.io.File;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLClassLoader;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
/**
* @author: liming
* @date: 2021/8/28 20:12
* @description:
*/
public class ClassLoaderTest {
private static String dataSourceDriverPath;
private static String classPath = "E:\\git\\sparkTest\\target";
public static void main(String[] args) {
try {
// dataSourceDriverPath = args[0];
dataSourceDriverPath = "D:\\software\\数据源驱动-202101.03.000\\drivers\\hive-cdh6\\lib";
// System.out.println("驱动路径:" + dataSourceDriverPath);
System.out.println("ClassLoaderTest.class.getClassLoader():" + ClassLoaderTest.class.getClassLoader().toString());
// System.out.println("ClassLoaderTest.class.getClassLoader().getParent():" + ClassLoaderTest.class.getClassLoader().getParent().toString());
// System.out.println("ClassLoaderTest.class.getClassLoader().getParent().getParent():" + ClassLoaderTest.class.getClassLoader().getParent().getParent());
// System.out.println("ClassLoaderTest.class.getClassLoader().getParent().getParent().getParent():" + ClassLoaderTest.class.getClassLoader().getParent().getParent().getParent());
jdbcDriverTest();
getDriverUsingContextClassLoader();
getDriverUsingUrlClassLoader();
getClassUsingContextClassLoader(classPath);
} catch (Exception e) {
System.out.println(e.getMessage());
System.out.println(e.getCause());
e.printStackTrace();
}
}
public static void jdbcDriverTest(){
try{
Class<?> driverManagerClass = Class.forName("java.sql.DriverManager");
Class<?> driverClass = Class.forName("java.sql.Driver");
Class<?> oracleDriverClass = Class.forName("oracle.jdbc.driver.OracleDriver");
System.out.println("driverManagerClass.getClassLoader():" + driverManagerClass.getClassLoader());
System.out.println("driverClass.getClassLoader():" + driverClass.getClassLoader());
System.out.println("oracleDriverClass.getClassLoader():" + oracleDriverClass.getClassLoader());
// Connection con=DriverManager.getConnection("jdbc:oracle:thin:@//10.20.29.239:1521/orclpdb1","hs_cic","hundsun");
Connection con= DriverManager.getConnection(
"jdbc:oracle:thin:@//10.20.23.215:1521/orcl","hs_dap","hundsun");
System.out.println(con.getAutoCommit());
con.setAutoCommit(false);
System.out.println(con.getAutoCommit());
Statement stmt=con.createStatement();
ResultSet rs=stmt.executeQuery("select count(1) from HS_DAP.DAP_DATA_TYPE_LIMING");
while (rs.next()) {
System.out.println(rs.getInt(1));
// System.out.println(rs.getString(1) + " " + rs.getInt(2) + " " + rs.getString(3));
}
PreparedStatement ps = con.prepareStatement("delete from HS_DAP.DAP_DATA_TYPE_LIMING where HIVE_DATA_TYPE = ?");
ps.setString(1,"DATE");
ps.execute();
Thread.sleep(1 * 60 * 1000);
con.close();
}catch(Exception e){ System.out.println(e);}
}
public static Driver getDriverUsingUrlClassLoader() throws URISyntaxException {
String driverPath = dataSourceDriverPath;
List<File> files = scanDir(driverPath);
System.out.println(files.get(0).toURI());
Class<?> driver = null;
Class<?> configuration = null;
try {
URL[] urls = new URL[files.size()];
for (int i = 0; i < files.size(); i++) {
urls[i] = files.get(i).toURI().toURL();
// System.out.println(files.get(i).toURI());
}
System.out.println("Thread.currentThread().getContextClassLoader():" + Thread.currentThread().getContextClassLoader());
URLClassLoader urlClassLoader = new URLClassLoader(urls);
System.out.println("urlClassLoader:" + urlClassLoader);
URL resource = urlClassLoader.getResource("core-site-test.xml");
String resourceURI = resource.toURI().toString();
System.out.println("resourceURI:" + resourceURI);
System.out.println("resource.getPath():" + resource.getPath());
driver = urlClassLoader.loadClass("org.apache.hive.jdbc.HiveDriver");
System.out.println("org.apache.hive.jdbc.HiveDriver.class.getClassLoader():" + HiveDriver.class.getClassLoader().toString());
System.out.println("org.apache.hive.jdbc.HiveDriver.class.getClassLoader().getParent():" + HiveDriver.class.getClassLoader().getParent().toString());
configuration = urlClassLoader.loadClass("org.apache.hadoop.conf.Configuration");
System.out.println("org.apache.hadoop.conf.Configuration.class.getClassLoader():" + Configuration.class.getClassLoader().toString());
System.out.println("org.apache.hadoop.conf.Configuration.class.getClassLoader().getParent():" + Configuration.class.getClassLoader().getParent().toString());
System.out.println("Thread.currentThread().getContextClassLoader():" + Thread.currentThread().getContextClassLoader());
System.out.println("urlClassLoader.getParent():" + urlClassLoader.getParent());
Thread.currentThread().setContextClassLoader(urlClassLoader);
System.out.println("Thread.currentThread().getContextClassLoader()" + Thread.currentThread().getContextClassLoader());
return (Driver) driver.newInstance();
} catch (Exception e) {
System.out.println(e.getCause());
System.out.println(e.getMessage());
e.printStackTrace();
}
return null;
}
public static Driver getDriverUsingContextClassLoader() throws URISyntaxException {
String driverPath = dataSourceDriverPath;
List<File> files = scanDir(driverPath);
System.out.println(files.get(0).toURI());
Class<?> driver = null;
Class<?> configuration = null;
try {
URL[] urls = new URL[files.size()];
for (int i = 0; i < files.size(); i++) {
urls[i] = files.get(i).toURI().toURL();
// System.out.println(files.get(i).toURI());
}
ClassLoader prevContextClassLoader = Thread.currentThread().getContextClassLoader();
System.out.println("prevContextClassLoader:" + prevContextClassLoader);
// create a URLClassLoader with the thread ContextClassLoader as parent
URLClassLoader urlContextClassLoader = new URLClassLoader(urls, prevContextClassLoader);
System.out.println("urlContextClassLoader:" + urlContextClassLoader);
URL resource = urlContextClassLoader.getResource("core-site-test.xml");
String resourceURI = resource.toURI().toString();
// System.out.println("g:" +resourceURI);
System.out.println("resource.getPath():" + resource.getPath());
driver = urlContextClassLoader.loadClass("org.apache.hive.jdbc.HiveDriver");
System.out.println("org.apache.hive.jdbc.HiveDriver.class.getClassLoader():" + org.apache.hive.jdbc.HiveDriver.class.getClassLoader().toString());
System.out.println("org.apache.hive.jdbc.HiveDriver.class.getClassLoader().getParent():" + org.apache.hive.jdbc.HiveDriver.class.getClassLoader().getParent().toString());
configuration = urlContextClassLoader.loadClass("org.apache.hadoop.conf.Configuration");
System.out.println("Thread.currentThread().getContextClassLoader():" + Thread.currentThread().getContextClassLoader());
System.out.println("org.apache.hadoop.conf.Configuration.class.getClassLoader():" + org.apache.hadoop.conf.Configuration.class.getClassLoader().toString());
System.out.println("org.apache.hadoop.conf.Configuration.class.getClassLoader().getParent():" + org.apache.hadoop.conf.Configuration.class.getClassLoader().getParent().toString());
System.out.println("urlContextClassLoader.getParent():" + urlContextClassLoader.getParent());
// set the thread contextClassLoader to the newly created urlContextClassLoader
Thread.currentThread().setContextClassLoader(urlContextClassLoader);
System.out.println("Thread.currentThread().getContextClassLoader()" + Thread.currentThread().getContextClassLoader());
return (Driver) driver.newInstance();
} catch (Exception e) {
System.out.println(e.getCause());
System.out.println(e.getMessage());
e.printStackTrace();
}
return null;
}
public static void getClassUsingContextClassLoader(String classPath) throws URISyntaxException {
List<File> files = scanDir(classPath);
System.out.println(files.get(0).toURI());
try {
URL[] urls = new URL[files.size()];
for (int i = 0; i < files.size(); i++) {
urls[i] = files.get(i).toURI().toURL();
// System.out.println(files.get(i).toURI());
}
ClassLoader prevContextClassLoader = Thread.currentThread().getContextClassLoader();
System.out.println("prevContextClassLoader:" + prevContextClassLoader);
System.out.println("prevContextClassLoader.getParent():" + prevContextClassLoader.getParent());
System.out.println("prevContextClassLoader.getParent().getParent():" + prevContextClassLoader.getParent().getParent());
URLClassLoader urlContextClassLoader = new URLClassLoader(urls, prevContextClassLoader);
System.out.println("urlContextClassLoader:" + urlContextClassLoader);
System.out.println("ClassLoader.getSystemClassLoader():" + ClassLoader.getSystemClassLoader());
Thread.currentThread().setContextClassLoader(urlContextClassLoader);
System.out.println("Thread.currentThread().getContextClassLoader()" + Thread.currentThread().getContextClassLoader());
System.out.println("Thread.currentThread().getContextClassLoader().getParent()" + Thread.currentThread().getContextClassLoader().getParent());
System.out.println("ClassLoader.getSystemClassLoader():" + ClassLoader.getSystemClassLoader());
// if you call Class.forName() without specifying the classloader, it will use the system classloader by default;
// Class<?> claz1 = Class.forName("com.hundsun.SimpleApp");
// Class<?> claz1 = Class.forName("com.hundsun.SimpleApp",true,urlContextClassLoader);
// if you call Class.forName() with the same class and same classloader multiple times,
// the class will be loaded and initialized only once
// Class.forName("com.hundsun.SimpleApp",true,urlContextClassLoader);
// Class.forName("com.hundsun.SimpleApp",true,urlContextClassLoader);
// ClassLoader.loadClass will only load the class but will not initialize it - the static code block will not be executed;
Class claz1 = urlContextClassLoader.loadClass("com.hundsun.SimpleApp");
System.out.println("claz1.getClassLoader()" + claz1.getClassLoader());
} catch (Exception e) {
System.out.println(e.getCause());
System.out.println(e.getMessage());
e.printStackTrace();
}
}
/**
* 扫描lib下面的所有jar包
*
* @return
*/
private static List<File> scanDir(String path) {
List<File> list = new ArrayList<>();
File[] files = new File(path).listFiles();
for (File f : files) {
if (f.isFile() && f.getName().endsWith(".jar")) {
list.add(f);
}
if (f.listFiles() != null) {
for (File file : f.listFiles()) {
if (file.isFile() && file.getName().endsWith(".jar")) {
list.add(file);
}
}
}
}
return list;
}
}