Java jar 命令行運行程序如何引用第三方依賴包

1 引言

mybatis generator 是一個命令行運行工具,可以生成 mybatis 代碼。但它需要依賴數據庫驅動 jar,否則會拋出 ClassNotFoundException 異常。

Exception in thread "main" java.lang.RuntimeException: Exception getting JDBC Driver
        at org.mybatis.generator.internal.JDBCConnectionFactory.getDriver(JDBCConnectionFactory.java:100)
        at org.mybatis.generator.internal.JDBCConnectionFactory.getConnection(JDBCConnectionFactory.java:83)
        at org.mybatis.generator.config.Context.getConnection(Context.java:542)
        at org.mybatis.generator.config.Context.introspectTables(Context.java:446)
        at org.mybatis.generator.api.MyBatisGenerator.generate(MyBatisGenerator.java:257)
        at org.mybatis.generator.api.MyBatisGenerator.generate(MyBatisGenerator.java:189)
        at org.mybatis.generator.api.ShellRunner.main(ShellRunner.java:117)
Caused by: java.lang.ClassNotFoundException: org.postgresql.Driver
        at java.net.URLClassLoader.findClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at java.lang.Class.forName0(Native Method)
        at java.lang.Class.forName(Unknown Source)
        at org.mybatis.generator.internal.ObjectFactory.internalClassForName(ObjectFactory.java:148)
        at org.mybatis.generator.internal.ObjectFactory.externalClassForName(ObjectFactory.java:119)
        at org.mybatis.generator.internal.JDBCConnectionFactory.getDriver(JDBCConnectionFactory.java:97)
        ... 6 more
'-overwrite' 不是內部或外部命令,也不是可運行的程序
或批處理文件。

這也就引出了本文的問題:利用 Java jar 命令行運行程序如何引用第三方依賴包?

2 Java 類加載器

JDK9 之前把類加載器分爲三類,它們分別是啓動類加載器、擴展類加載器和應用程序類加載器。

(1)啓動類加載器 ( Bootstrap Class Loader )

啓動類加載器負責加載存放在 <JAVA_HOME>\lib 目錄,或者被 -Xbootclasspath 參數所指定的路徑中存放的、且是 Java 虛擬機能夠識別的類庫加載到虛擬機的內存中。

(2)擴展類加載器 (Extension Class Loader)

擴展類加載器是在類 sun.misc.Launchers&ExtClassLoader 中以 Java 代碼的形式實現的。它負責加載 <JAVA_HOME>\lib\ext 目錄中,或者被 java. ext .dirs 系統變量所指定的路徑中所有的類庫。

(3)應用程序類加載器 (Application Class Loader )

應用程序類加載器由 sun.misc.Launcher&AppClassLoader實現。它負責加載用戶類路徑 (Classpath) 上所有的類庫。

3 雙親委派模型

類加載器之間的層次關係被稱爲類加載器的 “ 雙親委派模型 (Parents Delegation Model)”。 雙親委派模型要求除了頂層的啓動類加載器外,其餘的類加載器都應有自己的父類加載器。

如果一個類加載器收到了類加載的請求,它首先不會自己去嘗試加載這個類,而是把這個請求委派給父類加載器去完成,每一個層次的類加載器都是如此,因此所有的加載請求最終都應該傳送到最頂層的啓動類加載器中,只有當父加載器反饋自己無法完成這個加載請求 ( 它的搜索範圍中沒有找到所需的類 ) 時,子加載器纔會嘗試自己去完成加載。

4 引用第三方依賴包

(1)使用啓動類加載器

-Xbootclasspath/a:xxx.jar

示例:

java -Xbootclasspath/a:postgresql-42.2.18.jar; -jar mybatis-generator-core-1.3.7.jar -configfile generatorConfig.xml -overwrite

(2) 使用擴展類加載器

-Djava.ext.dirs=擴展類所在路徑

示例:

cd C:\workspace\ideaProjects\deniro-app\deniro-fly\generator\
java -Djava.ext.dirs=C:\programs\jdk1.8.0_181\jre\lib\ext -jar mybatis-generator-core-1.3.7.jar -configfile generatorConfig.xml
-overwrite

通過擴展類加載器來指定第三方依賴包的所在路徑,可以實現多個命令行程序複用這些第三方依賴包,因此建議採用。

參考資料

周志明. 深入理解Java虛擬機[M]. 機械工業出版社, 2019.

https://www.cnblogs.com/wqbin/p/11122709.html

https://blog.csdn.net/cyony/article/details/74375251/

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章