Ever since Plugins 2.0 was introduced, I have come across the NoSuchBeanDefinitionException more than anything else. And this happens when you try to inject a JIRA component in the constructor. Following is a typical example. [INFO] [talledLocalContainer] Caused by: org.osgi.framework.BundleException: Unresolved constraint in bundle com.jtricks.component-tricks-tests [105]: Unable to resolve 105.0: missing requirement [105.0] package; (package=com.jtricks) [INFO] [talledLocalContainer] at org.apache.felix.framework.Felix.resolveBundle(Felix.java:3409) [INFO] [talledLocalContainer] at org.apache.felix.framework.Felix.startBundle(Felix.java:1709) [INFO] [talledLocalContainer] at org.apache.felix.framework.BundleImpl.start(BundleImpl.java:905) [INFO] [talledLocalContainer] at org.apache.felix.framework.BundleImpl.start(BundleImpl.java:892) [INFO] [talledLocalContainer] at com.atlassian.plugin.osgi.factory.OsgiPlugin.enableInternal(OsgiPlugin.java:417) [INFO] [talledLocalContainer] ... 53 more [INFO] [talledLocalContainer] Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No unique bean of type [com.atlassian.sal.api.user.UserManager] is defined: Unsatisfied dependency of type [interface com.atlassian.sal.api.user.UserManager]: expected at least 1 matching bean [INFO] [talledLocalContainer] at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:613) [INFO] [talledLocalContainer] at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:622) [INFO] [talledLocalContainer] at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:584) Fortunately, the fix is a simple one. Atlassian gives the component-import plugin module. For the above error, all you need to do is to add the following in the atlassian-plugin.xml file. <component-import key="userManager" interface="com.atlassian.sal.api.user.UserManager"/> You would imagine the same will work for every component, Wouldn't you? Unfortunately, that is not the case! Here is an example: JiraDurationUtils. [INFO] [talledLocalContainer] Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No unique bean of type [com.atlassian.jira.util.JiraDurationUtils] is defined: Unsatisfied dependency of type [class com.atlassian.jira.util.JiraDurationUtils]: expected at least 1 matching bean [INFO] [talledLocalContainer] at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:613) Naturally, one would add the component-import tag for the class. I added the following: <component-import key="jiraDurationUtils" interface="com.atlassian.jira.util.JiraDurationUtils" /> This fixed the above error but along came another! [INFO] [talledLocalContainer] 2013-07-12 00:11:44,650 pool-5-thread-3 ERROR admin 11x1420x1 xq2dkb 127.0.0.1 /rest/plugins/1.0/ [plugin.osgi.factory.OsgiPlugin] Never resolved service '&jiraDurationUtils' for plugin 'com.jtricks.component-tricks' with filter (object.atlassian.jira.util.JiraDurationUtils) So, how is JiraDurationUtils different from other components? If you look at the JIRA source, ContainerRegistrar class to be exact, you will see that the JiraDurationUtils component is registered as an internal class. register.implementation(INTERNAL, JiraDurationUtils.class); And that is exactly what causes the new exception. Fortunately, the fix is again an easy one. Instead of using component-import in this case, assume JiraDurationUtils as a class in your plugin (which is of course imported via jira-api dependency). To make it available for constructor injection, define the class as a component in the atlassian-plugin.xml. Int this case, the definition will be as follows: <component key="jiraDurationUtils" name="JIRA Duration Utils" class="com.atlassian.jira.util.JiraDurationUtils"> </component> That's all. Everything will work fine and you don't need the component-import anymore. Want another example? Take ComponentLocator interface. Instead of <component-import key="componentLocator" interface="com.atlassian.jira.util.ComponentLocator" /> you will end up adding the following: <component key="componentLocator" name="Component Locator" class="com.atlassian.jira.util.JiraComponentLocator"> <interface>com.atlassian.jira.util.ComponentLocator</interface> </component> Attached is a sample listener code for you to try it out. Till the next one, enjoy the recipes in JIRA 5.x Development cookbook ;) ![]()
4 Comments
J-Tricks
7/14/2013 04:48:58 pm
Also see Patrick's explanation on https://answers.atlassian.com/questions/178292/error-creating-bean-with-name-dependency-on-jira-api-type
Reply
kiran
4/4/2017 02:18:46 pm
I am getting below Error, i have tried all the approaches to import component could you please help me on this. how do i share the source code?
Reply
Rusi Popov
7/12/2017 02:23:34 pm
Due to https://developer.atlassian.com/docs/getting-started/working-with-the-pom/managing-dependencies this is not possible.
Reply
Joe
7/23/2018 09:38:51 am
How to you deal with the Never resolved service '&jiraDurationUtils' for plugin error while developing plugins-versions 2 with the Atlassian-Plugin-Key set?
Reply
Your comment will be posted after it is approved.
Leave a Reply. |
AuthorJobin Kuruvilla - Works in Adaptavist as Head of DevOps Professional Services. Categories
All
Archives
October 2016
|