Reputation: 11
I get byte code from network. I transform byte array to class
package l2soft.utils;
public final class CustomClassLoader extends ClassLoader {
public static CustomClassLoader _instance;
public static CustomClassLoader getInstance() {
return _instance;
}
public void defineCustomClass(byte[] bytecode) {
Class<?> clazz = defineClass(null, bytecode, 0, bytecode.length);
resolveClass(clazz);
}
}
but when the application starts, derived classes can not be found.
The import test.Test1 cannot be resolved
(compilled with recieved class)
note: i don't know class file name. I do not need to request a class, the server itself sends
UPD:
package l2soft.utils;
import java.util.HashMap;
import java.util.Map;
public final class CustomClassLoader extends ClassLoader {
private Map<String, Class<?>> cache;
public static CustomClassLoader _instance;
public static CustomClassLoader getInstance() {
return _instance;
}
public CustomClassLoader(ClassLoader parent) {
super(ClassLoader.getSystemClassLoader());
_instance = this;
cache = new HashMap<String, Class<?>>();
}
public void defineCustomClass(byte[] bytecode) {
Class<?> clazz = defineClass(null, bytecode, 0, bytecode.length);
resolveClass(clazz);
cache.put(clazz.getName(), clazz);
}
@Override
public synchronized Class<?> findClass(String name) throws ClassNotFoundException {
Class<?> result = cache.get(name);
if(result == null)
super.findClass(name);
return result;
}
}
It is my custom classloader. SomeClass load by this classloader and tes.Test1. But i see error: import test.Test1 cannot resolve. This CustomClassLoader set as default loader (-Djava system.loader=l2soft.utils.CustomClassLoader)
Upvotes: 0
Views: 404
Reputation: 14791
Since you don't specify in your question, I'll assume that you're importing test.Test1
in a class named SomeClass
. I also assume that this class is in your initial classpath when you run the JVM (this seems to be implied by the nature of the problem).
When your application starts, it will load all the classes on the classpath (including SomeClass
) using the default class loader. To ensure that SomeClass
can operate properly, it has to also ensure that all the other classes that it imports (including test.Test1
) are also loaded.
The problem is, since test.Test1
isn't on the classpath, the default class loader can't resolve it, hence the error. test.Test1
is not resolvable until after you manually load it with your custom loader, which occurs after the initial class load from the class path (when the application is actually run by the JVM).
This is probably not an easy thing to fix. Probably the easiest approach is to make test.Test1
implement some interface (say Test
) which is on the classpath. Then, in SomeClass
you can import Test
and use Test
references rather than test.Test1
references to refer to objects of your dynamically loaded class.
Upvotes: 1