2010-05-04 15 views
7

Estoy usando OSGi para mi último proyecto en el trabajo, y es muy bonito en cuanto a modularidad y funcionalidad.¿Qué es un flujo de trabajo de desarrollo de OSGi razonable?

Pero no estoy contento con el flujo de trabajo de desarrollo. Eventualmente, planeo tener 30-50 paquetes separados, organizados en un gráfico de dependencia; supuestamente, esto es para lo que OSGi está diseñado. Pero no puedo encontrar una manera limpia de administrar dependencias en compilar tiempo.

Ejemplo: Tiene los paquetes A y B. B depende de los paquetes definidos en A. Cada paquete se desarrolla como un proyecto separado de Java.

Para compilar B, A tiene que estar en el classpath javac.

¿Te:

  1. referencia a la ubicación del sistema de archivos de proyecto en un script de compilación de B?
  2. ¿Compila A y tira el contenedor en el directorio lib de B?
  3. Confiar en función de "proyectos de referencia" de Eclipse y utilice siempre la ruta de clases de Eclipse para construir (uf)
  4. Usar un directorio "lib" común para todos los proyectos y volcar los frascos de haces allí después de la compilación?
  5. ¿Configurar un repositorio de paquetes, analizar el manifiesto del script de construcción y desplegar los paquetes necesarios del repositorio?

No. 5 suena más limpio, pero también como un montón de sobrecarga.

Respuesta

2

Básicamente, se puede utilizar:

  • dependencia de la fuente (con "proyectos referenciados" de Eclipse)
  • dependencia binaria (utilizando el frasco de paquete A)

Pero ya que la dependencia binario es mucho más limpio, también es el tipo de dependencia mejor administrada por un marco de administración de versiones como maven.
Y puede integrar maven en su proyecto Eclipse a través de m2eclipse.

El Maven plugin para utilizar sería entonces: maven-bundle-plugin, que se puede ver en acción en:

Considere este ejemplo más real usando la implementación del servicio de registro de Felix.
El proyecto de servicio de registro se compone de un único paquete: org.apache.felix.log.impl.
Tiene una dependencia en las interfaces OSGi centrales, así como una dependencia en las interfaces OSGi del compendio para las interfaces de servicio de registro específicas.El siguiente es el archivo de POM:

<project> 
    <modelVersion>4.0.0</modelVersion> 
    <groupId>org.apache.felix</groupId> 
    <artifactId>org.apache.felix.log</artifactId> 
    <packaging>bundle</packaging> 
    <name>Apache Felix Log Service</name> 
    <version>0.8.0-SNAPSHOT</version> 
    <description> 
    This bundle provides an implementation of the OSGi R4 Log service. 
    </description> 
    <dependencies> 
    <dependency> 
     <groupId>${pom.groupId}</groupId> 
     <artifactId>org.osgi.core</artifactId> 
     <version>0.8.0-incubator</version> 
    </dependency> 
    <dependency> 
     <groupId>${pom.groupId}</groupId> 
     <artifactId>org.osgi.compendium</artifactId> 
     <version>0.9.0-incubator-SNAPSHOT</version> 
    </dependency> 
    </dependencies> 
    <build> 
    <plugins> 
     <plugin> 
     <groupId>org.apache.felix</groupId> 
     <artifactId>maven-bundle-plugin</artifactId> 
     <extensions>true</extensions> 
     <configuration> 
      <instructions> 
      <Export-Package>org.osgi.service.log</Export-Package> 
      <Private-Package>org.apache.felix.log.impl</Private-Package> 
      <Bundle-SymbolicName>${pom.artifactId}</Bundle-SymbolicName> 
      <Bundle-Activator>${pom.artifactId}.impl.Activator</Bundle-Activator> 
      <Export-Service>org.osgi.service.log.LogService,org.osgi.service.log.LogReaderService</Export-Service> 
      </instructions> 
     </configuration> 
     </plugin> 
    </plugins> 
    </build> 
</project> 
+0

Las dependencias binarias son peligrosas para recomendar. Ayudé a un cliente la semana pasada a depurar un problema del cargador de clases provocado por tener 2 copias del mismo contenedor binario en 2 paquetes diferentes. Cuando intentaron pasar instancias de objetos desde el paquete binario de un paquete al otro, hubo una excepción de clase. Es mucho mejor utilizar los enunciados de paquete de importación/exportación como estaban destinados. En el caso del cliente, la solución consistía en hacer un paquete del binario que exportaba los paquetes requeridos. Luego, ambos paquetes de clientes importaron los paquetes que necesitaban del nuevo paquete. –

+0

Hm. Esperaba evitar Mavenizar todo el proyecto, pero es posible que no lo pueda evitar. – levand

+0

¿Tiene un seguimiento de esta pregunta, cómo lo manejó? Tengo un problema muy similar que resolví mediante la reinvención de la rueda Maven. Me costó un gran esfuerzo evitar usar Maven y finalmente terminé con una solución que era un subconjunto de Maven que eventualmente tendré que convertir a Maven. Cuanto más complejas sean las dependencias de un proyecto, más beneficios obtendrá Maven de alguien que realmente no le gusta la complejidad del mismo). – Chris

7

Mi empresa tiene más de 100 proyectos de paquete y utilizamos Eclipse para gestionar las dependencias. Sin embargo, no recomiendo el enfoque de "Complementos obligatorios" para administrar las dependencias. Su mejor apuesta es crear proyectos de complementos. Exporte solo los paquetes de cada proyecto que desee que sean visibles. Luego, en el lado de las importaciones hacer lo siguiente:

Abrir el editor de manifiesto

Ir a la pestaña dependencias En la parte inferior izquierda es una sección llamada "gestión automatizada de dependencias"

añadir cualquier plugins que el plugin actual depende de allí

Una vez que haya escrito el código, puede hacer clic en el enlace "agregar dependencias" en esa pestaña para calcular automáticamente los paquetes importados.

Si ejecuta desde Eclipse, esto se realiza automáticamente cuando se ejecuta.

Las ventajas de este enfoque es que sus paquetes integrados solo usan el mecanismo de importación/exportación del paquete definido por OSGi, a diferencia de algo de Eclipse.

Si desea obtener más información, le recomiendo ir a este sitio y solicitar el libro. Es excelente.

http://equinoxosgi.org/

+0

Esa es una solución mucho más práctica (que mi recomendación basada en maven), integrada con Eclipse PDE. +1 – VonC

2

Hay una sexta opción, que he utilizado para varios proyectos, que consiste en utilizar un solo proyecto Eclipse (no un proyecto de plug-in, pero sólo un proyecto Java ordinaria) y poner todo el código fuente ahí. Un archivo de compilación asociado con el proyecto simplemente compilará todo el código en una sola pasada y posteriormente creará paquetes de las clases compiladas (utilizando Bnd de Ant o de BndTools, que pronto se lanzará).

Esto tiene la desventaja de que no respeta la visibilidad durante el desarrollo y el tiempo de compilación, pero la ventaja es que es un modelo de desarrollo realmente simple que le ofrece tiempos de compilación e implementación muy rápidos.

5

Bueno, haz lo que deberías tener mucho tiempo antes, implementación separada y API ... ok, esto no siempre es tan fácil en los sistemas existentes, pero ese modelo tiene un gran impacto en tu inversión. Una vez que su API se encuentre en un paquete/jar por separado (mucho más estable) puede compilar los clientes y las implementaciones contra ese paquete/jar.

Una de las cualidades clave de un paquete exitoso es que hace tan pocas suposiciones sobre el mundo exterior como sea posible. Esto implica que no tiene que compilar contra los paquetes contra los que se ejecuta en tiempo de ejecución, prefiero esforzarme para no hacerlo. Solo debe compilar contra el conjunto mínimo de dependencias de paquetes. Si se hacen suposiciones, son explícitos como paquetes importados y el uso de servicios. Los sistemas OSGi bien diseñados intentan usar servicios para todas las comunicaciones entre paquetes. Este modelo no solo elimina los problemas de carga de clases, sino que también hace que su configuración de construcción esté más desacoplada.

Desafortunadamente, la mayoría del código está escrito como bibliotecas que tienen una interfaz bastante amplia porque codifican muchas de las funciones que los servicios proporcionan de fábrica, como Fábricas y Oyentes. Este código tiene una estrecha relación entre la implementación y API, por lo que debe tener el mismo en la ruta de clase durante la compilación y en OSGi. Una solución a este problema es incluir este tipo de código dentro del paquete que lo usa (pero asegúrese de que ningún objeto de esta biblioteca se filtre a otros paquetes). Un poco de consumo extra de memoria, pero te evita algunos dolores de cabeza.

Entonces, con OSGi, intente crear sistemas que dependan de los servicios y compilar contra su API de servicio, no un paquete de implementación.

Cuestiones relacionadas