如何将Java 8项目编译为可在Java 6 JRE运行的Jar包?
绝对可行!不过得做好几个关键配置,既要用Java 8的编译器来构建,又要确保最终产物能在Java 6上跑。我分几种常见的场景给你详细说步骤,你按需选就行:
首先得确保你的代码里没用到Java 7/8特有的东西:比如Lambda表达式、Stream API、Optional类、try-with-resources语法这些。要是不小心用了,要么替换成Java 6兼容的写法(比如用匿名内部类代替Lambda),要么后续考虑用RetroLambda这类工具转换(不过先建议你先清掉高版本语法,减少麻烦)。
另外,项目依赖的第三方库也得是Java 6兼容的,不然哪怕你的代码没问题,依赖包用了高版本API,到Java 6上跑还是会炸。
- 打开项目结构设置:按
Ctrl+Alt+Shift+S(Windows/Linux)或者Cmd+;(Mac)就能调出 - 配置全局项目:在
Project Settings > Project里,Project SDK选Java 8(必须用高版本编译器做交叉编译),Project language level改成6 - @Override in interface - 配置模块:进入
Modules选项卡,每个模块的Language level也改成和上面一样的Java 6级别 - 配置编译参数:到
Settings > Build, Execution, Deployment > Compiler > Java Compiler,找到你的项目模块,在Additional command line parameters里加一行:-source 1.6 -target 1.6 -bootclasspath /path/to/java6/jre/lib/rt.jar划重点:
-bootclasspath必须指定Java 6的rt.jar路径!不然编译器不会检查API兼容性,可能偷偷把Java 8的API编译进去,到Java 6上跑就报NoSuchMethodError之类的错。你得自己找个Java 6的JRE安装目录,比如Windows下可能是C:\Program Files\Java\jre1.6.0_45\lib\rt.jar,Mac下是/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home/jre/lib/rt.jar
如果是Maven管理的项目,直接在pom.xml里配置maven-compiler-plugin就行,不用手动调IntelliJ的设置:
<build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.1</version> <configuration> <!-- 指定源码和目标版本为Java 6 --> <source>1.6</source> <target>1.6</target> <!-- 关键:指定bootclasspath确保API兼容 --> <compilerArguments> <bootclasspath>${java6.home}/jre/lib/rt.jar</bootclasspath> </compilerArguments> </configuration> </plugin> </plugins> </build>
之后你可以在系统环境变量里设置java6.home指向Java 6的安装目录,或者直接把路径写死在bootclasspath里(不推荐,换机器就失效)。
要是用Gradle,就在build.gradle里加这段配置:
tasks.withType(JavaCompile) { sourceCompatibility = '1.6' targetCompatibility = '1.6' // 配置bootclasspath,确保只使用Java 6的API options.compilerArgs += [ '-bootclasspath', "${System.getenv('JAVA6_HOME')}/jre/lib/rt.jar" ] }
记得在系统环境变量里设置JAVA6_HOME指向Java 6的安装目录哦。
编译完Jar包后,一定要拿到Java 6的JRE环境下跑一遍!哪怕配置都对,也可能有隐藏的API兼容问题,比如某个第三方依赖偷偷用了高版本方法,只有跑起来才会发现。
内容的提问来源于stack exchange,提问作者Britney

