java - poner - ¿Cómo usar URLClassLoader para cargar un archivo*.class?
set title java (4)
De los Javadocs para el URLClassLoader(URL[])
:
Construye un nuevo URLClassLoader para las URL especificadas utilizando la delegación padre principal ClassLoader. Las URL se buscarán en el orden especificado para las clases y recursos después de la primera búsqueda en el cargador de clases padre. Cualquier URL que termine con un ''/'' se supone que se refiere a un directorio. De lo contrario, se supone que la URL hace referencia a un archivo JAR que se descargará y abrirá según sea necesario.
Así que tienes dos opciones:
- Consulte el directorio en el que se encuentra el archivo .class
- Coloque el archivo .class en un JAR y refiérase a ese
(1) es más fácil en este caso, pero (2) puede ser útil si está utilizando recursos de red.
Estoy jugando con Reflection y pensé en hacer algo que cargue una clase e imprima los nombres de todos los campos de la clase. He hecho un pequeño tipo de clase de mundo de hola para tener algo que inspeccionar:
kent@rat:~/eclipsews/SmallExample/bin$ ls
IndependentClass.class
kent@rat:~/eclipsews/SmallExample/bin$ java IndependentClass
Hello! Goodbye!
kent@rat:~/eclipsews/SmallExample/bin$ pwd
/home/kent/eclipsews/SmallExample/bin
kent@rat:~/eclipsews/SmallExample/bin$
En base a lo anterior, saco dos conclusiones:
- Existe en /home/kent/eclipsews/SmallExample/bin/IndependentClass.class
- ¡Funciona! (Por lo tanto, debe ser un archivo .class adecuado que pueda cargar un cargador de clases)
Luego se marca el código que debe usar Reflection: (La línea que causa una excepción)
import java.lang.reflect.Field;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
public class InspectClass {
@SuppressWarnings("unchecked")
public static void main(String[] args) throws ClassNotFoundException, MalformedURLException {
URL classUrl;
classUrl = new URL("file:///home/kent/eclipsews/SmallExample/bin/IndependentClass.class");
URL[] classUrls = { classUrl };
URLClassLoader ucl = new URLClassLoader(classUrls);
Class c = ucl.loadClass("IndependentClass"); // LINE 14
for(Field f: c.getDeclaredFields()) {
System.out.println("Field name" + f.getName());
}
}
}
Pero cuando lo ejecuto, obtengo:
Exception in thread "main" java.lang.ClassNotFoundException: IndependentClass
at java.net.URLClassLoader$1.run(URLClassLoader.java:200)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
at java.lang.ClassLoader.loadClass(ClassLoader.java:251)
at InspectClass.main(InspectClass.java:14)
Mis preguntas:
- ¿Qué estoy haciendo mal arriba? ¿Cómo lo arreglo?
- ¿Hay alguna forma de cargar varios archivos de clase e iterar sobre ellos?
Debe cargar la clase dando el nombre de clase completo con el nombre de clase con su ruta de paquete como,
Class c = ucl.loadClass("com.mypackage.IndependentClass");
Debe proporcionar los directorios o los archivos jar que contienen sus archivos .class al URLClassLoader:
classUrl = new URL("file:///home/kent/eclipsews/SmallExample/bin/");
Y sí, puedes cargar tantas clases como quieras
Estaba teniendo un problema similar, pero mi archivo de clase residía dentro de un paquete llamado "customElements". En tales escenarios, la URL debe construirse hasta la carpeta justo arriba del paquete raíz y en el método de carga se debe pasar el nombre completo de la clase, incluido el paquete. Por ejemplo, en mi caso; La URL era como:
File customElementsDir = new File("D:/My Space");
//File customElementsDir = new File("D://customElements");
URL[] urls = null;
try {
URL url = customElementsDir.toURI().toURL();
urls = new URL[] { url };
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Y la carga real fue como:
clazz = childFirstClassLoader
.loadClass("customElements.CustomLoadableClass");
Donde childFirstClassLoader es mi cargador de clases.