gradle構建 程序包com.sun.image.codec.jpeg不存在,解決方法

Gradle構建錯誤: 程序包com.sun.image.codec.jpeg不存在

D:\Projects\EclipseProjects\JavaDog\sample\y2018\date0912\批量下載\DpiUtil.java:12: 錯誤: 程序包com.sun.image.codec.jpeg不存在 import com.sun.image.codec.jpeg.JPEGCodec;

原因

這是因爲classpath中不包含sun公司的一些包導致的。
jdk1.7開始jdk被賣身給了oracle,sun公司的一些包不包含在jdk中,變爲私有的,默認是不使用的,所以編譯失敗了。

但爲什麼,eclipse、IDEA能夠編譯通過,而單獨使用gradle或者maven 不行?
eclipse和IDEA在run的時候,默認classpath加上了很多jar包。例如IDEA運行某個main方法,加上了-classpath參數:

"C:\Program Files\Java\jdk1.8.0_202\bin\java.exe" 
-javaagent:D:\Programming\IDE\IdeaIU\lib\idea_rt.jar=57164:D:\Programming\IDE\IdeaIU\bin 
-Dfile.encoding=UTF-8 
-classpath "C:\Program Files\Java\jdk1.8.0_202\jre\lib\charsets.jar;
C:\Program Files\Java\jdk1.8.0_202\jre\lib\deploy.jar;
C:\Program Files\Java\jdk1.8.0_202\jre\lib\ext\access-bridge-64.jar;
C:\Program Files\Java\jdk1.8.0_202\jre\lib\ext\cldrdata.jar;
C:\Program Files\Java\jdk1.8.0_202\jre\lib\ext\dnsns.jar;
C:\Program Files\Java\jdk1.8.0_202\jre\lib\ext\jaccess.jar;
C:\Program Files\Java\jdk1.8.0_202\jre\lib\ext\jfxrt.jar;
C:\Program Files\Java\jdk1.8.0_202\jre\lib\ext\localedata.jar;
C:\Program Files\Java\jdk1.8.0_202\jre\lib\ext\nashorn.jar;
C:\Program Files\Java\jdk1.8.0_202\jre\lib\ext\sunec.jar;
C:\Program Files\Java\jdk1.8.0_202\jre\lib\ext\sunjce_provider.jar;
C:\Program Files\Java\jdk1.8.0_202\jre\lib\ext\sunmscapi.jar;
C:\Program Files\Java\jdk1.8.0_202\jre\lib\ext\sunpkcs11.jar;
C:\Program Files\Java\jdk1.8.0_202\jre\lib\ext\zipfs.jar;
C:\Program Files\Java\jdk1.8.0_202\jre\lib\javaws.jar;
C:\Program Files\Java\jdk1.8.0_202\jre\lib\jce.jar;
C:\Program Files\Java\jdk1.8.0_202\jre\lib\jfr.jar;
C:\Program Files\Java\jdk1.8.0_202\jre\lib\jfxswt.jar;
C:\Program Files\Java\jdk1.8.0_202\jre\lib\jsse.jar;
C:\Program Files\Java\jdk1.8.0_202\jre\lib\management-agent.jar;
C:\Program Files\Java\jdk1.8.0_202\jre\lib\plugin.jar;
C:\Program Files\Java\jdk1.8.0_202\jre\lib\resources.jar;
C:\Program Files\Java\jdk1.8.0_202\jre\lib\rt.jar;
D:\Projects\EclipseProjects\JavaDog\out\production\classes;
D:\Projects\EclipseProjects\JavaDog\libs\core-3.2.2-SNAPSHOT.jar;
D:\Projects\EclipseProjects\JavaDog\libs\httpclient-4.5.2.jar;
D:\Projects\EclipseProjects\JavaDog\libs\xmlpull_1_1_3_4c.jar;
D:\Projects\EclipseProjects\JavaDog\libs\cpdetector\ext\jargs-1.0.jar;
D:\Projects\EclipseProjects\JavaDog\libs\cpdetector\ext\antlr-2.7.4.jar;
D:\Projects\EclipseProjects\JavaDog\libs\retrofit-2.5.0.jar;
D:\Projects\EclipseProjects\JavaDog\libs\okio-1.11.0.jar;
D:\Projects\EclipseProjects\JavaDog\libs\cpdetector\ext\chardet-1.0.jar;
D:\Projects\EclipseProjects\JavaDog\libs\fastjson-1.2.9.jar;
D:\Projects\EclipseProjects\JavaDog\libs\reactive-streams-1.0.2.jar;
D:\Projects\EclipseProjects\JavaDog\libs\mariadb-java-client-2.1.2.jar;
D:\Projects\EclipseProjects\JavaDog\libs\javase-3.2.1.jar;
D:\Projects\EclipseProjects\JavaDog\libs\rxjava-2.2.3.jar;
D:\Projects\EclipseProjects\JavaDog\libs\javax.mail.jar;
D:\Projects\EclipseProjects\JavaDog\libs\dom4j-1.6.1.jar;
D:\Projects\EclipseProjects\JavaDog\libs\okhttp-3.5.0.jar;
D:\Projects\EclipseProjects\JavaDog\libs\javase-3.2.1-sources.jar;
D:\Projects\EclipseProjects\JavaDog\libs\mysql-connector-java-5.0.5-bin.jar;
D:\Projects\EclipseProjects\JavaDog\libs\kxml2-2.2.2.jar;
D:\Projects\EclipseProjects\JavaDog\libs\jsoup-1.11.3.jar;
D:\Projects\EclipseProjects\JavaDog\libs\cpdetector\cpdetector_1.0.10.jar;
C:\Users\Lu\.m2\repository\org\junit\jupiter\junit-jupiter-api\5.5.2\junit-jupiter-api-5.5.2.jar;
C:\Users\Lu\.m2\repository\org\junit\platform\junit-platform-commons\1.5.2\junit-platform-commons-1.5.2.jar;
C:\Users\Lu\.m2\repository\org\apiguardian\apiguardian-api\1.1.0\apiguardian-api-1.1.0.jar;
C:\Users\Lu\.m2\repository\org\opentest4j\opentest4j\1.2.0\opentest4j-1.2.0.jar" y2018.date0912.批量下載.Test

解決方法

  • 1、將報錯誤的sun包代碼移除,使用其他api代替。(推薦★★★★★)
  • 2、將 jre/lib/rt.jar 加入classpath中(推薦★★★)
  • 3、將 jre/lib/rt.jar 加入依賴(推薦★★)

加入classpath是個解決方案,但不能保證不同環境能夠穩健執行,比如特別新的jdk或某些定製的jdk。加入依賴庫,比如項目的libs目錄中,也不推薦,打包時會增加體積。
推薦替換掉,保持程序的兼容性、可靠性。

PS:
1、sun包有很多不同類型,需要替換方式不同,不進行討論。
2、以下構建腳本都是kotlin腳本,即build.gradle.kts,xxx.gradle基本適用,但需要稍微修改。
3、下面的代碼沒有加入classpath而是加入bootstrapClasspath ,這是因爲classpath居然是隻讀的,
4、老版本gradle可能需要使用classbootpath,新版本使用bootstrapClasspath

本文當前使用gradle爲 6.1 版本。目前最新的正式版本。
參考:
https://docs.gradle.org/current/userguide/upgrading_version_4.html#potential_breaking_changes

The CompileOptions.bootClasspath property has been removed — use CompileOptions.bootstrapClasspath instead.


將 jre/lib/rt.jar 加入依賴(推薦★★★)

很簡單,到jdk/jre/lib/複製rt.jar加入libs目錄即可。

不可以不復制到 libs,直接配置 jdk/jre/lib/rt.jar 路徑到依賴中是無效的,按說應該可以,但實際上不行,原因不明。

//獲取系統環境變量javahome
var JAVA_HOME = System.getenv("JAVA_HOME")
dependencies {
// 實際上無效,要複製項目目錄的libs中。
	implementation(fileTree("$JAVA_HOME$/jre/lib/rt.jar"))
}

實際上配置這個即可

implementation(fileTree(mapOf("dir" to "libs", "include" to listOf("*.jar"))))

將 jre/lib/rt.jar 加入classpath中(推薦★★)

簡單的寫法

//獲取系統環境變量javahome
var JAVA_HOME = System.getenv("JAVA_HOME")
tasks.withType(JavaCompile::class) {
    options.bootstrapClasspath = fileTree("$JAVA_HOME/jre/lib/rt.jar")
}

參照IDEA構建的寫法

較爲完善,加上一堆的 jar 包

//獲取系統環境變量javahome
var JAVA_HOME = System.getenv("JAVA_HOME")
tasks.withType(JavaCompile::class) {
    //enable compilation in a separate daemon process
    sourceCompatibility = "1.8"
    targetCompatibility = "1.8"
    // 編譯參數,打印一些編譯信息
    options.compilerArgs = listOf<String>("-Xlint:unchecked", "-Xlint:deprecation", "-XDignore:symbol.file")

    var bootstrapClasspathArray = arrayListOf<String>(
            "$JAVA_HOME/jre/lib/charsets.jar",
            "$JAVA_HOME/jre/lib/deploy.jar",
            "$JAVA_HOME/jre/lib/ext/access-bridge-64.jar",
            "$JAVA_HOME/jre/lib/ext/cldrdata.jar",
            "$JAVA_HOME/jre/lib/ext/dnsns.jar",
            "$JAVA_HOME/jre/lib/ext/jaccess.jar",
            "$JAVA_HOME/jre/lib/ext/jfxrt.jar",
            "$JAVA_HOME/jre/lib/ext/localedata.jar",
            "$JAVA_HOME/jre/lib/ext/nashorn.jar",
            "$JAVA_HOME/jre/lib/ext/sunec.jar",
            "$JAVA_HOME/jre/lib/ext/sunjce_provider.jar",
            "$JAVA_HOME/jre/lib/ext/sunmscapi.jar",
            "$JAVA_HOME/jre/lib/ext/sunpkcs11.jar",
            "$JAVA_HOME/jre/lib/ext/zipfs.jar",
            "$JAVA_HOME/jre/lib/javaws.jar",
            "$JAVA_HOME/jre/lib/jce.jar",
            "$JAVA_HOME/jre/lib/jfr.jar",
            "$JAVA_HOME/jre/lib/jfxswt.jar",
            "$JAVA_HOME/jre/lib/jsse.jar",
            "$JAVA_HOME/jre/lib/management-agent.jar",
            "$JAVA_HOME/jre/lib/plugin.jar",
            "$JAVA_HOME/jre/lib/resources.jar",
            "$JAVA_HOME/jre/lib/rt.jar")
            .filter {
                var prefile = file(it)
                if (prefile.exists()) {
                    true
                } else {
                    println("Warining,ignore this classpath,not exists $it")
                    false
                }
            }
    options.bootstrapClasspath = files(bootstrapClasspathArray)
}

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