Search code examples
javaruntimejava-bytecode-asmdynamic-class-creation

super class not assignable to class implemented during runtime by asm


I have a java class that consist of an inner interface, and plan to implement the implementation class during runtime with asm bytecode injection.

package my.example;
public class X{
    public static interface XInt{
        public void getX();
    }
    //the following class that implement the interface will be defined during runtime.
    //I put it here just to show how the implementation will look like
    public static XImpl extend Y implements XInt{
        public void getX(){//implementation code}
    }
}

I am sure my asm code is correct, but the thing is after defining the class and call Class.forName("my.example.X$XImpl"), I get the following error:

> Bad <init> method call
Exception Details:
  Location:
    my/example/X$XImpl.<init>()V: invokespecial
  Reason:
    Type 'my/other/package/Y' is not assignable to 'my/example/X$XImpl'

My guess is that the class Y is not available during runtime yet? I have no idea.. Any help would be appreciated!

EDIT: The way I load XImpl is very simple:

defineClass("my.example.X$XImpl", getXImplByte());
Class.forName("my.example.X$XImpl"); //fails here

The reason why im sure my byte code and class loading method is right because if i define the implementation class without extending any other class, it will work fine


Solution

  • Seems that ASM classloader isn't a child of X classloader, so there is two different classes (even though they are identical), which can't be casted to each other.

    Try to use:

    Method m = ClassLoader.getDeclaredMethods("defineClass", String.class, byte[].class, int.class, int.class);
    m.setAccessible(true);
    m.invoke(X.class.getClassLoader(), ...);