[slf4j-dev] [Bug 75] Cyclic dependency in OSGi

bugzilla-daemon at pixie.qos.ch bugzilla-daemon at pixie.qos.ch
Thu Mar 26 14:57:38 CET 2009


http://bugzilla.slf4j.org/show_bug.cgi?id=75


Marcel Hoetter <Marcel.Hoetter at berner-mattner.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |Marcel.Hoetter at berner-
                   |                            |mattner.com




--- Comment #6 from Marcel Hoetter <Marcel.Hoetter at berner-mattner.com>  2009-03-26 14:57:37 ---
Hi Ceki!

First off all: I appreciate your work and was positively suprised that SLF4J as
well as Logback are packaged as OSGi bundles.

However, the latest version of SLF4J (1.5.6) and Logback (0.9.15) still
(again?) suffer from the cyclic dependency problem. This is especially
problematic with Eclipse (Equinox cannot resolve and PDE cannot export plug-ins
with cyclic dependencies).

I second Mirko's opinion (comment #1) that a fragment solution is suboptimal.
The main reason is that the OSGi package resolving process favours packages
that are found inside a host bundle (in the bundle's classpath) over packages
provided by fragments (see OSGi core specification section 3.8.4). One may work
around this circumstance by exporting the packge in the fragment and importing
it in the host bundle, but this is IMHO a rather twisted solution.

The "optional import" suggested in the original comment of this bug is also not
really helpful, as it does not resolve the problem with PDE.

It seems that it is difficult to find a "good" way to define SLF4J package
dependecies for OSGi due to the statical wiring of SLF4J API and
implementations. However, after working through the OSGi spec, i think i found
an acceptable solution:

The org.slf4j.api bundle should not only import, but alo export the
org.slf4j.impl package. This would resolve the cyclic dependecy problem, as the
bundle can provide the impl-package to itself.

The Manifest.mf of the org.slf4j.api bundle may then look like this:

Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: SLF4J Api Plug-in
Bundle-SymbolicName: org.slf4j.api
Bundle-Version: 1.5.6
Bundle-Vendor: org.slf4j
Bundle-RequiredExecutionEnvironment: J2SE-1.5
Bundle-ActivationPolicy: lazy
Export-Package:
org.slf4j;version="1.5.6";uses:="org.slf4j.spi,org.slf4j.helpers",
 org.slf4j.helpers;version="1.5.6";uses:="org.slf4j.spi,org.slf4j",
 org.slf4j.impl;version="1.5.6",
 org.slf4j.spi;version="1.5.6";uses:="org.slf4j"
Import-Package: org.slf4j.impl;version="[1.5.6,1.5.7)"

The imported org.slf4j.impl package features a rather strict version number
range. This should be done as SLF4J packages with different minor numbers are
incompatible (according to the FAQ).

Exported packages have to provide version numbers and should feature the uses
directive (prevents ClassCastExceptions in an environment where multiple
versions of SLF4J are present; see OSGi spec section 3.6.4).

Other bundles (e.g. the SLF4J Log4J adapter bundle) may then export the
org.slf4j.impl package as well to provide their actual implementation. To
ensure that the OSGi framework always selects the impl-package from an
implementation bundle, one has to add a version number to the export that is
higher that that provided in the org.slf4j.api manifest. This can easily be
done by adding an arbitray qualifier to the version number. (In this case, OSGi
will then always pick the higher version of the package; see OSGi spec section
3.7)

In the case of the SLF4J Log4J adapter bundle, the Manifest.mf could then look
like this:

Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: SLF4J Log4j12 Plug-in
Bundle-SymbolicName: org.slf4j.log4j12
Bundle-Version: 1.5.6
Bundle-Vendor: org.slf4j
Bundle-RequiredExecutionEnvironment: J2SE-1.5
Import-Package: org.apache.log4j;version="[1.2.13,1.3)",
 org.slf4j;version="[1.5.6,1.5.7)",
 org.slf4j.helpers;version="[1.5.6,1.5.7)",
 org.slf4j.spi;version="[1.5.6,1.5.7)"
Export-Package: org.slf4j.impl;version="1.5.6.impl";
  uses:="org.slf4j.spi,
   org.apache.log4j,
   org.slf4j.helpers,
   org.slf4j"

Additional benefits:
-the "higher" version number would also imply that the packages have a
different content (what in fact is the case)
-the bundle ids can be selected arbirarily (this is not the case with the
fragment-approach, as fragments are bound to their host via the host bundle's
id)

I hope this will help you to modify the SLF4J and Logback bundles so they can
be used with Eclipse out of the box.

If you have any other questions about this topic, i will gladly (try to ;-)
answer them.


Greetings,

Marcel


-- 
Configure bugmail: http://bugzilla.slf4j.org/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are the assignee for the bug.



More information about the slf4j-dev mailing list