Expand my Community achievements bar.

Dive into Adobe Summit 2024! Explore curated list of AEM sessions & labs, register, connect with experts, ask questions, engage, and share insights. Don't miss the excitement.
SOLVED

OSGi bundle export conflicts

Avatar

Former Community Member

I have an OSGi bundle that is used to export a number of common classes that we want to manage for specific versions. It includes a simple bundle Activator class not unlike the one created by the archetype, lets say :-

import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.squeakysand.osgi.framework.BasicBundleActivator; public class Activator extends BasicBundleActivator { private static final Logger LOG = LoggerFactory.getLogger(Activator.class); public Activator() { super(LOG); } }

We can see that a static SLF4J Logger is created.The POM naturally contains a dependency for SLF4J :-

          <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.6.4</version>
        </dependency>

Initially I was using a later version of SLF4J (1.7.5) but noted that there is a standard OSGi bundle that is installed and this exports the 1.6.4 version and I encountered problems, so, for now I have kept to this same version.

I can successfully deploy my bundle and all dependencies are successfully resolved. However, when attempting to start the bundle the following exception occurs where this line suggests that there is a version conflict for the SLF4J LoggerFactory :-

resolved class, org/slf4j/impl/StaticLoggerBinder, have different Class objects for the type LoggerFactory

17.10.2013 16:09:45.046 *ERROR* [FelixDispatchQueue] com.mycompany.aem.support.aem-osgi-support FrameworkEvent ERROR (org.osgi.framework.BundleException: Activator start error in bundle com.mycompany.aem.support.aem-osgi-support [318].) org.osgi.framework.BundleException: Activator start error in bundle com.mycompany.aem.support.aem-osgi-support [318].
    at org.apache.felix.framework.Felix.activateBundle(Felix.java:2184)
    at org.apache.felix.framework.Felix.startBundle(Felix.java:2052)
    at org.apache.felix.framework.Felix.setActiveStartLevel(Felix.java:1279)
    at org.apache.felix.framework.FrameworkStartLevelImpl.run(FrameworkStartLevelImpl.java:304)
    at java.lang.Thread.run(Thread.java:724)
Caused by: java.lang.LinkageError: loader constraint violation: when resolving method "org.slf4j.impl.StaticLoggerBinder.getLoggerFactory()Lorg/slf4j/ILoggerFactory;" the class loader (instance of org/apache/felix/framework/BundleWiringImpl$BundleClassLoaderJava5) of the current class, org/slf4j/LoggerFactory, and the class loader (instance of org/apache/felix/framework/BundleWiringImpl$BundleClassLoaderJava5) for resolved class, org/slf4j/impl/StaticLoggerBinder, have different Class objects for the type LoggerFactory; used in the signature
    at org.slf4j.LoggerFactory.getILoggerFactory(LoggerFactory.java:284)
    at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:252)
    at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:265)
    at com.squeakysand.osgi.framework.BasicBundleActivator.<clinit>(BasicBundleActivator.java:33)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:526)
    at java.lang.Class.newInstance(Class.java:374)
    at org.apache.felix.framework.Felix.createBundleActivator(Felix.java:4318)
    at org.apache.felix.framework.Felix.activateBundle(Felix.java:2129)
    ... 4 more

If I don't declare the BundleActivator in the POM I can successfully start the bundle :-

<Bundle-Activator>com.mycompany.aem.support.wrap3rdpartylib.osgi.Activator</Bundle-Activator>

... , but although in this case that's OK as a workaround, I really want to get to the bottom of the problem and fix it, so that I don't hit the same thing again when I do have a bundle where I want to use the Activator class.

Can anyone suggest where the conflict is likely to be and how I can resolve that issue.

Also I would like to use SLF4J 1.7.5, how would that be possible (would I have to remove the 1.6.4 bundle and replace it with one which exports the later version classes ?)

Kind regards

Fraser.

1 Accepted Solution

Avatar

Correct answer by
Level 10

Yes -- if you want to use a specific version of a Java package in your OSGi, you can create another bundle that wraps that version of the lib in it. Then you can deploy and activate it. Once its part of the run-time - you can reference it using a version. But make sure that the version that you include is part of CQ, otherwise the bundle will not start. 

View solution in original post

1 Reply

Avatar

Correct answer by
Level 10

Yes -- if you want to use a specific version of a Java package in your OSGi, you can create another bundle that wraps that version of the lib in it. Then you can deploy and activate it. Once its part of the run-time - you can reference it using a version. But make sure that the version that you include is part of CQ, otherwise the bundle will not start.