So, as I understand the situation you are describing, we have the following packages (abbreviated to save typing):

   * parsers - containing the Parser interface.
   * parsers.java - containing the Java Parser implementation.
   * parsers.cobol - containing the COBOL Parser implementation.

We can package this up in four ways:

  1. Three inter-dependent bundles:
        1. Bundle A containing and exporting parsers.
        2. Bundle B containing Java impl and importing parsers from A.
        3. Bundle C containing COBOL impl and importing parsers from A.
  2. Two inter-dependent bundles (the bundle exporting parsers could be
     reversed):
        1. Bundle A containing parsers and Java impl and exporting parsers.
        2. Bundle B containing COBOL impl and importing parsers from A.
  3. Two self-contained bundles:
        1. Bundle A containing parsers and Java impl and exporting parsers.
        2. Bundle B containing parsers and COBOL impl and exporting
           parsers.
  4. Two self-contained, but potentially inter-dependent bundles:
        1. Bundle A containing parsers and Java impl and
           exporting/importing parsers.
        2. Bundle B containing parsers and COBOL impl and
           exporting/import parsers.

(Note: Below you mention something about exporting parsers.java and/or parsers.cobol, but you should not need to export these since they are implementations of the well-known parsers.Parser API, so all collaboration should be through the public API.)

Given these four options, approach (1) is the most intuitive. The downside of approach (1) is that no implementations are ever self-contained, you always need to deploy multiple bundles to get your implementation to work.

Approach (2) is a variant of approach one where we make one of our impls self-contained, while the other one is not. This solution is not very good since it is asymmetric and the second bundle still requires the other impl to be present just to get the parsers package.

Approach (3) looks good at first blush, since both impls are self-contained. However, there is an issue in this approach. Since both bundles ONLY export parsers, their respective impls are using their own copies of the parsers.Parser class. As a result, if both are deployed at the same time, then clients will only be able to see one or the other impl, but not both, since a client cannot see two copies of the same class at the same time.

This leads to approach (4), which solves the issue in approach (3) by not only exporting the parsers package, but also importing it. Now both A and B are self-contained, so if they are deployed independently, they will work without needing any other bundles. However, if they are deployed at the same time, the OSGi framework will choose one copy of the parsers package and wire the other bundle to the selected package. Now a client will be compatible with both impls, since there is only one copy of the parsers package in use.

Importing and exporting the same package is not necessary at all if you are following approach (1), where you package your public API in a separate bundle. It is generally only useful when you package your public interface-based API with an implementation of it.

These are just rules of thumb, though. The ultimate rule to consider when exporting a package is, do you expect that someone else may also export the package and you might want to substitute their export for yours (typically because you want class space compatibility). If so, then you should also import your export. If not, then you should only export.

-> richard

Vinicius Carvalho wrote:
Hello there! I've got Hall's book, and even after reading section 2.4.3
where he explains why would one need to import and export a package I'm
still a bit confused.

A good explanation provided by him was " (...)common situation when
importing and exporting is useful is
when using an interface-based development approach. (...)" Well, this is
just my case :)

We are building an open source governance tool (we already have the product
on a locked non osgi architecture, we are just migrating and opening it to
the community), well we have several parsers (Java, COBOL, C#, C++, PHP ...)
and we would like to have our parsers to be implemented as bundles. So I
guess I'll have an interface: org.openspotlight.parsers.Parser which each
bundle must implement, so let's suppose I have two bundles (java and cobol)
I would export this packages:

Export-Package: org.openspotlight.parsers.java
.
.
.
Export-Package: org.openspotlight.parsers.cobol


Why would I need to add an import-package statement to my manifest as well?
Would it be a problem if I do not? Also We intend to use the parsers as
services, so on each bundle we add an activator to register the given
implementation using the general interface, I guess this is ok as well
right?

Best regards


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to