What you describe should not be allowed.
The uses directive on the export of org.slf4j.impl from ch.qos.logback.slf4j
should not allow bundle slf4j.api (id=927) from wiring to the logback version.
Running the osgi> command 'bundle 927' should give you the packages
that bundle 927 is wired to. That should tell us if it really is
wired to the one from logback which is being hosted by orbit slf4j bundle.
Your analysis sounds correct for the IncombatibleClassChangeError,
but I don't understand how it is getting wired to the logback version of
the impl package.
Andreas Sewe <andreas.sewe@xxxxxxxxxxxxxx>
mailing list <equinox-dev@xxxxxxxxxxx>
10/07/2014 11:22 AM
Question about uses constraints in a constellation
I've come across a weird constellation involving uses constraints and
fragments and need an OSGi expert to double-check my logic. I hope this
is the right mailing list. If not, please accept my apologies.
I've just had fun making sense of the following bug report  (which
exhibits similar symptoms as these other reports [2,3,4]).
> java.lang.IncompatibleClassChangeError: Class ch.qos.logback.classic.LoggerContext
does not implement the requested interface org.slf4j.ILoggerFactory
> at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:270)
> at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:281)
The situation in which this occurs seems to be like this:
> osgi> ss slf4j
> "Framework is launched."
> id State Bundle
> 5 RESOLVED ch.qos.logback.slf4j_1.0.7.v20121108-1250
> 836 RESOLVED org.slf4j.api_1.7.2.v20121108-1250
> 908 RESOLVED jcl.over.slf4j_1.7.2
> 924 ACTIVE org.sonar.ide.eclipse.slf4j.pde_126.96.36.19940404-0949-RELEASE
> 927 RESOLVED slf4j.api_1.7.2
So, we have two SLF4J API bundles (836, 927). The former comes from
Orbit, the latter is shipped with the SonarQube Eclipse plugin. The
plugin from Orbit uses a neat implementation trick where a fragment (5)
is used to give the org.slf4j.api bundle (836) access to the package
org.slf4j.impl and thereby make it use Logback as an API implementation.
Now, my explanation for the IncompatibleClassChangeError is that whoever
calls org.slf4j.LoggerFactory.getLogger(...) is for some reason wired to
the slf4j.api (927) shipped with SonarQube. Now, that bundle's manifest
looks like this:
And here's where I think things can go wrong. Instead of getting wired
to the org.slf4j.impl package from org.sonar.ide.eclipse.slf4j.pde
(924), the slf4j.api bundle (927) gets wired to the org.slf4j.api bundle
(836) + ch.qos.logback.slf4j fragment (5) from Orbit. And the
ch.qos.logback.classic.LoggerContext from the fragment of course
implements the interface org.slf4j.ILoggerFactory exported from its host
bundle, not from the conflicting slf4j.api bundle (927). Hence the
So far for my theory. There is one thing, however, that puzzles me. The
fragment dutifully exports org.slf4j.impl with a uses constraint:
Shouldn't this constraint prevent the slf4j.api bundle (927) from wiring
to the org.slf4j.api bundle (836) + fragment in the first place? Or does
the fact that the slf4j.api bundle (927) itself *defines* the org.slf4j
package (rather importing another, conflicting instance) does not
constitute a *use* that would violate the constraint and hence prevent
the two bundles from being wired together?
Can someone more knowledgeable of OSGi please explain to me what's going
on? Is this a constellation where uses constraints just don't help? Or
is my theory simply wrong and there exists another possible wiring that
explains the IncompatibleClassChangeError?
Managing Director: Dr. Marcel Bruch
Handelsregister: Darmstadt HRB 91940
equinox-dev mailing list
To change your delivery options, retrieve your password, or unsubscribe
from this list, visit https://dev.eclipse.org/mailman/listinfo/equinox-dev