前言
最近需要做儀表盤(pán)相關(guān)的項(xiàng)目,用到了ETL工具Kettle,下載鏈接:data-integration-kettle,這是一款基于Java開(kāi)發(fā)的工具,當(dāng)然,Java環(huán)境變量相關(guān)配置就不在這里說(shuō)明了,不過(guò)相信大家電腦上一般也都配好了環(huán)境變量,那么理論上來(lái)說(shuō)應(yīng)該解壓Kettle即可用才對(duì)。然而在進(jìn)行數(shù)據(jù)庫(kù)連接時(shí),測(cè)試連接拋出了一個(gè)報(bào)錯(cuò):
錯(cuò)誤連接數(shù)據(jù)庫(kù) [xxx] : org.pentaho.di.core.exception.KettleDatabaseException:
Error occurred while trying to connect to the database
Driver class 'org.gjt.mm.mysql.Driver' could not be found, make sure the 'MySQL' driver (jar file) is installed.
org.gjt.mm.mysql.Driver
org.pentaho.di.core.exception.KettleDatabaseException:
Error occurred while trying to connect to the database
Driver class 'org.gjt.mm.mysql.Driver' could not be found, make sure the 'MySQL' driver (jar file) is installed.
org.gjt.mm.mysql.Driver
at org.pentaho.di.core.database.Database.normalConnect(Database.java:477)
at org.pentaho.di.core.database.Database.connect(Database.java:373)
at org.pentaho.di.core.database.Database.connect(Database.java:344)
...
解決辦法
問(wèn)題很明顯,數(shù)據(jù)庫(kù)驅(qū)動(dòng)問(wèn)題,相信大家在遇到這個(gè)問(wèn)題查找解決方案時(shí),肯定會(huì)搜索到千篇一律的答案,即在data-integration\lib目錄下放入mysql-connector-java.jar包即可。
可能大部分人這樣操作問(wèn)題會(huì)得到解決,但是很遺憾,本人在lib目錄下放入各個(gè)版本的jar包后,均不起作用,進(jìn)而開(kāi)始思考原因。找了許久,在jdk目錄C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext下,我發(fā)現(xiàn)不知道什么時(shí)候被我放入了一個(gè)mysql-connector-java-8.0.16.jar包,然后有了個(gè)推測(cè):
- Kettle基于Java啟動(dòng)
- 數(shù)據(jù)連接的jar包首先從jdk目錄讀取
- 若jdk目錄不存在數(shù)據(jù)庫(kù)驅(qū)動(dòng)包,則從安裝目錄的lib目錄下讀取
進(jìn)過(guò)測(cè)試,測(cè)試結(jié)果如下:
- 刪除jdk目錄下的所有數(shù)據(jù)庫(kù)驅(qū)動(dòng)包,刪除
data-integration\lib下的所有數(shù)據(jù)庫(kù)驅(qū)動(dòng)包,重啟Kettle,連接數(shù)據(jù)庫(kù)失敗。 - 刪除jdk目錄下的所有數(shù)據(jù)庫(kù)驅(qū)動(dòng)包,在
data-integration\lib放入mysql-connector-java-5.1.48.jar數(shù)據(jù)庫(kù)驅(qū)動(dòng)包,重啟Kettle,連接數(shù)據(jù)庫(kù)成功。 - 在jdk目錄下放入mysql-connector-java-5.1.48.jar數(shù)據(jù)庫(kù)驅(qū)動(dòng)包,刪除
data-integration\lib下的所有數(shù)據(jù)庫(kù)驅(qū)動(dòng)包,重啟Kettle,連接數(shù)據(jù)庫(kù)成功。 - 刪除jdk目錄下的所有數(shù)據(jù)庫(kù)驅(qū)動(dòng)包,在
data-integration\lib放入mysql-connector-java-8.0.16.jar數(shù)據(jù)庫(kù)驅(qū)動(dòng)包,重啟Kettle,連接數(shù)據(jù)庫(kù)失敗。 - 在jdk目錄下放入mysql-connector-java-8.0.16.jar數(shù)據(jù)庫(kù)驅(qū)動(dòng)包,刪除
data-integration\lib下的所有數(shù)據(jù)庫(kù)驅(qū)動(dòng)包,重啟Kettle,連接數(shù)據(jù)庫(kù)失敗。 - 在jdk目錄下放入mysql-connector-java-8.0.16.jar、mysql-connector-java-5.1.48.ja數(shù)據(jù)庫(kù)驅(qū)動(dòng)包,刪除
data-integration\lib下的所有數(shù)據(jù)庫(kù)驅(qū)動(dòng)包,重啟Kettle,連接數(shù)據(jù)庫(kù)成功。
其實(shí)到了這一步,問(wèn)題的解決方案已經(jīng)出來(lái)了,總結(jié)如下(后續(xù)結(jié)果為分析探討為什么8.0+版本的jar包會(huì)失效):
- Kettle工具安裝目錄
data-integration\lib放入mysql-connector-java-5.1.48.jar。 - Jdk目錄
C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext放入mysql-connector-java-5.1.48.jar。 - 重啟Kettle。
- 下載鏈接:mysql-connector-java-5.1.48 mysql-connector-java-8.0.16
后續(xù)分析
所以,問(wèn)題現(xiàn)在變成了,為什么Kettle讀取了mysql8.0+版本的數(shù)據(jù)庫(kù)驅(qū)動(dòng)包,仍然提示'org.gjt.mm.mysql.Driver' could not be found?
使用解壓工具將mysql-connector-java-5.1.48.jar與mysql-connector-java-8.0.16.jar包解壓,可以很明顯看到二者的目錄結(jié)構(gòu)差別:


顯而易見(jiàn),在5.0+的版本中,數(shù)據(jù)庫(kù)驅(qū)動(dòng)jar包提供了org.gjt.mm.mysql.Driver.class文件,然而在8.0+版本的數(shù)據(jù)庫(kù)驅(qū)動(dòng)jar包中,則根本沒(méi)有這個(gè)路徑,所以上述的測(cè)試中,在單獨(dú)使用8.0+版本的jar包時(shí),數(shù)據(jù)連接失敗的原因也找到了,MySQL官方在新版本中更改了類(lèi)文件的路徑,而為了兼容性問(wèn)題,Kettle仍然采用了老的路徑,所以出現(xiàn)了可以使用低版本的jar包連接高版本數(shù)據(jù)庫(kù)的情況。
那么有沒(méi)有辦法使用8.0+的jar包呢,或者說(shuō)Kettle工具為什么要以這種方式讀取數(shù)據(jù)庫(kù)驅(qū)動(dòng)呢,可以更改嗎?繼續(xù)查。
我們可以在Kettle數(shù)據(jù)庫(kù)連接設(shè)置時(shí),選擇MySQL(因?yàn)楸救诵枰B接的數(shù)據(jù)庫(kù)是MySQL),點(diǎn)擊下方特征列表,可看到對(duì)應(yīng)的參數(shù):

可以看到這里已經(jīng)被定義好了,以org.gjt.mm.mysql.Driver讀取,其實(shí),在Java與MySQL數(shù)據(jù)庫(kù)連接中,5.0+版本的連接連接是這樣定義的:
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/db3?userSSL=false
8.0+版本的連接連接是這樣定義的:
driverClassName=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/db3?userSSL=false&serverTimezone=UTC
與Kettle這里預(yù)定義的class路徑并不一致,那么我們要怎樣才能修改這個(gè)路徑呢?在特征列表里面可以直接修改,但是并沒(méi)有保存的按鈕,修改了也不會(huì)生效,有另外一種辦法。
在Kettle設(shè)置數(shù)據(jù)庫(kù)連接時(shí),不選擇MySQL,而選擇Generic database的連接類(lèi)型,如下:

該連接類(lèi)型為自定義數(shù)據(jù)庫(kù)URL,一看便知,此時(shí)和Java定義數(shù)據(jù)連接時(shí)幾乎一致,所以填寫(xiě)自定義連接URL,自定義驅(qū)動(dòng)名稱(chēng)即可,這里需要注意的是,8.0+版本的MySQL在連接時(shí)需要指定時(shí)區(qū),這是上述兩個(gè)版本的連接url不一致的原因,而class類(lèi)文件的路徑也略有不同,稍作注意即可。
使用自定義連接,終于在使用8.0+jar包的同時(shí),正確連接到了數(shù)據(jù)庫(kù)。
至此,問(wèn)題應(yīng)該算是圓滿(mǎn)解決,雖然花了大量的時(shí)間,但是遇到問(wèn)題,就得解決、看透問(wèn)題。希望能對(duì)大家提供一點(diǎn)小小的幫助。
歡迎訪問(wèn)我的個(gè)人博客:Lemon - 萬(wàn)事順?biāo)?/a>