2011-06-23 6 views
6

Estoy en el proceso de refactorizar una aplicación Java para usar OSGi. Una característica de la aplicación es la compilación de Java sobre la marcha utilizando javax.tools.JavaCompiler. En la aplicación original, este proceso funcionó alimentando al compilador el classpath existente, como tal.Uso de JavaCompiler en un OSGi Bundle

JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); 
String[] options = {"-classpath", System.getProperty("java.class.path")}; 
DiagnosticListener<JavaFileObject> listener = new DiagnosticListener<JavaFileObject>() {...}; 
StandardJavaFileManager fileManager = compiler.getStandardFileManager(listener, null, null); 
Iterable<? extends JavaFileObject> fileObjects = fileManager.getFileObjects(sourceFile); 
CompilationTask task = compiler.getTask(null, fileManager, listener, Arrays.asList(options), null, fileObjects); 
task.call(); 

Sin embargo, esto no va a trabajar en un paquete OSGi ya que la ruta de clase ya no contiene los caminos necesarios. En la versión OSGi refactorizada de la aplicación, el compilador necesita acceso a las clases que están dentro del mismo paquete que el código anterior, así como las clases de otros paquetes. ¿Cómo hago que el compilador conozca estas clases?

he pensado en dos soluciones posibles:

  1. Dale el compilador el cargador de clases utilizado por el paquete que contiene el código anterior ya que es consciente de todas las clases necesarias. Sin embargo, esto no parece una solución viable de lo que he leído here y here.
  2. Construya el classpath usando las ubicaciones físicas de los paquetes instalados. Miré org.osgi.framework.Bundle.getLocation() pero no estoy seguro de si esta sería una solución confiable. Las rutas que obtengo (al menos cuando se implementan en Eclipse) son relativas y no estoy seguro de si serían seguras para usar en todas las plataformas y situaciones.

¿La opción dos anterior parece posible? ¿Hay una mejor solución?

+0

Una nota más: he visto un enfoque [aquí] (http://blog.linkedin.com/2008/06/12/osgi-at-linkedin-java-compilation-in-osgi/) que aparece para trabajar, pero depende de las clases internas de JDT. Por lo que he leído, esta no es una buena práctica. –

+0

¿Alguien tiene alguna idea ...? –

Respuesta

3

He creado un ejemplo de trabajo en GitHub.

No es la opción 1 o 2, crea un JavaFileManager personalizado que examina todos los paquetes y recupera sus recursos.

Cosas a tener en cuenta:

  • Utiliza la API JSR 199 compilador, pero sólo funciona en el compilador OpenJDK/Sol, el compilador Eclipse JDT parece roto en este sentido.
  • Solo he probado en Equinox, no he usado ningún código específico de Equinox, por lo que debería funcionar en otras implementaciones.
  • No está optimizado, por lo que puede ser lento y/o tener mucha memoria.
  • Registra un detector de paquetes por lo que vaciará su caché de clases cuando un paquete que ofrece un determinado paquete resuelva o resuelva
  • No es muy determinista para los paquetes divididos, creo.
  • Se utiliza la API BundleWiring, que se introdujo en OSGi 4.3, por lo que no va a funcionar en los más antiguos implementaciones OSGi de OSGi (Karaf 2.x por ejemplo)

Debo mencionar Technology Excruciation, su ejemplo ayudó yo a lo largo de tremendamente.

Cuestiones relacionadas