前言
最近需要做儀表盤相關(guān)的項目,用到了ETL工具Kettle,下載鏈接:data-integration-kettle,這是一款基于Java開發(fā)的工具,當(dāng)然,Java環(huán)境變量相關(guān)配置就不在這里說明了,不過相信大家電腦上一般也都配好了環(huán)境變量,那么理論上來說應(yīng)該解壓Kettle即可用才對。然而在進(jìn)行數(shù)據(jù)庫連接時,測試連接拋出了一個報錯:
錯誤連接數(shù)據(jù)庫 [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)
...
解決辦法
問題很明顯,數(shù)據(jù)庫驅(qū)動問題,相信大家在遇到這個問題查找解決方案時,肯定會搜索到千篇一律的答案,即在data-integration\lib目錄下放入mysql-connector-java.jar包即可。
可能大部分人這樣操作問題會得到解決,但是很遺憾,本人在lib目錄下放入各個版本的jar包后,均不起作用,進(jìn)而開始思考原因。找了許久,在jdk目錄C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext下,我發(fā)現(xiàn)不知道什么時候被我放入了一個mysql-connector-java-8.0.16.jar包,然后有了個推測:
- Kettle基于Java啟動
- 數(shù)據(jù)連接的jar包首先從jdk目錄讀取
- 若jdk目錄不存在數(shù)據(jù)庫驅(qū)動包,則從安裝目錄的lib目錄下讀取
進(jìn)過測試,測試結(jié)果如下:
- 刪除jdk目錄下的所有數(shù)據(jù)庫驅(qū)動包,刪除
data-integration\lib下的所有數(shù)據(jù)庫驅(qū)動包,重啟Kettle,連接數(shù)據(jù)庫失敗。 - 刪除jdk目錄下的所有數(shù)據(jù)庫驅(qū)動包,在
data-integration\lib放入mysql-connector-java-5.1.48.jar數(shù)據(jù)庫驅(qū)動包,重啟Kettle,連接數(shù)據(jù)庫成功。 - 在jdk目錄下放入mysql-connector-java-5.1.48.jar數(shù)據(jù)庫驅(qū)動包,刪除
data-integration\lib下的所有數(shù)據(jù)庫驅(qū)動包,重啟Kettle,連接數(shù)據(jù)庫成功。 - 刪除jdk目錄下的所有數(shù)據(jù)庫驅(qū)動包,在
data-integration\lib放入mysql-connector-java-8.0.16.jar數(shù)據(jù)庫驅(qū)動包,重啟Kettle,連接數(shù)據(jù)庫失敗。 - 在jdk目錄下放入mysql-connector-java-8.0.16.jar數(shù)據(jù)庫驅(qū)動包,刪除
data-integration\lib下的所有數(shù)據(jù)庫驅(qū)動包,重啟Kettle,連接數(shù)據(jù)庫失敗。 - 在jdk目錄下放入mysql-connector-java-8.0.16.jar、mysql-connector-java-5.1.48.ja數(shù)據(jù)庫驅(qū)動包,刪除
data-integration\lib下的所有數(shù)據(jù)庫驅(qū)動包,重啟Kettle,連接數(shù)據(jù)庫成功。
其實到了這一步,問題的解決方案已經(jīng)出來了,總結(jié)如下(后續(xù)結(jié)果為分析探討為什么8.0+版本的jar包會失效):
- 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ù)分析
所以,問題現(xiàn)在變成了,為什么Kettle讀取了mysql8.0+版本的數(shù)據(jù)庫驅(qū)動包,仍然提示'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)差別:


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

可以看到這里已經(jīng)被定義好了,以org.gjt.mm.mysql.Driver讀取,其實,在Java與MySQL數(shù)據(jù)庫連接中,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路徑并不一致,那么我們要怎樣才能修改這個路徑呢?在特征列表里面可以直接修改,但是并沒有保存的按鈕,修改了也不會生效,有另外一種辦法。
在Kettle設(shè)置數(shù)據(jù)庫連接時,不選擇MySQL,而選擇Generic database的連接類型,如下:

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