2009-12-08 23 views
46

OSGi permite determinar dependencias a través de Import-Package, que simplemente conecta un paquete (exportado desde cualquier paquete) y Require-Bundle, que se conecta hasta las exportaciones de un determinado paquete nombrado.¿Cuándo debería usar Import-Package y cuándo debería usar Require-Bundle?

Al construir una aplicación OSGi totalmente nueva, ¿qué enfoque debo usar para representar las dependencias? La mayoría de los paquetes serán internos, pero habrá algunas dependencias en paquetes externos (código abierto).

+4

De http://eclipsesource.com/blogs/2009/07/14/why-i-cant-recommend-using-import-package/: "Mira, Require-Bundle es algo que se ha usado en Eclipse para un tiempo, principalmente por razones de legado. No recomendamos su uso más. Import-Package es mejor si desea un acoplamiento más flexible entre los paquetes. Sin embargo, tenga en cuenta el dolor que pueden causar los paquetes divididos. " –

Respuesta

45

Creo que Require-Bundle es una cosa de Eclipse (que ahora ha sido incluida en la especificación OSGi para acomodar Eclipse). La forma "pura" de OSGi es usar Import-Package, ya que desacopla específicamente el paquete del paquete que lo proporciona. Debería declarar dependencias de la funcionalidad que necesita (la API de Java proporcionada por una determinada versión de un determinado paquete) en lugar de desde dónde proviene esa funcionalidad (lo cual no debería importarle). Esto mantiene la composición de los paquetes más flexible.

analogía de JavaScript: Esto es como detectar si un navegador web admite una determinada API, en vez de inferir de qué cadena de agente de usuario dice qué tipo de navegador es.

Peter Kriens de OSGi Alliance tiene más que decir sobre esto en el OSGi blog.

Probablemente el único caso en el que necesite utilizar Require-Bundle sea si tiene paquetes divididos, es decir, un paquete que se distribuye en múltiples paquetes. Los paquetes divididos son, por supuesto, muy desaconsejados.

+2

Tanto Require-Bundle como Import-Package se definen en la especificación OSGi; no hay una variante "pura" de los dos. – AlBlue

+2

@AlBlue: actualicé mi respuesta para dejar en claro que, aunque Require-Bundle está en la especificación, solo está ahí para compatibilidad con Eclipse. – Thilo

+6

Creo que Thilo tiene razón. Como Peter Kriens mencionó en el artículo: "Require-Bundle tiene un atractivo intuitivo que es difícil de negar". Pero está atando innecesariamente los paquetes. En el mundo de Java, lo compararía con IoC frente a las dependencias directas. Un ejemplo está en función del paquete 'commons-logging' frente al paquete de API' commons-logging'.En este último caso se puede cambiar fácilmente el paquete 'common-logging' con adaptador apropiado SLF4J paquete que también exporta el paquete de API Commons-logging'' y por lo tanto sin problemas crea un puente de 'Commons-logging' a SLF4J. –

3

Creo que Import-Package le da un acoplamiento más flexible y debe ser preferido. Lo uso cuando declaro dependencias en paquetes que no son de mi propiedad, como slf4j, y puedo intercambiar implementaciones como me gustaría. Utilizo Require-Bundle cuando la dependencia es algo sobre lo que tengo control, como mis propios paquetes, porque de todos modos cualquier cambio importante hubiera pasado por mí.

-1

No estoy convencido de que usar Import-Package sea mejor, porque mi expectativa predeterminada cuando trabajo con un paquete es trabajar con la API pública asociada. Por esa razón, Require-Bundle tiene más sentido.

+5

Esta afirmación no tiene sentido. Su justificación es la razón por la que usaría Import Package en lugar de Require-Bundle. Trate con la API pública y no se preocupe por quién la proporciona. No trabajas con el paquete, trabajas con la API. Para – Robin

13

Favorece Importar-Paquete sobre Require-Bundle.

Require-Bundle:

  • especifica el haz explícita (y versión) para su uso. Si un paquete requirde necesita ser refactorizado y un paquete trasladado a otro lugar, los dependientes necesitarán cambios en su MANIFEST.MF
  • le da acceso a TODAS las exportaciones del paquete, independientemente de lo que sean, independientemente de si las necesita . Si las piezas que no necesitan tener sus propias dependencias tendrá que aquellos a
  • paquetes pueden ser re-exportados
  • aunque desanimado, permite el uso de paquetes divididos, es decir: un paquete que se transmite a través de múltiples paquetes
  • se puede utilizar para dependencias sin código, por ejemplo: recursos, Ayuda, etc.

Import-Package:

  • más flojo de acoplamiento, sólo el paquete (y versión) se especifica y el tiempo de ejecución se encuentra el paquete requerido
  • implementaciones reales pueden swaped cabo
  • Dependiente el propietario del paquete puede mover paquetes a diferentes paquetes
  • Pero requiere que se mantengan más metadatos (es decir, cada nombre de paquete) en niveles más bajos de granularidad
+0

Import-Package, ¿y si se necesita una particular versión del paquete, pero el paquete en realidad tiene la versión en ella? AFAIK, los paquetes de Java no tienen versiones. –

0

Import-Package debería ser mejor, ya que, como se ha dicho anteriormente, puede mover un paquete de un paquete a otro sin cambiar MANIFIEST.MF de cliente existente

Pero ...

Hay una razón práctica para use Require-Bundle si está usando Eclipse para desarrollar sus paquetes:

Eclipse no usa paquetes como unidades de resolución. Utiliza paquetes. Es decir, si usa un paquete de un paquete, Eclipse compila su paquete sin informar ningún problema con el uso del resto de paquetes no importados de ese paquete.

Podría (usted es humano) pensar que todo está bien y cargar su paquete para la implementación pero ... su paquete se romperá en el tiempo de ejecución.

Estoy seguro porque este problema me ha sucedido (¡a mí!) Hoy.

La buena solución sería cambiar el contenedor Eclipse classpath, pero ... si esto no se va a hacer ... puede decidir evitar este tipo de problemas que requieren paquetes, en lugar de paquetes, pagando el precio mencionado (ningún movimiento de código compatible hacia atrás entre paquetes).

0

Avoid Import-Package. Como los paquetes proporcionan relaciones de muchos a muchos entre los paquetes, son propensos a ciclos de dependencia que son difíciles de detectar y evitar.

Require-Bundle, por otro lado, hace referencia a un solo paquete, haciendo que el gráfico de dependencia esté protegido de ciclos por una comprobación trivial de tiempo de compilación. Con Require-Bundle es mucho más fácil construir una arquitectura en capas con un nivel de abstracción aislado más bajo.

Cuestiones relacionadas