猿Why碰到一个异常【INVOKESPECIAL/STATIC on interfaces require ASM 5】。
跟踪到异常抛出的类:org.springframework.asm.MethodVisitor
/**
* Visits a method instruction. A method instruction is an instruction that invokes a method.
*
* @param opcode the opcode of the type instruction to be visited. This opcode is either
* INVOKEVIRTUAL, INVOKESPECIAL, INVOKESTATIC or INVOKEINTERFACE.
* @param owner the internal name of the method's owner class (see {@link
* Type#getInternalName()}).
* @param name the method's name.
* @param descriptor the method's descriptor (see {@link Type}).
* @param isInterface if the method's owner class is an interface.
*/
public void visitMethodInsn(
final int opcode,
final String owner,
final String name,
final String descriptor,
final boolean isInterface) {
if (api < Opcodes.ASM5 && (opcode & Opcodes.SOURCE_DEPRECATED) == 0) {
if (isInterface != (opcode == Opcodes.INVOKEINTERFACE)) {
throw new UnsupportedOperationException("INVOKESPECIAL/STATIC on interfaces requires ASM5");
}
visitMethodInsn(opcode, owner, name, descriptor);
return;
}
if (mv != null) {
mv.visitMethodInsn(opcode & ~Opcodes.SOURCE_MASK, owner, name, descriptor, isInterface);
}
}
大概意思:spring中对bean做了一些asm增强,同时会限制一些调用。例如:异常抛出点的意思是:当org.springframework.asm.MethodVisitor#api
的值小于org.springframework.asm.Opcodes#ASM5
的时候,interface中的static方法不允许被调用!也就是说:如果使用的是org.springframework.asm.Opcodes#ASM5
之前的版本对代码做了字节码增强,那么在增强后的类中不允许出现interface中的static方法被调用
的情况。
举例说明
public interface Asm4Interface{
static void asm4Method();
}
@service
public class Asm4Service{
public void serviceMethod(){
Asm4Interface.asm4Method();
}
}
如果Asm4Service
所在的应用中ASM的级别小于org.springframework.asm.Opcodes#ASM5
,就会触发异常抛出了!
org.springframework.asm.SpringAsmInfo#ASM_VERSION
则是ASM设置的值。
org.springframework.asm.SpringAsmInfo
在两个版本的值分别如下:
spring-core-3.2.9.RELEASE.jar
public final class SpringAsmInfo {
/**
* The ASM version used internally throughout the framework.
*
* @see Opcodes#ASM4
*/
public static final int ASM_VERSION = Opcodes.ASM4;
}
spring-core-5.3.12.jar
public final class SpringAsmInfo {
/**
* The ASM compatibility version for Spring's ASM visitor implementations:
* currently {@link Opcodes#ASM10_EXPERIMENTAL}, as of Spring Framework 5.3.
*/
public static final int ASM_VERSION = Opcodes.ASM10_EXPERIMENTAL;
}
另外,通过mvn命令来查看项目实际使用哪个版本的jar
mvn dependency:tree -Dincludes=:spring-context
建议
低版本的spring中,尽可能调用class的static方法,不要使用interface的static方法