2010-06-22 12 views
7

Estamos ampliando nuestra aplicación java para admitir complementos. Parte de eso incluye mantener los complementos aislados de nuestras propias clases, por lo que cada complemento vivirá en su propio cargador de clases.Implementación de un cargador de clase de filtro

También planeamos proporcionar a los complementos un marco de Java para trabajar, por lo que deberá estar expuesto a los complementos. Este marco de Java también contiene clases que deberán ser accesibles desde nuestro propio código de Java, por lo tanto, también deberá ser accesible para nuestro propio código de Java.

El problema es que si el framework java vive en el cargador de clases del sistema (donde vive nuestro propio código java), no podemos dar a los plugins el aislamiento que queremos. Si optamos por separar el marco java en un cargador de clases diferente y usamos ese como el padre del cargador de clases de los complementos, el marco java no será visible para nuestras propias clases.

La solución actual que tenía en mente era implementar un cargador de clase de filtrado. El framework java vivirá en el cargador de clases del sistema, pero este cargador de clases filtrará todo desde el cargador de clases del sistema, excepto el marco java y usaré este cargador de clases como el cargador de clases padre de los complementos.

Aquí hay una aplicación aproximada de ella:

public class FilteringClassLoader extends ClassLoader { 
    private URLClassLoader _internalLoader; 

    public FilteringClassLoader(ClassLoader parent) { 
     super(parent); 

     // load our java framework to this class loader 
     _internalLoader = new URLClassLoader(...) 
    } 

    public Class<?> loadClass(String name) throws ClassNotFoundException { 
     // first, try to load from our internal class loader 
     // that only sees the java framework if that works, load the class 
     // from the system class loader and return that. otherwise, the class 
     // should be filtered out and the call to loadClass will throw as expected 
     _internalLoader.loadClass(name); 

     Class<?> retClazz = super.loadClass(name); 

     return retClazz; 
    } 
} 

Sin embargo, esto tiene varios problemas de la manera que lo veo:

  1. El uso de un URLClassLoader separado, sólo para ver si la clase debe ser filtrada se siente como un truco para mí.
  2. Cuando un complemento carga una clase, ese cargador de clase clase padre será el cargador de clases del sistema, lo que obviamente frustra todo el propósito de lo que estoy tratando de lograr.

¿Cómo resuelves este tipo de problema?

+0

¿Es esto diferente de las personas que introducen dependencias en los paquetes 'com.sun' en la biblioteca JRE? ¿O hay más restricciones? – McDowell

+0

no estoy seguro de lo que quiere decir –

Respuesta

2

¿Cómo resuelves este tipo de problema?

La OSGi Alliance ya lo hizo. El artículo de Wikipedia en el OSGi framework podría darle algunas ideas.

Es posible que desee consultar el código fuente de Eclipse, y ver cómo implementaron la carga plug-in.

+0

¿Tiene algún otro artículo de introducción bueno para OSGi? La entrada de wikipedia parece bastante densa. –

+0

Puedes probar esto: http://aneeshkumarkb.blogspot.com/ No soy un experto en OSGi, pero he codificado complementos de Eclipse. –

+0

Este es un recurso inestimable, ni siquiera he oído hablar de este proyecto antes (conversación de novatos de Java). Me parece que es un poco exagerado para nuestro pequeño marco de plugins, pero seguramente será útil en el futuro. –

2

Si elegimos separar el marco java en un cargador de clases diferente y usarlo como el padre del cargador de clases de los complementos, el marco java no será visible para nuestras propias clases.

Ponga su código en un cargador de clases que sea igual al cargador de clases del complemento, ambos con el cargador de clases de código de interfaz como primario.

+0

esta es una buena solución, siempre que el código de la API se pueda aislar por completo de cualquier dependencia del código de la aplicación principal. –

+0

También pensé en hacerlo de esta manera y, francamente, podría terminar eligiendo esta solución. Los problemas son: (1) lo que dijo 'matt b', aunque por ahora la interfaz del framework está completamente aislada. (2) tenemos algunos pedazos centrales de código que por alguna razón intentan acceder al cargador de clases del sistema directamente y si muevo todas las clases desde allí, podría romper una gran cantidad de código existente. Aunque tal vez sea hora de arreglar ese código. –

Cuestiones relacionadas