为什么编译时会报 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 版本有问题了。所以,适当的了解一下这些对应关系还是有一定帮助作用的。

 


 

上一篇:java.lang.NoClassDefFoundError: org/w3c/dom/ElementTraversal问题解决


下一篇:java_ClassLoader学习