"Error creating bean with name" dependency on jira-api type

Blair Johnston June 7, 2013

Hi,

I’m looking for help resolving dependencies setting up a new plugin. We’re just starting out with Jira and need to add the ability to add an activity code to work log records. The available plugins add more complexity than we need.

My immediate goal is to intercept the CreateWorklog action and display my own version of the JSP page adding the required field and with my own action class sub-classing the CreateWorklog action class.

I’m getting the following when I invoke Log Work on an issue:

[INFO] [talledLocalContainer] org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'com.shipconstructor.jira.SsiCreateWorklog': Unsatisfied dependency expressed through constructor argument with index 3 of type [com.atlassian.jira.util.JiraDurationUtils]

I found two articles that are close, but didn’t help me.

- https://answers.atlassian.com/questions/59422/plugin-dependency-unresolved-constraint

- https://answers.atlassian.com/questions/51497/error-unsatisfied-dependency-expressed-through-constructor-argument

The way I have it set up currently I have the following in pom.xml

<dependency>
    <groupId>com.atlassian.jira</groupId>
    <artifactId>jira-api</artifactId>
    <version>${jira.version}</version>
    <scope>provided</scope>
</dependency>
<dependency>
    <groupId>com.atlassian.jira</groupId>
    <artifactId>jira-core</artifactId>
    <version>${jira.version}</version>
    <scope>provided</scope>
</dependency>
...
 <instructions>	
     <Import-Package>
         ...
         com.atlassian.jira*;version="${jira.version}",
         ...
    </Import-Package>
    <Export-Package>
         com.shipconstructor.jira*;version="1.0",
    </Export-Package>
</instructions>
...

I have included the jira-core just to try, but from what I can see in the Jira source, the failing dependency JiraDurationUtils, seems to be in the actual jira api.

The atlassian-plugin.xml file includes the following webwork1 module.

<webwork1 key="ssi-create-worklog" name="SSI Create Worklog">
    <actions>
        <action name="com.shipconstructor.jira.SsiCreateWorklog" alias="CreateWorklog">
            <view name="error">/secure/custom/com/shipconstructor/jira/worktypes/webwork/ssi-logwork.jsp</view>
            <view name="input">/secure/custom/com/shipconstructor/jira/worktypes/webwork/ssi-logwork.jsp</view>
        </action>
    </actions>
</webwork1>

Taking care to match the alias CreateWorkLog with that used by Jira so as to override the action.

SsiCreateWorklog.java is very basic:

package com.shipconstructor.jira;
 
import com.atlassian.jira.web.action.issue.CreateWorklog;
import com.atlassian.jira.util.JiraDurationUtils;
...
 
public class SsiCreateWorklog extends CreateWorklog {
 
    public SsiCreateWorklog(WorklogService worklogService,
                            CommentService commentService,
                            ProjectRoleManager projectRoleManager,
                            JiraDurationUtils jiraDurationUtils,
                            OutlookDateManager outlookDateManager,
                            FieldVisibilityManager fieldVisibilityManager,
                            final FieldLayoutManager fieldLayoutManager,
                            final RendererManager rendererManager,
                            UserUtil userUtil,
                            final FeatureManager featureManager)
    {
        super(worklogService, commentService, projectRoleManager, jiraDurationUtils, outlookDateManager, fieldVisibilityManager, fieldLayoutManager, rendererManager, userUtil, featureManager);
    }
 
}

The fourth constructor parameter is the one causing the trouble.

It doesn't get this far, but for completeness the JSP page is trivial page looks like:

<html>
<body>
<h1>Hello world</h1>
</body>
</html>

And this works fine if I navigate directly to it.

Jira starts up fine with this setup and the plugin shows enabled on the system page. However, when I go to an issue and invoke the Log Work action, it results in the following:

[INFO] [talledLocalContainer] 2013-06-07 14:42:08,416 http-2990-2 ERROR admin 882x1696x1 6oio4q 10.0.1.23 /secure/CreateWorklog!default.jspa [jira.config.webwork.JiraActionFactory] Error autowiring Action 'com.shipconstructor.jira.SsiCreateWorklog'.

[INFO] [talledLocalContainer] org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'com.shipconstructor.jira.SsiCreateWorklog': Unsatisfied dependency expressed through constructor argument with index 3 of type [com.atlassian.jira.util.JiraDurationUtils]: : 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; nested exception is 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.ConstructorResolver.createArgumentArray(ConstructorResolver.java:591)

[INFO] [talledLocalContainer] at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:193)

I also tried adding the following to the atlassian-plugin.xml file

<component-import key="jiraDurationUtils"
       interface="com.atlassian.jira.util.JiraDurationUtils" />

but get the following on startup and the plugin was disabled:

[INFO] [talledLocalContainer] 2013-06-07 13:36:10,011 main ERROR [plugin.osgi.factory.OsgiPlugin] Never resolved service '&jiraDurationUtils' for

plugin 'com.shipconstructor.jira.worktypes' with filter (objectClass=com.atlassian.jira.util.JiraDurationUtils)

Any suggestions would be greatly appreciated. I've been going in circles on this one.

4 answers

1 accepted

Comments for this post are closed

Community moderators have prevented the ability to post new answers.

Post a new question

6 votes
Answer accepted
Patrick Li
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
June 7, 2013

Ah, the dreaded JiraDurationUtils, try use the snippet below instead of component-import in your atlassian-plugin.xml

<component key="jiraDurationUtils" name="JIRA Duration Utils" class="com.atlassian.jira.util.JiraDurationUtils"></component>

Blair Johnston June 8, 2013

Thanks Patrick! This did work.

Can you offer any insight as to what this is doing? The plugin XML reference doesn't cover these tags and looking at the source this appears to be part of the api.

Thanks again...

Blair

Patrick Li
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
June 8, 2013

Hi Blair,

<component-import> is introduced with Plugin 2 framework, works if the said component is exposed/marked as public. For the most part, it allows one plugin to expose its components and make them available to use by another plugin.

Now, JiraDurationUtils for some reason is not declared as public, so you cannot import it this way. But since it is available in the JIRA system, you can declare it as a component bean in your own plugin (as if the class is part of your plugin).

There is another way to get JiraDurationUtils, via code through ComponentManager, another handy way to get components that are otherwise not accessible, but looks like this is getting deprecated in JIRA 6.

ComponentManager.getInstance().getJiraDurationUtils();
Blair Johnston June 12, 2013

Patrick, thanks for that explanation. It does explain why I got stuck on that type and not others.

4 votes
JPB August 3, 2014

Thank you so much guys, I had a similar problem but with ComponentLocator and ComponentFactory, and I was stuck for two days with that, but reading a lot and with your help, I could solve that: I had to add this to my atlassian-plugin.xml file:

&lt;component key="componentLocator" name="Component Locator" class="com.atlassian.jira.util.JiraComponentLocator"&gt;
    &lt;interface&gt;com.atlassian.jira.util.ComponentLocator&lt;/interface&gt;
&lt;/component&gt;
  
&lt;component key="componentFactory" name="Component Factory" class="com.atlassian.jira.util.JiraComponentFactory"&gt;
     &lt;interface&gt;com.atlassian.jira.util.ComponentFactory&lt;/interface&gt;
&lt;/component&gt;

And that solved the problem !!

0 votes
P November 25, 2015

Hi Jhonnatan, where is this "atlassian-plugin.xml" file located ?
I am trying to add the following component and stil its unable to find it..

 

The one that i can see is on the following path :
Hook_Plugin_Project >src >test >resource >atlassian-plugin.xml
and
Hook_Plugin_Project >src >main >resource >atlassian-plugin.xml


We tried adding <component-import key="authenticationContext" interface="com.atlassian.stash.user.StashAuthenticationContext"/> .. but that is not helping ..

Below are the logs

2015-11-25 11:10:21,627 ERROR [spring-startup] c.a.p.manager.DefaultPluginManager There was an error loading the descriptor 'My Pre Receive Repository Hook' of plugin 'com.att.icecream.icecream-plugin'. Disabling.
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'com.att.icecream.hook.MyPreReceiveRepositoryHook': Unsatisfied dependency expressed through constructor argument with index 0 of type [com.atlassian.stash.user.StashAuthenticationContext]: : No unique bean of type [com.atlassian.stash.user.StashAuthenticationContext] is defined: Unsatisfied dependency of type [interface com.atlassian.stash.user.StashAuthenticationContext]: expected at least 1 matching bean; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No unique bean of type [com.atlassian.stash.user.StashAuthenticationContext] is defined: Unsatisfied dependency of type [interface com.atlassian.stash.user.StashAuthenticationContext]: expected at least 1 matching bean
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:591) ~[ConstructorResolver.class:4.1.6.RELEASE]
at java.security.AccessController.doPrivileged(Native Method) ~[na:1.8.0_05]
at com.atlassian.plugin.module.ClassPrefixModuleFactory.createModule(ClassPrefixModuleFactory.java:32) ~[ClassPrefixModuleFactory.class:na]
at com.atlassian.plugin.module.PrefixDelegatingModuleFactory.createModule(PrefixDelegatingModuleFactory.java:100) ~[PrefixDelegatingModuleFactory.class:na]
at com.atlassian.plugin.module.PrefixDelegatingModuleFactory$$FastClassBySpringCGLIB$$e05be356.invoke(<generated>) ~[ReflectUtils.class:na]
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204) ~[MethodProxy.class:4.1.6.RELEASE]
at com.atlassian.stash.internal.plugin.OsgiSafeProxyProvider$1.invoke(OsgiSafeProxyProvider.java:93) ~[OsgiSafeProxyProvider$1.class:na]
at com.atlassian.plugin.module.PrefixDelegatingModuleFactory$$EnhancerBySpringCGLIB$$4f92a811.createModule(<generated>) ~[ReflectUtils.class:na]
at com.atlassian.stash.internal.plugin.RepositoryHookModuleDescriptor.enabled(RepositoryHookModuleDescriptor.java:145) ~[RepositoryHookModuleDescriptor.class:na]
at com.atlassian.plugin.manager.DefaultPluginManager.notifyModuleEnabled(DefaultPluginManager.java:2114) [DefaultPluginManager.class:na]
at com.atlassian.plugin.manager.DefaultPluginManager.enableConfiguredPluginModule(DefaultPluginManager.java:1888) [DefaultPluginManager.class:na]
at com.atlassian.plugin.manager.DefaultPluginManager.enableConfiguredPluginModules(DefaultPluginManager.java:1858) [DefaultPluginManager.class:na]
at com.atlassian.plugin.manager.DefaultPluginManager.addPlugins(DefaultPluginManager.java:1250) [DefaultPluginManager.class:na]
at com.atlassian.stash.internal.plugin.StashPluginManager.addPlugins(StashPluginManager.java:66) [StashPluginManager.class:na]
at com.atlassian.plugin.manager.DefaultPluginManager.earlyStartup(DefaultPluginManager.java:523) [DefaultPluginManager.class:na]
at com.atlassian.stash.internal.plugin.StashPluginManager.earlyStartup(StashPluginManager.java:46) [StashPluginManager.class:na]
at com.atlassian.plugin.manager.DefaultPluginManager.init(DefaultPluginManager.java:436) [DefaultPluginManager.class:na]
at com.atlassian.stash.internal.plugin.SpringPluginSystemLifecycle.start(SpringPluginSystemLifecycle.java:34) [SpringPluginSystemLifecycle.class:na]
at org.springframework.context.support.DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.java:173) [DefaultLifecycleProcessor.class:4.1.6.RELEASE]
at org.springframework.context.support.DefaultLifecycleProcessor.access$200(DefaultLifecycleProcessor.java:51) [DefaultLifecycleProcessor.class:4.1.6.RELEASE]
at org.springframework.context.support.DefaultLifecycleProcessor$LifecycleGroup.start(DefaultLifecycleProcessor.java:346) [DefaultLifecycleProcessor$LifecycleGroup.class:4.1.6.RELEASE]
at org.springframework.context.support.DefaultLifecycleProcessor.startBeans(DefaultLifecycleProcessor.java:149) [DefaultLifecycleProcessor.class:4.1.6.RELEASE]
at org.springframework.context.support.DefaultLifecycleProcessor.onRefresh(DefaultLifecycleProcessor.java:112) [DefaultLifecycleProcessor.class:4.1.6.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:770) [AbstractApplicationContext.class:4.1.6.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:483) [AbstractApplicationContext.class:4.1.6.RELEASE]
at javax.servlet.GenericServlet.init(GenericServlet.java:158) [servlet-api.jar:3.1.FR]
at java.lang.Thread.run(Thread.java:745) [na:1.8.0_05]
... 23 frames trimmed
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No unique bean of type [com.atlassian.stash.user.StashAuthenticationContext] is defined: Unsatisfied dependency of type [interface com.atlassian.stash.user.StashAuthenticationContext]: expected at least 1 matching bean
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:613) ~[DefaultListableBeanFactory.class:4.1.6.RELEASE]
... 27 common frames omitted

0 votes
Patrick Li
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
June 8, 2013

Hi Blair,

<component-import> is introduced with Plugin 2 framework, works if the said component is exposed/marked as public. For the most part, it allows one plugin to expose its components and make them available to use by another plugin.

Now, JiraDurationUtils for some reason is not declared as public, so you cannot import it this way. But since it is available in the JIRA system, you can declare it as a component bean in your own plugin (as if the class is part of your plugin).

There is another way to get JiraDurationUtils, via code through ComponentManager, another handy way to get components that are otherwise not accessible, but looks like this is getting deprecated in JIRA 6.

ComponentManager.getInstance().getJiraDurationUtils();

Comments for this post are closed

Community moderators have prevented the ability to post new answers.

Post a new question

TAGS
AUG Leaders

Atlassian Community Events