UnsatisfiedDependencyException error when creating a custom field plugin

Angelo Diego Crabolu November 21, 2019

I'm trying to migrate on old plugin I wrote, containing a custom field but I get  then following error com.atlassian.cache.CacheException: com.atlassian.util.concurrent.LazyReference$InitializationException: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'xxx.plugins.jira.customfields.ReadOnlyProjectComponent': Unsatisfied dependency expressed through constructor argument with index 0 of type [com.atlassian.jira.issue.customfields.manager.OptionsManager]: No qualifying bean of type [com.atlassian.jira.issue.customfields.manager.OptionsManager] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@com.atlassian.plugin.spring.scanner.annotation.imports.JiraImport(value=)}; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.atlassian.jira.issue.customfields.manager.OptionsManager] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@com.atlassian.plugin.spring.scanner.annotation.imports.JiraImport(value=)}

 

Here is the code for the component

 

package com.index_education.plugins.jira.customfields;
import com.atlassian.jira.bc.issue.search.SearchService;import com.atlassian.jira.bc.project.component.ProjectComponent;import com.atlassian.jira.component.ComponentAccessor;import com.atlassian.jira.config.FeatureManager;import com.atlassian.jira.issue.customfields.impl.MultiSelectCFType;import com.atlassian.jira.issue.customfields.manager.GenericConfigManager;import com.atlassian.jira.issue.customfields.manager.OptionsManager;import com.atlassian.jira.issue.customfields.option.Option;import com.atlassian.jira.issue.customfields.persistence.CustomFieldValuePersister;import com.atlassian.jira.issue.Issue;import com.atlassian.jira.issue.fields.CustomField;import com.atlassian.jira.issue.fields.config.FieldConfig;import com.atlassian.jira.issue.fields.layout.field.FieldLayoutItem;import com.atlassian.jira.issue.fields.rest.json.beans.JiraBaseUrls;import com.atlassian.jira.security.JiraAuthenticationContext;
import java.util.ArrayList;import java.util.List;import java.util.Map;
import com.atlassian.plugin.spring.scanner.annotation.imports.JiraImport;

public class ReadOnlyProjectComponent extends MultiSelectCFType {
        public ReadOnlyProjectComponent(@JiraImport OptionsManager optionsManager, @JiraImport CustomFieldValuePersister valuePersister,    @JiraImport GenericConfigManager genericConfigManager, @JiraImport JiraBaseUrls jiraBaseUrls, @JiraImport SearchService searchService, @JiraImport FeatureManager featureManager    @JiraImport JiraAuthenticationContext authenticationContext) {        super(optionsManager, valuePersister, genericConfigManager, jiraBaseUrls, searchService, featureManager, authenticationContext);    }
    @Override    public Map<StringObjectgetVelocityParameters(final Issue issuefinal CustomField fieldfinal FieldLayoutItem fieldLayoutItem) {
        // This method is also called to get the default value, in        // which case issue is null         if (issue.equals(null)) {            return super.getVelocityParameters(issue, field, fieldLayoutItem);        }
        FieldConfig fieldConfig = field.getRelevantConfig(issue);        // add what you need to the map here        OptionsManager optionsManager = ComponentAccessor.getOptionsManager();                List<OptionexistingOptions = new ArrayList<Option>();        optionsManager.removeCustomFieldConfigOptions(fieldConfig);
        Long l = 0L;        for (ProjectComponent component : ComponentAccessor.getProjectComponentManager().findAllForProject(issue.getProjectObject().getId())) {            Option option = optionsManager.createOption(fieldConfig, null, l, component.getName());            existingOptions.add(option);            l++;        }                optionsManager.updateOptions(existingOptions);                        final Map<StringObjectmap = super.getVelocityParameters(issue, field, fieldLayoutItem);        return map;    }}

Any idea of what's wrong?

1 answer

0 votes
Tuncay Senturk
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
November 21, 2019

Hi @Angelo Diego Crabolu 

Have you tried adding below component-import to atlassian-plugin.xml ?

<component-import key="optionsManager" interface="com.atlassian.jira.issue.customfields.manager.OptionsManager" />
Angelo Diego Crabolu November 22, 2019

HI, @Tuncay Senturk 

yes I did and I get a atlassian-plugin.xml contains a definition of component-import. This is not allowed when Atlassian-Plugin-Key is set.
[ERROR]

Ignat May 10, 2022

for me worked this

import com.atlassian.plugin.spring.scanner.annotation.imports.ComponentImport;
import org.springframework.beans.factory.annotation.Autowired;

import javax.inject.Inject;
import javax.inject.Named;
import java.util.logging.Level;

/*
jira.core dependency should be uncommented for this plugin to work
*/
@Named // using @Named instead of @Scanned by Matveev's suggestion
public class MultiSelect2 extends MultiSelectCFType {
/*
use of atlassian logger described it this tutorial
https://developer.atlassian.com/server/jira/platform/writing-jira-event-listeners-with-the-atlassian-event-library/
*/
// private static final Logger log = LoggerFactory.getLogger(MultiSelect2.class);
private final LoggerUtils loggerUtils;
private final java.util.logging.Logger logger;

/*
atlassian tutorial step 4.4 suggests to use @JiraImport annotation for
constructor arguments to import them from host application with atlassian
spring scanner
https://developer.atlassian.com/server/jira/platform/creating-a-custom-field-in-jira/
*/
@Autowired
@Inject
public MultiSelect2(@ComponentImport CustomFieldValuePersister customFieldValuePersister
, @ComponentImport GenericConfigManager genericConfigManager
, @ComponentImport JiraBaseUrls jiraBaseUrls
, @ComponentImport SearchService searchService
, @ComponentImport FeatureManager featureManager
, @ComponentImport JiraAuthenticationContext jiraAuthenticationContext) {
/*
Options manager is acquired trough ComponentAccessor and the rest of
managers trough @ComponentImport annotation of Atlassian Spring Scanner
I do not know what this matters for yet
*/
super(ComponentAccessor.getOptionsManager() // this interface is used to manipulate options. not sure if I need it here
, customFieldValuePersister // This interface is used to save an issue's custom field value to the database
, genericConfigManager
, jiraBaseUrls
, searchService
, featureManager
, jiraAuthenticationContext); // This interface is used to store Generic configuration values for issue's custom field

 

Suggest an answer

Log in or Sign up to answer