background

Gradle plugins throw exceptions when using the ASM or Javassist libraries.

The exception information is as follows: ASM:

Caused by: java.lang.RuntimeException
	at org.objectweb.asm.ClassVisitor.visitModule(ClassVisitor.java:148)
	at org.objectweb.asm.ClassReader.readModule(ClassReader.java:731)
	at org.objectweb.asm.ClassReader.accept(ClassReader.java:632)
	at org.objectweb.asm.ClassReader.accept(ClassReader.java:500)
Copy the code

Javassist:

java.io.IOException: invalid constant type: 19 at 5
	at javassist.bytecode.ConstPool.readOne(ConstPool.java:1244)
	at javassist.bytecode.ConstPool.read(ConstPool.java:1175)
	at javassist.bytecode.ConstPool.<init>(ConstPool.java:185)
	at javassist.bytecode.ClassFile.read(ClassFile.java:829)
	at javassist.bytecode.ClassFile.<init>(ClassFile.java:154)
	at javassist.CtClassType.<init>(CtClassType.java:96)
	at javassist.ClassPool.makeClass(ClassPool.java:729)
	at javassist.ClassPool.makeClass(ClassPool.java:707)
	at javassist.ClassPool$makeClass$2.call(Unknown Source)
Copy the code

Question why

The module-info.class file was used when the plugin failed.

module-info.class

First, we find that the module-info.class exists in multiple official Kotlin libraries, for example:

Org. Jetbrains. Kotlin: kotlin stdlib - common: 1.4.21 + kotlin - stdlib - jdk8-1.4.21. Jar + - meta-inf + versions + - - - 9 +--- module-info.classCopy the code

Module-info.class contains the following contents:

module kotlin.stdlib { exports kotlin; exports kotlin.annotation; exports kotlin.collections; exports kotlin.collections.unsigned; exports kotlin.comparisons; . }Copy the code

The function of this class can be found by baidu + Google. In short, JDK9 supports modularization, a package organization similar to the Dart language, and JS export, so that you can manage or reorganize a new package, rather than controlling access through Java modifiers like JDK8. The module-info.class manages and describes this package;

Module-info.class does not work in JDK8 or below, only in JDK9 or above;

As you can see, this class is not a normal class and contains no classes or methods, so asm and Javassist will parse the class with an error.

The solution

Method 1: Check whether the signature of the class is module-info.class. If yes, skip it. But all plug-ins need to do this;

Write a separate plugin that removes the module-info.class and register the transform first so that all subsequent plug-ins don’t handle the class. The disadvantage is that the project cannot support JDK9, but Android currently supports JDK8, so the impact is not big;

Finally, we adopted the second method of the project. The current operation is stable and no abnormality is found.