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.
Tom From: Andreas Sewe <[email protected]> To: Equinox development mailing list <[email protected]> Date: 10/07/2014 11:22 AM Subject: [equinox-dev] Question about uses constraints in a constellation involving fragments Sent by: [email protected] Hi, 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 [1] (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 > Master=836 > 836 RESOLVED org.slf4j.api_1.7.2.v20121108-1250 > Fragments=5 > 908 RESOLVED jcl.over.slf4j_1.7.2 > 924 ACTIVE org.sonar.ide.eclipse.slf4j.pde_3.4.0.20140404-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. osgi> h 5 Bundle headers: Bundle-Localization = fragment Bundle-ManifestVersion = 2 Bundle-Name = Logback Native SLF4J Logger Module Bundle-RequiredExecutionEnvironment = J2SE-1.5,JavaSE-1.6,JavaSE-1.7 Bundle-SymbolicName = ch.qos.logback.slf4j Bundle-Vendor = Eclipse.org Bundle-Version = 1.0.7.v20121108-1250 Eclipse-SourceReferences = scm:cvs:pserver:dev.eclipse.org:/cvsroot/tools:org.eclipse.orbit/ch.qos.logback.slf4j;tag=v20121108-1250 Export-Package = org.slf4j.impl; uses:="org.slf4j.spi,ch.qos.logback.classic.util,org.slf4j.helpers,ch.qos.logback.classic,ch.qos.logback.core,ch.qos.logback.classic.selector,ch.qos.logback.core.joran.spi,org.slf4j,ch.qos.logback.core.util";version="1.7.2" Fragment-Host = org.slf4j.api;bundle-version="[1.7.2,1.7.3)" Manifest-Version = 1.0 Require-Bundle = ch.qos.logback.core;bundle-version="[1.0.7,1.0.8)",ch.qos.logback.classic;bundle-version="[1.0.7,1.0.8)" 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: > osgi> h 927 > Bundle headers: > Archiver-Version = Plexus Archiver > Build-Jdk = 1.6.0_23 > Built-By = ceki > Bundle-Description = The slf4j API > Bundle-ManifestVersion = 2 > Bundle-Name = slf4j-api > Bundle-RequiredExecutionEnvironment = J2SE-1.3 > Bundle-SymbolicName = slf4j.api > Bundle-Vendor = SLF4J.ORG > Bundle-Version = 1.7.2 > Created-By = Apache Maven > Export-Package = org.slf4j;version=1.7.2, org.slf4j.spi;version=1.7.2, org.slf4j.helpers;version=1.7.2 > Implementation-Title = slf4j-api > Implementation-Version = 1.7.2 > Import-Package = org.slf4j.impl;version=1.6.0 > Manifest-Version = 1.0 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 IncompatibleClassChangeError. So far for my theory. There is one thing, however, that puzzles me. The fragment dutifully exports org.slf4j.impl with a uses constraint: > org.slf4j.impl; uses:="...,org.slf4j,...";version="1.7.2" 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? Any help is greatly appreciated. Best wishes, Andreas [1] <https://bugs.eclipse.org/bugs/show_bug.cgi?id=446167> [2] < http://sonarqube.15.x6.nabble.com/SonarQube-Eclipse-3-4-0-not-compatible-with-Eclipse-Luna-4-4-0-td5026057.html > [3] <https://bugs.eclipse.org/bugs/show_bug.cgi?id=438161> [4] <https://issuetracker.springsource.com/browse/STS-1620> -- Codetrails GmbH The knowledge transfer company Robert-Bosch-Str. 7, 64293 Darmstadt Phone: +49-6151-276-7092 Mobile: +49-170-811-3791 http://www.codetrails.com/ Managing Director: Dr. Marcel Bruch Handelsregister: Darmstadt HRB 91940 _______________________________________________ equinox-dev mailing list [email protected] To change your delivery options, retrieve your password, or unsubscribe from this list, visit https://dev.eclipse.org/mailman/listinfo/equinox-dev
_______________________________________________ equinox-dev mailing list [email protected] To change your delivery options, retrieve your password, or unsubscribe from this list, visit https://dev.eclipse.org/mailman/listinfo/equinox-dev
