the following, seemingly trivial issue has been driving me mad for the last day and a half: - the bundle "netty-worker-service" exports a simple interface that wraps around a type provided ( exported ) by io.netty.transport
package com.github.andlaz.netty.worker.service.api;
import io.netty.channel.nio.NioEventLoopGroup;
public interface NettyWorkerService {
public NioEventLoopGroup getWorkerGroup();
}
it also implements this interface and declares it as a service:
package com.github.andlaz.netty.worker.service.impl;
import io.netty.channel.nio.NioEventLoopGroup;
import aQute.bnd.annotation.component.Component;
import com.github.andlaz.netty.worker.service.api.NettyWorkerService;
@Component(immediate=true)
public class NettyWorkerServiceImpl implements NettyWorkerService {
private final NioEventLoopGroup workerGroup = new NioEventLoopGroup();
@Override
public NioEventLoopGroup getWorkerGroup() {
return workerGroup;
}
}
bnd creates the following component xml:
<component name="com.github.andlaz.netty.worker.service.impl.NettyWorkerServiceImpl" immediate="true">
<implementation class="com.github.andlaz.netty.worker.service.impl.NettyWorkerServiceImpl"/>
<service>
<provide interface="com.github.andlaz.netty.worker.service.api.NettyWorkerService"/>
</service>
</component>
and manifest.mf:
Manifest-Version: 1.0
Bnd-LastModified: 1397806521471
Bundle-ManifestVersion: 2
Bundle-Name: com.github.andlaz.netty.worker.service
Bundle-SymbolicName: netty-worker-service
Bundle-Version: 1.0.0
Created-By: 1.7.0_45 (Oracle Corporation)
Export-Package: com.github.andlaz.netty.worker.service.api;version="1.0"
;uses:="io.netty.channel.nio"
Import-Package: com.github.andlaz.netty.worker.service.api;version="[1.0
,2)",io.netty.channel.nio;version="[4.0,5)"
Private-Package: com.github.andlaz.netty.worker.service.impl
Service-Component: OSGI-INF/com.github.andlaz.netty.worker.service.impl.
NettyWorkerServiceImpl.xml
Tool: Bnd-2.2.0.20130927-173417
Not too complex stuff, right? However, with the following bndrun configuration:
-runfw: org.apache.felix.framework;version='[4,5)'
-runee: JavaSE-1.7
-runsystemcapabilities: ${native_capability}
-resolve.effective: active
-runbundles: io.netty.buffer;version='[4.0.18,4.0.19)',\
io.netty.common;version='[4.0.15,4.0.16)',\
io.netty.transport;version='[4.0.15,4.0.16)',\
netty-worker-service;version=latest,\
org.apache.felix.configadmin;version='[1.6.0,1.6.1)',\
org.apache.felix.gogo.command;version='[0.12.0,0.12.1)',\
org.apache.felix.gogo.runtime;version='[0.10.0,0.10.1)',\
org.apache.felix.gogo.shell;version='[0.10.0,0.10.1)',\
org.apache.felix.log;version='[1.0.1,1.0.2)',\
org.apache.felix.scr;version='[1.8.2,1.8.3)',\
osgi.enterprise;version='[4.2.0,4.2.1)'
-runrequires: osgi.identity;filter:='(osgi.identity=org.apache.felix.gogo.shell)',\
osgi.identity;filter:='(osgi.identity=org.apache.felix.gogo.command)',\
osgi.identity;filter:='(&(osgi.identity=netty-worker-service)(version>=1.0.0))',\
osgi.identity;filter:='(&(osgi.identity=org.apache.felix.log)(version>=1.0.1))'
while everything resolves correctly, i'm seeing the following in logs..
014.04.18 09:35:31 INFO - Bundle: org.apache.felix.framework - [java.lang.Object, aQute.launcher.Launcher] - ServiceEvent REGISTERED
2014.04.18 09:35:31 INFO - Bundle: osgi.enterprise - BundleEvent STARTED
2014.04.18 09:35:31 INFO - Bundle: org.apache.felix.scr - BundleEvent STARTED
2014.04.18 09:35:31 INFO - Bundle: org.apache.felix.scr - [org.apache.felix.scr.impl.ScrGogoCommand] - ServiceEvent REGISTERED
2014.04.18 09:35:31 ERROR - Bundle: netty-worker-service - [com.github.andlaz.netty.worker.service.impl.NettyWorkerServiceImpl(0)] Failed creating the component instance; see log for reason
2014.04.18 09:35:31 ERROR - Bundle: netty-worker-service - [com.github.andlaz.netty.worker.service.impl.NettyWorkerServiceImpl(0)] Error during instantiation of the implementation object - org.apache.felix.log.LogException: java.lang.NoClassDefFoundError: io/netty/util/concurrent/EventExecutorGroup
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:800)
at org.apache.felix.framework.BundleWiringImpl$BundleClassLoader.findClass(BundleWiringImpl.java:2279)
at org.apache.felix.framework.BundleWiringImpl.findClassOrResourceByDelegation(BundleWiringImpl.java:1501)
at org.apache.felix.framework.BundleWiringImpl.access$400(BundleWiringImpl.java:75)
at org.apache.felix.framework.BundleWiringImpl$BundleClassLoader.loadClass(BundleWiringImpl.java:1955)
at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:800)
at org.apache.felix.framework.BundleWiringImpl$BundleClassLoader.findClass(BundleWiringImpl.java:2279)
at org.apache.felix.framework.BundleWiringImpl.findClassOrResourceByDelegation(BundleWiringImpl.java:1501)
at org.apache.felix.framework.BundleWiringImpl.access$400(BundleWiringImpl.java:75)
at org.apache.felix.framework.BundleWiringImpl$BundleClassLoader.loadClass(BundleWiringImpl.java:1955)
at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:800)
at org.apache.felix.framework.BundleWiringImpl$BundleClassLoader.findClass(BundleWiringImpl.java:2279)
at org.apache.felix.framework.BundleWiringImpl.findClassOrResourceByDelegation(BundleWiringImpl.java:1501)
at org.apache.felix.framework.BundleWiringImpl.access$400(BundleWiringImpl.java:75)
at org.apache.felix.framework.BundleWiringImpl$BundleClassLoader.loadClass(BundleWiringImpl.java:1955)
at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
at org.apache.felix.framework.BundleWiringImpl.getClassByDelegation(BundleWiringImpl.java:1374)
at org.apache.felix.framework.BundleWiringImpl.searchImports(BundleWiringImpl.java:1553)
at org.apache.felix.framework.BundleWiringImpl.findClassOrResourceByDelegation(BundleWiringImpl.java:1484)
at org.apache.felix.framework.BundleWiringImpl.access$400(BundleWiringImpl.java:75)
at org.apache.felix.framework.BundleWiringImpl$BundleClassLoader.loadClass(BundleWiringImpl.java:1955)
at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
at com.github.andlaz.netty.worker.service.impl.NettyWorkerServiceImpl.<init>(NettyWorkerServiceImpl.java:11)
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.scr.impl.manager.SingleComponentManager.createImplementationObject(SingleComponentManager.java:253)
at org.apache.felix.scr.impl.manager.SingleComponentManager.createComponent(SingleComponentManager.java:127)
at org.apache.felix.scr.impl.manager.SingleComponentManager.getService(SingleComponentManager.java:871)
at org.apache.felix.scr.impl.manager.SingleComponentManager.getServiceInternal(SingleComponentManager.java:838)
at org.apache.felix.scr.impl.manager.AbstractComponentManager.activateInternal(AbstractComponentManager.java:850)
at org.apache.felix.scr.impl.manager.AbstractComponentManager.enable(AbstractComponentManager.java:419)
at org.apache.felix.scr.impl.config.ConfigurableComponentHolder.enableComponents(ConfigurableComponentHolder.java:376)
at org.apache.felix.scr.impl.BundleComponentActivator.initialize(BundleComponentActivator.java:172)
at org.apache.felix.scr.impl.BundleComponentActivator.<init>(BundleComponentActivator.java:120)
at org.apache.felix.scr.impl.Activator.loadComponents(Activator.java:258)
at org.apache.felix.scr.impl.Activator.access$000(Activator.java:45)
at org.apache.felix.scr.impl.Activator$ScrExtension.start(Activator.java:185)
at org.apache.felix.utils.extender.AbstractExtender.createExtension(AbstractExtender.java:259)
at org.apache.felix.utils.extender.AbstractExtender.modifiedBundle(AbstractExtender.java:232)
at org.apache.felix.utils.extender.AbstractExtender.addingBundle(AbstractExtender.java:192)
at org.osgi.util.tracker.BundleTracker$Tracked.customizerAdding(BundleTracker.java:467)
at org.osgi.util.tracker.BundleTracker$Tracked.customizerAdding(BundleTracker.java:414)
at org.osgi.util.tracker.AbstractTracked.trackAdding(AbstractTracked.java:256)
at org.osgi.util.tracker.AbstractTracked.trackInitial(AbstractTracked.java:183)
at org.osgi.util.tracker.BundleTracker.open(BundleTracker.java:156)
at org.apache.felix.utils.extender.AbstractExtender.startTracking(AbstractExtender.java:150)
at org.apache.felix.utils.extender.AbstractExtender.doStart(AbstractExtender.java:142)
at org.apache.felix.scr.impl.Activator.doStart(Activator.java:117)
at org.apache.felix.utils.extender.AbstractExtender.start(AbstractExtender.java:114)
at org.apache.felix.scr.impl.Activator.start(Activator.java:92)
at org.apache.felix.framework.util.SecureAction.startActivator(SecureAction.java:645)
at org.apache.felix.framework.Felix.activateBundle(Felix.java:2146)
at org.apache.felix.framework.Felix.startBundle(Felix.java:2064)
at org.apache.felix.framework.BundleImpl.start(BundleImpl.java:955)
at aQute.launcher.Launcher.update(Launcher.java:378)
at aQute.launcher.Launcher.activate(Launcher.java:303)
at aQute.launcher.Launcher.run(Launcher.java:193)
at aQute.launcher.Launcher.main(Launcher.java:89)
Caused by: java.lang.ClassNotFoundException: io.netty.util.concurrent.EventExecutorGroup not found by io.netty.common [2]
at org.apache.felix.framework.BundleWiringImpl.findClassOrResourceByDelegation(BundleWiringImpl.java:1532)
at org.apache.felix.framework.BundleWiringImpl.access$400(BundleWiringImpl.java:75)
at org.apache.felix.framework.BundleWiringImpl$BundleClassLoader.loadClass(BundleWiringImpl.java:1955)
at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
at org.apache.felix.framework.BundleWiringImpl.getClassByDelegation(BundleWiringImpl.java:1374)
at org.apache.felix.framework.BundleWiringImpl.searchImports(BundleWiringImpl.java:1553)
at org.apache.felix.framework.BundleWiringImpl.findClassOrResourceByDelegation(BundleWiringImpl.java:1484)
at org.apache.felix.framework.BundleWiringImpl.access$400(BundleWiringImpl.java:75)
at org.apache.felix.framework.BundleWiringImpl$BundleClassLoader.loadClass(BundleWiringImpl.java:1955)
at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
... 66 more
2014.04.18 09:35:31 INFO - Bundle: netty-worker-service - [com.github.andlaz.netty.worker.service.api.NettyWorkerService] - ServiceEvent REGISTERED
2014.04.18 09:35:31 INFO - Bundle: org.apache.felix.scr - [org.osgi.service.cm.ManagedService] - ServiceEvent REGISTERED
2014.04.18 09:35:31 INFO - Bundle: org.apache.felix.scr - [org.apache.felix.scr.ScrService] - ServiceEvent REGISTERED
2014.04.18 09:35:31 INFO - Bundle: org.apache.felix.scr - [org.osgi.service.cm.ConfigurationListener] - ServiceEvent REGISTERED
2014.04.18 09:35:31 INFO - Bundle: org.apache.felix.log - BundleEvent STARTED
2014.04.18 09:35:31 INFO - Bundle: org.apache.felix.log - [org.osgi.service.log.LogReaderService] - ServiceEvent REGISTERED
2014.04.18 09:35:31 INFO - Bundle: org.apache.felix.log - [org.osgi.service.log.LogService] - ServiceEvent REGISTERED
g!
tl;dr : io.netty.util.concurrent.EventExecutorGroup is nowhere to be found.
Caused by: java.lang.ClassNotFoundException: io.netty.util.concurrent.EventExecutorGroup not found by io.netty.common [2]
i verified the following: - io.netty.transport correctly imports this type from io.netty.common - io.netty.common contains and exports this type
i dont know how to proceed with debugging this. Any pointers are greatly appreciated! project source is available at https://github.com/andlaz/netty-worker-service
( nb: i just noticed a mixing of minor versions of netty packages in runbundles, setting all versions to [4.0.15,4.0.16) made no difference - however : )-
with netty 4.0.18 i can no longer reproduce this - everything works flawlessly.
-runbundles: io.netty.buffer;version='[4.0.18,5)',\
io.netty.common;version='[4.0.18,5)',\
io.netty.transport;version='[4.0.18,5)',\
i'll have to check changes between .15 and .18 but the update seemed to have fixed whatever was causing this.
I finally figured this out. A bit of backstory:
i use Nexus to create an .m2 proxy repository of Maven Central, this gives me the safety of my dependencies not vanishing in to thin air ( not that central has been doing that ).
On top of this however, i have an OBR proxy ( proxy of a proxy :-) ) that filters out Bundles from whatever is cached in my proxy of Central and indexes bundles in a repository.xml Works flawlessly - i add <type>bundle</type>
dependencies in my poms that are fetched through my Central proxy; as soon as the proxy downloads the artifacts, the OBR repository.xml is updated and the packages in the bundle become resolve-able through OBR.
But then Netty happened. Their -sources.jar has complete Bundle headers matching that of their actual bundles When this makes its way in to an OSGI framework, it is resolved correctly, all headers ( names, versions, exports, imports) are matching the actual bundle so there is no way for you to tell that you loaded a bundle that is exporting .java files