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
加入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.
很简单,到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"))))
//获取系统环境变量javahome
var JAVA_HOME = System.getenv("JAVA_HOME")
tasks.withType(JavaCompile::class) {
options.bootstrapClasspath = fileTree("$JAVA_HOME/jre/lib/rt.jar")
}
较为完善,加上一堆的 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)
}