Pregunta

Estoy escribiendo una biblioteca donde dejo que la gente proporcione implementaciones de ciertas interfaces que utilizan un marco plug-in (es JPF si está familiarizado). Los plugins no se almacenan en la ruta de clase. El marco me da un cargador de clases para cada plugin, por lo que cuando se solicita la aplicación denominada "MyImpl" de la interfaz "MyInterface", que se puede encontrar el plugin correcto, y luego usar cargador de clases de ese plugin para cargar la clase, de la que puede hacer que una instancia si sé algo sobre el constructor. Hasta aquí todo bien.

Sin embargo, ahora tengo un caso en el que tengo que llamar a un método que sólo está disponible en esa aplicación en particular. Por lo tanto, hay dos maneras en que podría tratar de hacer esto:

Método 1:

// Makes sure that MyImpl has been loaded, using the custom classloader
Plugins.getClass(MyInterface.class, "MyImpl");
// This line will not compile because MyImpl is not available at build time
MyImpl foo = new MyImpl();
// If I could get this far, this line would work:
foo.methodOnlyInMyImpl();

Método 2:

// This call will get an instance of MyImpl (already written and tested)
MyInterface foo = Plugins.getInstance(MyInterface.class, "MyImpl");
// Compiler error because there is no MyInterface.methodOnlyInMyImpl method.
foo.methodOnlyInMyImpl()

Método 1 es el más limpio de los dos, ya que es más similar a cómo se escribe el código si la clase eran "normales" y no es accesible a través de un plugin. Sin embargo, ni compila.

Opciones que he encontrado hasta el momento:
A. Utilice el método 2, pero el uso de reflexión para hacer la llamada al método methodOnlyInMyImpl (por favor, no!)
B. Lugar de las clases de plugin en la trayectoria de la estructura y luego utilizar el método 1, que compile. (Mi favorito actual)
C. B + cuando se instalan plugins, copiar los archivos de clase a otro directorio que está en la ruta de clase, por lo que el cargador de clases sistema puede cargarlos (provoca otros problemas)

Por lo tanto, mis preguntas son:

  1. ¿Me estoy perdiendo otra idea que es mejor?
  2. Si hago B, voy a tener problemas en tiempo de ejecución? Después de todo, la clase utilizando MyImpl presumiblemente se han cargado mediante el cargador de clases del sistema. Así, tan pronto como se ve MyImpl foo, no se intentará cargar MyImpl usando el cargador de clases del sistema, que se producirá un error (aunque la llamada Plugins.newInstance proporcionaría una instancia de MyImpl)?
¿Fue útil?

Solución

En primer lugar, ¿qué ventaja se obtiene a partir del mecanismo plugin, cuando se necesita para poner en práctica en contra de la implementación real? El plugin debe implementar una interfaz y se puede utilizar la aplicación a través de la interfaz.

No estoy fimilar con JPF, pero las clases de Java no son compatibles cuando se carga por diferentes cargadores de clases. Pero hay dos maneras posibles:

  1. La interfaz está en el cargador de clases, el cargador de clase plugin tiene su cargador de clases como padre, por lo que su interfaz es la misma que la suya. El código de 2 debe trabajar con esto, cuando el método se decladed en la interfaz.

  2. Puede utilizar la serialización. Esta es una forma limitada objetos más transferencia de los datos útiles entre los cargadores de clases independientes. Necesitaba usar esto para contexto cruz despachar con parámetro de petición entre dos webapps.

Otros consejos

Hay una biblioteca llamada Transloader que se ha mencionado en una pregunta anterior. Aquí está la dirección URL de la fuente: http://code.google.com/p/transloader/.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top