Caused by: java.sql.SQLException: No suitable driver found for jdbc:mysql://25.79.1.13:90/tide_cloud?connectTimeout=60000&socketTimeout=60000
at java.sql.DriverManager.getConnection(DriverManager.java:689) ~[?:1.8.0_332]
at java.sql.DriverManager.getConnection(DriverManager.java:247) ~[?:1.8.0_332]
at org.apache.flink.connector.jdbc.catalog.MySqlCatalog.getDriverVersion(MySqlCatalog.java:159) ~[?:?]
at org.apache.flink.connector.jdbc.catalog.MySqlCatalog.<init>(MySqlCatalog.java:93) ~[?:?]
at com.tide.util.TableAssembler.build(TableAssembler.java:63) ~[?:?]
at com.tide.Insight.prepare(Insight.java:112) ~[?:?]
at com.tide.Insight.execute(Insight.java:104) ~[?:?]
at com.tide.Insight.main(Insight.java:48) ~[?:?]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_332]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_332]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_332]
at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_332]
at org.apache.flink.client.program.PackagedProgram.callMainMethod(PackagedProgram.java:355) ~[flink-dist-1.17.1.jar:1.17.1]
... 7 more
public void invokeInteractiveModeForExecution() throws ProgramInvocationException {
FlinkSecurityManager.monitorUserSystemExitForCurrentThread();
try {
callMainMethod(mainClass, args);
} finally {
FlinkSecurityManager.unmonitorUserSystemExitForCurrentThread();
}
}
this.mainClass =
loadMainClass(
// if no entryPointClassName name was given, we try and look one up through
// the manifest
entryPointClassName != null
? entryPointClassName
: getEntryPointClassNameFromJar(this.jarFile),
userCodeClassLoader);
mainClass是 ChildFirstClassLoader載入的,因此java.sql.DriverManager.getConnection也是ChildFirstClassLoader載入的。
因此,
// log.info(java.sql.DriverManager.class.getClassLoader().toString());
log.info(Insight.class.getClassLoader().toString());
log.info(com.mysql.cj.jdbc.Driver.class.getClassLoader().toString());
輸出:
org.apache.flink.util.ChildFirstClassLoader@7d81f8b6
sun.misc.Launcher$AppClassLoader@12a3a380
ChildFirstClassLoader 是 Flink 自定義的類載入器,繼承自 Java 的 ClassLoader 類,但它的工作機制和 AppClassLoader 不同。
ChildFirstClassLoader 會將子類載入器的類優先載入,而 AppClassLoader 則是按照預設的父類優先載入機制工作。
這兩者之間並沒有直接的繼承關係或父子關係,而是獨立存在的,用於不同的目的和場景。
去掉classloader.parent-first-patterns.additional: com.mysql.; org.codehaus.
配置之後,
列印:
org.apache.flink.util.ChildFirstClassLoader@69cebb68
org.apache.flink.util.ChildFirstClassLoader@69cebb68
這時候抱錯了,提示No suitable driver found for jdbc
,猜測原因:
- java.sql.DriverManager是由Boostrap類載入器載入的
- com.mysql.cj.jdbc.Driver 是由ChildFirstClassLoader類載入器載入的。
https://juejin.cn/post/7249934982114672695
知識點
1、任意一個類,都需要由載入它的類載入器和這個類本身一同確立其在Java虛擬機器中的唯一性,每一個類載入器,都擁有一個獨立的類名稱空間。這句話可以表達更通俗一些:比較兩個類是否”相等”,只有再這兩個類是有同一個類載入器載入的前提下才有意義,否則,即使這兩個類來源於同一個Class 檔案,被同一個虛擬機器載入,只要載入它們的類載入器不同,那這兩個類就必定不相等。
2、類載入器本身不存在繼承關係。 即使有雙親委派關係的存在,一個類的載入器,指的也是實際載入這個類的classLoader
3、每個執行緒繫結一個classLoader