2012-03-13 21 views
5

Tengo un pequeño problema. Aprendo SE de Java y encuentro ClassLoader. Intento usarlo en el siguiente código: Estoy tratando de usar URLClassLoader para cargar dinámicamente una clase en tiempo de ejecución.Ejemplo de Java con ClassLoader

URLClassLoader urlcl = new URLClassLoader(new URL[] {new URL("file:///I:/Studia/PW/Sem6/_repozytorium/workspace/Test/testJavaLoader.jar")}); 
Class<?> classS = urlcl.loadClass("michal.collection.Stack"); 
for(Method field: classS.getMethods()) { 
    System.out.println(field.getName()); 
} 
Object object = classS.newInstance(); 
michal.collection.Stack new_name = (michal.collection.Stack) object; 

La máquina virtual de Java no me ve la clase, y me da la siguiente excepción:

Exception in thread "main" java.lang.Error: Unresolved compilation problems: michal cannot be resolved to a type michal cannot be resolved to a type at Main.main(Main.java:62) 

¿Sabe cómo puedo solucionar este problema?

+0

¿Puedes publicar la excepción y el seguimiento de la pila que obtienes? – Shaunak

+0

Por supuesto: Excepción en el hilo java.lang.Error "principal": problemas de compilación sin resolver: \t Michal no se puede resolver a un tipo \t Michal no se pueden resolver a un tipo \t en Main.main (Main.java: 62) –

Respuesta

4
Class<?> classS = urlcl.loadClass("michal.collection.Stack"); 
[...] 
Object object = classS.newInstance(); 
michal.collection.Stack new_name = (michal.collection.Stack) object; 

Así que está intentando cargar dinámicamente una clase y luego se refiere estáticamente a ella. Si ya puede vincular estáticamente a él, se carga y no puede volver a cargarlo. Tendrá que acceder a los métodos por reflexión.

Lo que normalmente haría es que la clase cargada implemente una interfaz del cargador de clases principal. Después de crear una instancia (generalmente solo una instancia), puede consultarla a través de una referencia con un tipo de interfaz.

public interface Stack { 
    [...] 
} 
[...] 
    URLClassLoader urlcl = URLClassLoader.newInstance(new URL[] { 
     new URL(
      "file:///I:/Studia/PW/Sem6/_repozytorium/workspace/Test/testJavaLoader.jar" 
     ) 
    }); 
    Class<?> clazz = urlcl.loadClass("michal.collection.StackImpl"); 
    Class<? extends Stack> stackClass = clazz.asSubclass(Stack.class); 
    Constructor<? extends Stack> ctor = stackClass.getConstructor(); 
    Stack stack = ctor.newInstance(); 

(Usual desbordamiento de pila Aviso Legal no tanto como la compilación.)

Usted tendrá que añadir gastos de envío al gusto de error. URLClassLoader.newInstance agrega un poco de refinamiento al URLClassLoader. Class.newInstance ha roto completamente el manejo de excepciones y debe evitarse.

+0

Entonces, ¿cómo puedo usar el método de esta clase? –

+0

@ user1267483 Debería crear una interfaz en el proyecto que está utilizando URLClassloader para Stack, que su michal.collection.Stack implementa. –

+0

@ user1267483 Tenga en cuenta que he cambiado el nombre de 'Stack' por' StackImpl' (no es el mejor nombre, pero es convencional), y presenté una nueva interfaz, 'Stack'. –

0

No se puede hacer referencia al tipo cargado dinámicamente por nombre en el código, ya que esto debe resolverse en tiempo de compilación. Tendrá que utilizar la función newInstance() del objeto Class que obtiene de loadClass().

+1

El OP usa 'Class.newInstance' en el objeto' Class' de 'loadClass'. –

0

Las respuestas anteriores son incorrectas, no entienden el problema de raíz. Tu principal se refiere a la clase Stack que fue cargada por un cargador de clases. Tu urlclassloader está intentando cargar una clase con el mismo nombre. No puede convertir el cargado a lo referido porque no son lo mismo, pertenecen a diferentes cargadores de clase. Puede imprimir el código de cada uno para ver que son diferentes. Una prueba de igualdad también mostrará que las referencias de clase son diferentes. Su problema probablemente se deba a que se pueden encontrar las clases dependientes referenciadas por sstack, que se mostrarán en NoClassDefErrors, etc. Su principal probablemente fallará con una excepción de excepción de clase.