Search code examples
javajacksonosgiapache-felixosgi-bundle

Optional bundle resolution


I'm new in OSGi. I wrote JIRA plugin which is Apache Felix Bundle. My bundle uses Sprring Framework RestTemplate and Jackson XML for a simple REST API call.

So I use other bundle (available on OSGi containter) : Apache ServiceMix :: Bundles :: spring-web which has <Import-Package> set to com.fasterxml.jackson.*; version="[2,3)";resolution:="optional"

I installed jackson-databind, jackson-core and jackson-annotations (all in version 2.6.5) on OSGi container to provide missing, optional dependencies.

Full source code available on my github.

When I install my plugin everything is ok, but during runtime I recieve error :

2016-03-09 10:47:55,431 http-nio-2990-exec-11 ERROR achomont 647x10800x1 1wof9hv 0:0:0:0:0:0:0:1 /secure/CreateWorklog.jspa [c.a.event.internal.AsynchronousAbleEventDispatcher] There was an exception thrown trying to dispatch event [WorklogCreatedEvent{worklog=com.atlassian.jira.issue.worklog.WorklogImpl2@555b9717}] from the invoker [SingleParameterMethodListenerInvoker{method=public void com.company.soft.mycompany.work.log.plugin.listeners.WorkLogIssueListener.onWorklogEvent(com.atlassian.jira.event.worklog.WorklogEvent), listener=com.company.soft.mycompany.work.log.plugin.listeners.WorkLogIssueListener@7491b5aa}]
java.lang.RuntimeException: com/fasterxml/jackson/core/JsonProcessingException
    at com.atlassian.event.internal.SingleParameterMethodListenerInvoker.invoke(SingleParameterMethodListenerInvoker.java:54)
    at com.atlassian.event.internal.AsynchronousAbleEventDispatcher$1$1.run(AsynchronousAbleEventDispatcher.java:48)
    at com.google.common.util.concurrent.MoreExecutors$DirectExecutorService.execute(MoreExecutors.java:299)
    at com.atlassian.event.internal.AsynchronousAbleEventDispatcher.dispatch(AsynchronousAbleEventDispatcher.java:107)
    at com.atlassian.event.internal.EventPublisherImpl.invokeListeners(EventPublisherImpl.java:160)
    at com.atlassian.event.internal.EventPublisherImpl.publish(EventPublisherImpl.java:79)
    at java.util.Optional.ifPresent(Optional.java:159)
    at com.atlassian.jira.issue.worklog.DefaultTimeTrackingIssueUpdater.dispatchEvent(DefaultTimeTrackingIssueUpdater.java:242)
    at com.atlassian.jira.issue.worklog.DefaultTimeTrackingIssueUpdater.doUpdate(DefaultTimeTrackingIssueUpdater.java:221)
    at com.atlassian.jira.issue.worklog.DefaultTimeTrackingIssueUpdater.updateIssue(DefaultTimeTrackingIssueUpdater.java:202)
    at com.atlassian.jira.issue.worklog.DefaultTimeTrackingIssueUpdater.updateIssueOnWorklogCreate(DefaultTimeTrackingIssueUpdater.java:89)
    at com.atlassian.jira.issue.worklog.DefaultWorklogManager.create(DefaultWorklogManager.java:68)
    at com.atlassian.jira.bc.issue.worklog.DefaultWorklogService.create(DefaultWorklogService.java:724)
    at com.atlassian.jira.bc.issue.worklog.DefaultWorklogService.createAndAutoAdjustRemainingEstimate(DefaultWorklogService.java:381)
    at com.atlassian.jira.web.action.issue.CreateWorklog.doExecute(CreateWorklog.java:100)
    ... 1 filtered
    at com.atlassian.jira.action.JiraActionSupport.execute(JiraActionSupport.java:63)
    ... 7 filtered
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:725)
    ... 74 filtered
    at com.atlassian.labs.httpservice.resource.ResourceFilter.doFilter(ResourceFilter.java:59)
    ... 38 filtered
    at com.atlassian.jira.security.JiraSecurityFilter.doFilter(JiraSecurityFilter.java:70)
    ... 37 filtered
    at com.atlassian.fastdev.AutoReloadFilter.doFilter(AutoReloadFilter.java:63)
    ... 55 filtered
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.NoClassDefFoundError: com/fasterxml/jackson/core/JsonProcessingException
    at com.company.soft.mycompany.connector.impl.MycompanyConnectorImpl.sendWorklogData(MycompanyConnectorImpl.java:80)
    at com.company.soft.mycompany.connector.impl.MycompanyConnectorImpl.sendWorklogData1(MycompanyConnectorImpl.java:96)
    at com.company.soft.mycompany.connector.impl.MycompanyConnectorImpl.sendWorklogDataWithCheck(MycompanyConnectorImpl.java:100)
    at com.company.soft.mycompany.connector.impl.MycompanyConnectorImpl.sendAddWorkLogData(MycompanyConnectorImpl.java:65)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    ... 1 filtered
    at java.lang.reflect.Method.invoke(Method.java:497)
    at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317)
    at org.eclipse.gemini.blueprint.service.importer.support.internal.aop.ServiceInvoker.doInvoke(ServiceInvoker.java:56)
    at org.eclipse.gemini.blueprint.service.importer.support.internal.aop.ServiceInvoker.invoke(ServiceInvoker.java:60)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.aop.support.DelegatingIntroductionInterceptor.doProceed(DelegatingIntroductionInterceptor.java:133)
    at org.springframework.aop.support.DelegatingIntroductionInterceptor.invoke(DelegatingIntroductionInterceptor.java:121)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.eclipse.gemini.blueprint.service.util.internal.aop.ServiceTCCLInterceptor.invokeUnprivileged(ServiceTCCLInterceptor.java:70)
    at org.eclipse.gemini.blueprint.service.util.internal.aop.ServiceTCCLInterceptor.invoke(ServiceTCCLInterceptor.java:53)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.eclipse.gemini.blueprint.service.importer.support.LocalBundleContextAdvice.invoke(LocalBundleContextAdvice.java:57)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.aop.support.DelegatingIntroductionInterceptor.doProceed(DelegatingIntroductionInterceptor.java:133)
    at org.springframework.aop.support.DelegatingIntroductionInterceptor.invoke(DelegatingIntroductionInterceptor.java:121)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207)
    at com.sun.proxy.$Proxy2639.sendAddWorkLogData(Unknown Source)
    at com.company.soft.mycompany.work.log.plugin.listeners.WorkLogIssueListener.sendWorkLogData(WorkLogIssueListener.java:115)
    at com.company.soft.mycompany.work.log.plugin.listeners.WorkLogIssueListener.onWorklogEvent(WorkLogIssueListener.java:63)
    ... 3 filtered
    at java.lang.reflect.Method.invoke(Method.java:497)
    at com.atlassian.event.internal.SingleParameterMethodListenerInvoker.invoke(SingleParameterMethodListenerInvoker.java:36)
    ... 235 more
Caused by: java.lang.ClassNotFoundException: com.fasterxml.jackson.core.JsonProcessingException not found by org.apache.servicemix.bundles.spring-web [13]
    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:357)
    ... 267 more

It looks like OSGi containter do not figure out that com.fasterxml.jackson.core is now available.

  1. Should I somehow reload Apache ServiceMix :: Bundles :: spring-web?
  2. Or mayby I need to do it in another way?

I hope someone could help me with this.


Solution

  • If your bundle has an optional import and you allow it to resolve without the import being wired to an exporter, then that situation will continue until you do a "refresh" operation. OSGi tries to leave bundle import/export wiring as static as possible, because it can be expensive to recalculate and it also forced bundles to restart.

    So if you want OSGi to wire to the import that is now available, you need to refresh. This can be done in the Gogo shell by typing the refresh command.