Use a class from byte array without reflection?

I've instrumented my class using ASM and processed it like this

public class MyClassLoader extends ClassLoader {
...
    byte[] classBytes = ... //the class is of type com.mypackage.Test
    Class clazz = defineClass("com.mypackage.Test", classBytes, 0, classBytes.length);
    resolveClass(clazz);
    com.mypackage.Test test =(com.mypackage.Test) clazz.newInstance();

However I get ClassCastException on the last line:

java.lang.ClassCastException: com.mypackage.Test cannot be cast to com.mypackage.Test

The workaround is to use reflection:

Object test = clazz.newInstance();
test.getClass().getMethods()[0].invoke(test, null); //invoke some method - successfully

Am I using using wrong classloader or something?

Upvotes: 0

Views: 967

Answers (1)

Tom Hawtin - tackline
Tom Hawtin - tackline

Reputation: 147164

Class.newInstance is a reflective call.

Typically what you would do in these situations is have the class loader be a child of the class loader that loaded the existing code. Have the implementation class implement an interface from your code's class loader. Use Class.asSubclass such that the Class is a known subtype of your interface. Construct an instance of the implementation class through Class.getConstructor.newInstance.

Using this technique you are not dependent upon using reflection to pick out a method, although it does require a no-args constructor.

Upvotes: 5

Related Questions