Closed luckybilly closed 4 years ago
classpath 'com.android.tools.build:gradle:3.2.0'
)
编译报错日志如下:
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':demo:transformClassesWithCc-registerForDebug'.
> java.lang.IllegalArgumentException (no error message)
* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.
按照提示使用--stacktrace
参数后详细日志中可以看到关键信息:
Caused by: java.lang.IllegalArgumentException
at org.objectweb.asm.ClassReader.<init>(Unknown Source)
at org.objectweb.asm.ClassReader.<init>(Unknown Source)
at org.objectweb.asm.ClassReader.<init>(Unknown Source)
通过查看源码可知:这个问题的原因是由于ASM5不支持大于1.8的jdk所编译的class导致的
public ClassReader(final byte[] b, final int off, final int len) {
this.b = b;
// checks the class version
if (readShort(off + 6) > Opcodes.V1_8) {
throw new IllegalArgumentException();
}
//其它代码...
}
在ASM6.0中ClassReader构造方法的版本判断逻辑如下(可支持JDK9):
public ClassReader(final byte[] b, final int off, final int len) {
this.b = b;
// checks the class version
if (readShort(off + 6) > Opcodes.V9) {
throw new IllegalArgumentException();
}
//其它代码...
}
通过查看ASM各版本源码得知,ASM版本所支持的JDK版本对应关系如下表:
ASM版本号 | 最高支持的JDK版本 超过就报错 |
---|---|
5.0 | 8 |
5.1 | 8 |
5.2 | 8 |
6.0 | 9 |
6.1 | 10 |
6.2 | 11 |
6.2.1 | 12 |
7.0 | 12 |
7.1 | 13 |
7.2 | 14 |
而ASM的版本又是根据gradle插件的版本而定的:
通过一步步排查确定,android gradle插件3.2.0版本才将ASM升级到6.0,
目前的最新版3.5.3对应的ASM版本也是6.0,所以不能支持JDK10及以上的版本
ASM源码中,将当前支持的API版本信息记录到了Opcodes接口类中:
public interface Opcodes {
// ASM API versions
int ASM4 = 4 << 16 | 0 << 8 | 0;
int ASM5 = 5 << 16 | 0 << 8 | 0;
int ASM6 = 6 << 16 | 0 << 8 | 0;
//.......
}
在ASM官网上看到,目前最新的ASM版本是7.2,在cc-register 1.1.2版中通过这种方式暂时兼容到ASM10以下:
private static int ASM_LEVEL = 0
static int getAsmApiLevel() {
if (ASM_LEVEL > 0) return ASM_LEVEL
int api = Opcodes.ASM5
for (i in (10..5)) {
try {
def field = Opcodes.class.getDeclaredField("ASM" + i)
if (field != null) {
api = field.get(null)
break
}
} catch (Throwable ignored) {
}
}
ASM_LEVEL = api
return ASM_LEVEL
}
终于解决了。之前遇到了这个问题,原来是gson导致的。
如题