¡Hola a todos y gracias por la atención! Tengo un problema que debe ser fácil y obvio, pero estoy atascado.¿Cómo poner Custom ClassLoader para usar?
Deseo entregar clases de Java creadas dinámicamente para ser utilizadas por una biblioteca de terceros a través de un ClassLoader personalizado.
Ahora mi problema es: ¿cómo puedo configurar mi ClassLoader personalizado para cargar estas clases cuando no las cargo directamente?
Pensé que cuando usaba mi ClassLoader para cargar cierta clase, se convertía en el ClassLoader de esta clase, y todas las clases cargadas de esa clase se canalizarían a través de mi ClassLoader.
Creé un ClassLoader personalizado, siguiendo este tutorial oficial: http://java.sun.com/developer/onlineTraining/Security/Fundamentals/magercises/ClassLoader/help.html.
public class DynamicClassloader extends ClassLoader {
private Map<String, Class<?>> classesMap = new HashMap<String, Class<?>>();
public DynamicClassloader(ClassLoader parent) {
// Also tried super(parent);
super(sun.misc.Launcher.getLauncher().getClassLoader());
}
// Adding dynamically created classes
public void defineClass(String name, Class<?> clazz) {
classesMap.put(name, clazz);
}
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
// load from parent
Class<?> result = findLoadedClass(name);
if (result != null) {
return result;
}
try {
result = findSystemClass(name);
} catch (Exception e) {
// Ignore these
}
if (result != null) {
return result;
}
result = classesMap.get(name);
if (result == null) {
throw new ClassNotFoundException(name);
}
return result;
}
}
que quería utilizar esto en otro lugar en el código de esa manera:
ClassLoader thisClassLoader = this.getClass().getClassLoader();
((DynamicClassloader) thisClassLoader).defineClass(className, dynClass);
Ahora mi problema es que cuando llamo findSystemClass(name)
de la tercera clase de biblioteca de partido, el cargador de clases padre encuentra esta clase (porque está en la ruta de clases) y se convierte en su ClassLoader. Y dado que el ClassLoader padre no sabe acerca de mi ClassLoader personalizado, está efectivamente fuera de uso y this.getClass().getClassLoader()
no se puede convertir a DynamicClassLoader.
Otro enfoque sería configurar mi ClassLoader para que sea el sistema ClassLoader a través del argumento de JVM -Djava.system.class.loader=my.DynamicClassloader
. Pero eso me da un StackOverflowError:
...
at de.unisaarland.cs.st.DynamicClassloader.findClass(DynamicClassloader.java:39)
at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
at java.lang.ClassLoader.loadClass(ClassLoader.java:248)
at java.lang.ClassLoader.findSystemClass(ClassLoader.java:916)
at de.unisaarland.cs.st.DynamicClassloader.findClass(DynamicClassloader.java:39)
...
Esto debe ser muy fácil de hacer, pero ahora estoy sin ideas ... cualquier ayuda es muy apreciada!
relacionada a http://stackoverflow.com/questions/6366288/how-to-change-default-class-loader-in-java, http://stackoverflow.com/questions/5380275/replacement-system-classloader-for-classes-in-jars-containing-jars/19128964 # 191 28964 y http: // stackoverflow.com/questions/5380275/replacement-system-classloader-for-classes-in-jar-containing-jar. – roesslerj