2011-01-28 15 views
7

Estoy trabajando en un plugin de Eclipse que necesita clases que no se conocen en tiempo de compilación. Las clases se envían a través de la red en archivos jar. Me gustaría cargar dinámicamente esas clases en tiempo de ejecución.Añadiendo jar a un plugin de Eclipse en tiempo de ejecución

He intentado el enfoque que aparece aquí: http://blog.imaginea.com/making-applications-work-together-in-eclipse/

Por desgracia, no tiene el efecto deseado. Mientras que las clases se cargan, no puedo usarlas fuera de la función donde las cargué. Supongo que tiene algo que ver con el uso de cargadores de diferentes clases.

Cualquier ayuda es apreciada. Incluso si me dices, eso no es posible, así que sé que no tengo que buscar más.

Respuesta

5

Si haces esos frascos en paquetes OSGi (es decir, darles un MANIFIEST.MF), entonces se puede instálelos dinámicamente en el tiempo de ejecución de OSGi.

Si añade un activador de paquete a su plugin, a continuación, se pueden almacenar los org.osgi.framework.BundleContext y entonces usted puede hacer:

Bundle [] newBundle = new Bundle[] { bundleContext.install(location, newJarInputStream) }; 
    packageAdmin.refreshPackages(newBundle); 
    packageAdmin.resolveBundles(newBundle); 

packageAdmin es una instancia de org.osgi.service. packageAdmin.PackageAdmin que es un servicio que puede adquirir con BundleContext#getService

Las nuevas jarras pueden ser paquetes completos por derecho propio, o también pueden ser paquetes de fragmentos que tienen su complemento como su host. Si son fragmentos de su paquete, entonces su paquete (BundleContext#getBundle()) deberá incluirse en el conjunto pasado a refreshPackages y resolveresBundles.

(classloading EDIT) Class.forName de su código del plugin sólo encontrará clases en los paquetes recién instalados si su plugin tiene dependencias que serán satisfechas por los nuevos paquetes, una vez que se resuelvan.

  • Una forma de hacer esto sería un Import-Package opcional en el manifiesto de su complemento. En este caso, su complemento deberá incluirse en la matriz pasada al refreshPackages.
  • Otra opción sería usar una declaración DynamicImport-Package en el manifiesto de su complemento. Las importaciones dinámicas se resuelven durante la carga de clase

Otra opción es utilizar Bundle.loadClass (en lugar de Class.forName) en los objetos del paquete para sus paquetes recién instalados. Esto utiliza el cargador de clases del nuevo paquete, por lo que su plugin no necesita tener una dependencia en los nuevos paquetes.

+0

Esto suena como la forma correcta de hacerlo (+1) –

+0

Gracias. Eso suena como un buen enfoque. Aunque todavía tengo algunos problemas. Logré cargar el paquete. Pero Class.forName ("MyClass") aún arroja una excepción ClassNotFound. Especifiqué el paquete, que contiene la clase en la declaración de exportación del manifiesto – Maria

+0

Edité la respuesta original con más detalles sobre la carga de clases una vez que los paquetes están instalados. –

1

poco hice esto para un plugin para Eclipse:

Aquí está el código saliente

URL[] urls = new URL[]{ new URL("jar", "", "file:" + jarFile.getAbsolutePath() + "!/")}; 
URLClassLoader cl = URLClassLoader.newInstance(urls, this.getClass().getClassLoader()); 
Class<?> loadedClass = cl.loadClass("com.whatever.SomeClass"); 
Cuestiones relacionadas