Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Major Major
    • Resolution: Works as designed
    • Affects Version/s: 2.2.0
    • Fix Version/s: None
    • Component/s: None
    • Labels:
      None
    • Environment:

      Apache Felix 4.2.1, Java 1.8.0-ea-b116, Win-7

      Description

      Creating a Named service always returns NULL in OSGi environment. I am using 2.2.0-b27 version from Maven repo.

      After enabling ServiceLocatorUtilities.enableLookupExceptions(locator); I get the following exception:

      org.osgi.framework.BundleException: Activator start error in bundle hk2felixtest [28].
      at org.apache.felix.framework.Felix.activateBundle(Felix.java:2196)
      at org.apache.felix.framework.Felix.startBundle(Felix.java:2064)
      at org.apache.felix.framework.BundleImpl.start(BundleImpl.java:955)
      at org.apache.felix.gogo.command.Basic.start(Basic.java:729)
      at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
      at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
      at java.lang.reflect.Method.invoke(Unknown Source)
      at org.apache.felix.gogo.runtime.Reflective.invoke(Reflective.java:137)
      at org.apache.felix.gogo.runtime.CommandProxy.execute(CommandProxy.java:82)
      at org.apache.felix.gogo.runtime.Closure.executeCmd(Closure.java:477)
      at org.apache.felix.gogo.runtime.Closure.executeStatement(Closure.java:403)
      at org.apache.felix.gogo.runtime.Pipe.run(Pipe.java:108)
      at org.apache.felix.gogo.runtime.Closure.execute(Closure.java:183)
      at org.apache.felix.gogo.runtime.Closure.execute(Closure.java:120)
      at org.apache.felix.gogo.runtime.CommandSessionImpl.execute(CommandSessionImpl.java:89)
      at org.apache.felix.gogo.shell.Console.run(Console.java:62)
      at org.apache.felix.gogo.shell.Shell.console(Shell.java:203)
      at org.apache.felix.gogo.shell.Shell.gosh(Shell.java:128)
      at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
      at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
      at java.lang.reflect.Method.invoke(Unknown Source)
      at org.apache.felix.gogo.runtime.Reflective.invoke(Reflective.java:137)
      at org.apache.felix.gogo.runtime.CommandProxy.execute(CommandProxy.java:82)
      at org.apache.felix.gogo.runtime.Closure.executeCmd(Closure.java:477)
      at org.apache.felix.gogo.runtime.Closure.executeStatement(Closure.java:403)
      at org.apache.felix.gogo.runtime.Pipe.run(Pipe.java:108)
      at org.apache.felix.gogo.runtime.Closure.execute(Closure.java:183)
      at org.apache.felix.gogo.runtime.Closure.execute(Closure.java:120)
      at org.apache.felix.gogo.runtime.CommandSessionImpl.execute(CommandSessionImpl.java:89)
      at org.apache.felix.gogo.shell.Activator.run(Activator.java:75)
      at java.lang.Thread.run(Unknown Source)
      Caused by: A MultiException has 1 exceptions. They are:
      1. java.lang.ClassNotFoundException: hk2felixtest.FooImpl not found by org.glassfish.hk2.locator [11]

      at org.jvnet.hk2.internal.Collector.throwIfErrors(Collector.java:88)
      at org.jvnet.hk2.internal.Utilities.handleErrors(Utilities.java:458)
      at org.jvnet.hk2.internal.ServiceLocatorImpl$6.compute(ServiceLocatorImpl.java:1023)
      at org.jvnet.hk2.internal.ServiceLocatorImpl$6.compute(ServiceLocatorImpl.java:1006)
      at org.glassfish.hk2.utilities.cache.LRUHybridCache$OriginThreadAwareFuture$1.call(LRUHybridCache.java:115)
      at org.glassfish.hk2.utilities.cache.LRUHybridCache$OriginThreadAwareFuture$1.call(LRUHybridCache.java:111)
      at java.util.concurrent.FutureTask.run(Unknown Source)
      at org.glassfish.hk2.utilities.cache.LRUHybridCache$OriginThreadAwareFuture.run(LRUHybridCache.java:173)
      at org.glassfish.hk2.utilities.cache.LRUHybridCache.compute(LRUHybridCache.java:292)
      at org.jvnet.hk2.internal.ServiceLocatorImpl.internalGetDescriptor(ServiceLocatorImpl.java:1093)
      at org.jvnet.hk2.internal.ServiceLocatorImpl.internalGetService(ServiceLocatorImpl.java:647)
      at org.jvnet.hk2.internal.ServiceLocatorImpl.getService(ServiceLocatorImpl.java:632)
      at hk2felixtest.TestAppMain.getFooService(TestAppMain.java:50)
      at hk2felixtest.TestAppMain.start(TestAppMain.java:31)
      at org.apache.felix.framework.util.SecureAction.startActivator(SecureAction.java:645)
      at org.apache.felix.framework.Felix.activateBundle(Felix.java:2146)
      ... 32 more
      Caused by: java.lang.ClassNotFoundException: hk2felixtest.FooImpl not found by org.glassfish.hk2.locator [11]
      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(Unknown Source)
      at org.jvnet.hk2.internal.Utilities.loadClass(Utilities.java:531)
      at org.jvnet.hk2.internal.ServiceLocatorImpl.loadClass(ServiceLocatorImpl.java:1979)
      at org.jvnet.hk2.internal.ServiceLocatorImpl.reifyDescriptor(ServiceLocatorImpl.java:400)
      at org.jvnet.hk2.internal.ServiceLocatorImpl.narrow(ServiceLocatorImpl.java:2046)
      at org.jvnet.hk2.internal.ServiceLocatorImpl.access$700(ServiceLocatorImpl.java:116)
      at org.jvnet.hk2.internal.ServiceLocatorImpl$6.compute(ServiceLocatorImpl.java:1011)
      ... 45 more
      A MultiException has 1 exceptions. They are:
      1. java.lang.ClassNotFoundException: hk2felixtest.FooImpl not found by org.glassfish.hk2.locator [11]

        Activity

        Hide
        martin.soch added a comment -

        Since I don't see a possibility to attach an example that demonstrates this issue I can send to anyone who is interested. Thanks.

        Show
        martin.soch added a comment - Since I don't see a possibility to attach an example that demonstrates this issue I can send to anyone who is interested. Thanks.
        Hide
        jwells added a comment -

        So we use named services all the time in GlassFish so I am thinking that this is probably an OSGi classloading issue. In particular it looks to me like the reify is using the default algorithm:

        at org.jvnet.hk2.internal.Utilities.loadClass(Utilities.java:531)
        at org.jvnet.hk2.internal.ServiceLocatorImpl.loadClass(ServiceLocatorImpl.java:1979)
        at org.jvnet.hk2.internal.ServiceLocatorImpl.reifyDescriptor(ServiceLocatorImpl.java:400)

        Using the default algorithm is almost always the wrong thing to do on OSGi. Instead the loader needs to be based on the bundle that contains FooImpl. So I wonder

        a) How are you adding the descriptor for FooImpl?
        b) Why does this loader not have an associated HK2Loader https://hk2.java.net/2.2.0/apidocs/org/glassfish/hk2/api/HK2Loader.html?

        How you are adding the descriptor will tell the best way of adding an HK2Loader to your descriptor before binding it.

        Show
        jwells added a comment - So we use named services all the time in GlassFish so I am thinking that this is probably an OSGi classloading issue. In particular it looks to me like the reify is using the default algorithm: at org.jvnet.hk2.internal.Utilities.loadClass(Utilities.java:531) at org.jvnet.hk2.internal.ServiceLocatorImpl.loadClass(ServiceLocatorImpl.java:1979) at org.jvnet.hk2.internal.ServiceLocatorImpl.reifyDescriptor(ServiceLocatorImpl.java:400) Using the default algorithm is almost always the wrong thing to do on OSGi. Instead the loader needs to be based on the bundle that contains FooImpl. So I wonder a) How are you adding the descriptor for FooImpl? b) Why does this loader not have an associated HK2Loader https://hk2.java.net/2.2.0/apidocs/org/glassfish/hk2/api/HK2Loader.html? How you are adding the descriptor will tell the best way of adding an HK2Loader to your descriptor before binding it.
        Hide
        jwells added a comment -

        Here is my reply on your newsgroup thread which I think may also help in this case:

        So looking closer at your code:

        private Descriptor createEventServiceDescriptor(String name)

        { return BuilderHelper.link(EventServiceImpl.class). to(EventService.class). named(name). in(Singleton.class). build(); }

        In an OSGi environment this is likely not going to work because you have not done an "andLoadWith". So this EventServiceImpl will attempt to be loaded by the default algorithm which will not work in an OSGi environment. Since you seem to have access to the class here already you can write a fairly trivial HK2Loader that looks in a HashMap from name to given class which would work in both OSGi and non-OSGi environments or even one that hard-codes the output class file something like this:

        return BuilderHelper.link(fClass).
        to(EventService.class).
        named(name).
        in(Singleton.class).
        andLoadWith(new HK2Loader() {
        public Class<?> loadClass(String a)

        { return EventServiceImpl.class; }

        }).build()

        Or something like that (this is done free-form so excuse any syntax errors in the above code).

        I believe the above code should work in both an OSGi and non-OSGi environment.

        Show
        jwells added a comment - Here is my reply on your newsgroup thread which I think may also help in this case: So looking closer at your code: private Descriptor createEventServiceDescriptor(String name) { return BuilderHelper.link(EventServiceImpl.class). to(EventService.class). named(name). in(Singleton.class). build(); } In an OSGi environment this is likely not going to work because you have not done an "andLoadWith". So this EventServiceImpl will attempt to be loaded by the default algorithm which will not work in an OSGi environment. Since you seem to have access to the class here already you can write a fairly trivial HK2Loader that looks in a HashMap from name to given class which would work in both OSGi and non-OSGi environments or even one that hard-codes the output class file something like this: return BuilderHelper.link(fClass). to(EventService.class). named(name). in(Singleton.class). andLoadWith(new HK2Loader() { public Class<?> loadClass(String a) { return EventServiceImpl.class; } }).build() Or something like that (this is done free-form so excuse any syntax errors in the above code). I believe the above code should work in both an OSGi and non-OSGi environment.
        Hide
        jwells added a comment -

        Martin verified that the solution provided works in both OSGi and non-OSGi cases

        Show
        jwells added a comment - Martin verified that the solution provided works in both OSGi and non-OSGi cases

          People

          • Assignee:
            jwells
            Reporter:
            martin.soch
          • Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: