为什么编译时会报 Unsupported major.minor version 51.0 错误?
2019-09-11
关键字:Android 大包编译
搞 Android 系统开发的时候,常用的编译模块的命令无非就两条:
mm
mmm
但有的时候却发现,以前用的好好的编译命令,突然就报错了。比如:
Exception in thread "main" java.lang.UnsupportedClassVersionError: com/android/signapk/SignApk : Unsupported major.minor version 51.0 at java.lang.ClassLoader.defineClass1(Native Method) at java.lang.ClassLoader.defineClassCond(ClassLoader.java:631) at java.lang.ClassLoader.defineClass(ClassLoader.java:615) at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:141) at java.net.URLClassLoader.defineClass(URLClassLoader.java:283) at java.net.URLClassLoader.access$000(URLClassLoader.java:58) at java.net.URLClassLoader$1.run(URLClassLoader.java:197) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(URLClassLoader.java:190) at java.lang.ClassLoader.loadClass(ClassLoader.java:306) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301) at java.lang.ClassLoader.loadClass(ClassLoader.java:247) Could not find the main class: com.android.signapk.SignApk. Program will exit. make: *** [out/target/product/rk3288/obj/APPS/GPIOAPI_intermediates/package.apk] Error 1
最后翻遍一众博客并经过一顿思考,终寻得答案:编译环境中的 JDK 版本有问题。
从这个异常栈信息字面意思来看是 SignApk 这个程序所能支持的最小版本号越界了。SignApk 是干嘛的我暂时还不知道,不过我知道有一个 SignApk.jar,它是用来给编译出来的 APK 签名用的。也许这个 SignApk 也有差不多的作用吧。不过这并不重要。
既然异常信息栈中有提到因为 java 的 class loader 因版本越界而报错,那我们就来看看当前系统的 PATH 信息:
$echo $PATH /opt/jdk1.6.0_29//bin: ... :/opt/jdk1.6.0_29//bin:/opt/jdk1.6.0_29/jre/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games
这里可以很明显地看到笔者所使用的系统环境下只引入了 JDK6,而刚好笔者在开发的 Android 系统是 5.1 的,这个版本的 Android 系统要求 JDK 版本至少要达到 7。这当然要报版本越界错误的嘛。
既然问题的原因搞清楚了,那解决的办法自然也是很简单了。
最快速、应急式的解决办法,就是手动将 JDK7 的路径引入到系统 PATH 中。
例如,笔者所使用的编译服务器下已经安装有 JDK7 的软件了,它的路径为:
/opt/jdk1.7.0_65/
所以,只需要使用如下命令手动添加 JDK7 的路径进 PATH 即可:
export PATH=/opt/jdk1.7.0_65/bin:$PATH
这个时候可以再检查一个 PATH 的信息,确认这个 JDK7 的路径被应用上去了。
这个时候,再来编译,就发现不会再报版本异常的错误了。
---
这里再贴一下上面异常栈中提到的 51.0 版本号与 JDK 版本号之间的对应关系
1.1 ---> 45
1.2 ---> 46
1.3 ---> 47
1.4 ---> 48
1.5 ---> 49
1.6 ---> 50
1.7 ---> 51
1.8 ---> 52
如果我们打一开始就知道这个 51.0 指代的就是 JDK1.7 版本,那肯定立马就能想到是自己当前编译链中的 JDK 版本有问题了。所以,适当的了解一下这些对应关系还是有一定帮助作用的。