NoSuchBeanException on jira plugin component

Hi,

I’m developing an sso plugin for jira. However, on clicking the configure button it’s redirecting to dead link and throwing following Exception in logs:

/secure/admin/samlsso.configure.jspa [c.a.j.web.dispatcher.JiraWebworkActionDispatcher] Exception thrown from action ‘samlsso.configure’, returning 404
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name ‘com.miniorange.sso.saml.jira.servlet.ConfigurationAction’: Unsatisfied dependency expressed through constructor argument with index 0 of type [com.miniorange.sso.saml.jira.SAMLSettings]: : No qualifying bean of type [com.miniorange.sso.saml.jira.SAMLSettings] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.miniorange.sso.saml.jira.SAMLSettings] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}

SAMLSettings.java is the part of the plugin files. Strange part is that the plugin is working just fine on local jira server and most of the servers. Only some people are getting this. I’m including ConfigurationAction, SAMLSettings and atlassian-plugin.xml. Please help

ConfigurationAction.java

package com.miniorange.sso.saml.jira.servlet;

import com.atlassian.crowd.embedded.api.Group;
import com.atlassian.jira.component.ComponentAccessor;
import com.atlassian.jira.security.groups.GroupManager;
import com.atlassian.jira.web.action.JiraWebActionSupport;
import com.miniorange.sso.saml.PluginException;
import com.miniorange.sso.saml.jira.PluginHandler;
import com.miniorange.sso.saml.jira.SAMLSettings;
import com.miniorange.sso.saml.utils.SAMLUtils;
import com.atlassian.upm.api.license.PluginLicenseManager;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class ConfigurationAction extends JiraWebActionSupport {

	private static final Logger LOGGER = LoggerFactory.getLogger(ConfigurationAction.class);

	
	private PluginLicenseManager pluginLicenseManager;
	private SAMLSettings settings;
	private PluginHandler pluginHandler;

	public ConfigurationAction(SAMLSettings settings, PluginHandler pluginHandler, PluginLicenseManager pluginLicenseManager) {
		this.settings = settings;
		this.pluginHandler = pluginHandler;
		this.pluginLicenseManager=pluginLicenseManager;
	}

	public SAMLSettings getSettings() {
		return this.settings;
	}

	public void setSettings(SAMLSettings settings) {
		this.settings = settings;
	}

	
	public void setPluginHandler(PluginHandler pluginHandler) {
		this.pluginHandler = pluginHandler;
	}


	public PluginLicenseManager getPluginLicenseManager() {
		return pluginLicenseManager;
	}

	public void setPluginLicenseManager(PluginLicenseManager pluginLicenseManager) {
		this.pluginLicenseManager = pluginLicenseManager;
	}

	public PluginHandler getPluginHandler() {
		return pluginHandler;
	}	

}

SAMLSettings.java

package com.miniorange.sso.saml.jira;



import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.atlassian.jira.component.ComponentAccessor;
import com.atlassian.jira.config.properties.APKeys;
import com.atlassian.jira.license.LicenseCountService;
import com.atlassian.jira.user.ApplicationUser;
import com.atlassian.jira.user.util.UserManager;
import com.atlassian.sal.api.pluginsettings.PluginSettings;
import com.atlassian.sal.api.pluginsettings.PluginSettingsFactory;
import com.atlassian.upm.api.license.PluginLicenseManager;
import com.atlassian.upm.api.license.entity.Contact;
import com.atlassian.upm.api.license.entity.PluginLicense;
import com.miniorange.sso.saml.jira.servlet.SAMLLoginServlet;
import com.miniorange.sso.saml.utils.SAMLUtils;
import com.miniorange.sso.saml.jira.PluginConstants;

public class SAMLSettings {
	private static Log LOGGER = LogFactory.getLog(SAMLLoginServlet.class);
	private PluginSettings pluginSettings;
	private LicenseCountService licenseCountService;
	private PluginLicenseManager pluginLicenseManager;
	private UserManager userManager;
	public static final String CUSTOMER_TOKEN_KEY = generateRandomAlphaNumericKey(16);
	
	public LicenseCountService getLicenseCountService() {
		return licenseCountService;
	}

	public void setLicenseCountService(LicenseCountService licenseCountService) {
		this.licenseCountService = licenseCountService;
	}
	
	public PluginLicenseManager getPluginLicenseManager() {
		return pluginLicenseManager;
	}

	public void setPluginLicenseManager(PluginLicenseManager pluginLicenseManager) {
		this.pluginLicenseManager = pluginLicenseManager;
	}

	
	public void setPluginSettingsFactory(PluginSettingsFactory pluginSettingsFactory) {
		this.pluginSettings = pluginSettingsFactory.createGlobalSettings();
	}

	public void setUserManager(UserManager userManager) {
		this.userManager = userManager;
	}
	
	
}

atlassian-plugin.xml

<?xml version="1.0" encoding="UTF-8"?>

<atlassian-plugin key="${project.groupId}.${project.artifactId}"
	name="${project.name}" plugins-version="2">
	<plugin-info>
		<description>${project.description}</description>
		<version>${project.version}</version>
		<vendor name="${project.organization.name}" url="${project.organization.url}" />
		<param name="atlassian-data-center-compatible">true</param>
		<param name="plugin-icon">images/icon.png</param>
		<param name="plugin-logo">images/logo.png</param>
		<param name="configure.url">/secure/admin/samlsso.configure.jspa</param>
		<param name="atlassian-licensing-enabled">true</param>
	</plugin-info>
	<!-- add our i18n resource -->
	<resource type="i18n" name="i18n" location="jira-sso" />
	<!-- add our web resources -->
	<web-resource key="samlsso.plugin.auth.resources"
		i18n-name-key="samlsso.plugin.auth.resources" name="Authentication Resources">
		<resource name="jira-sso.js" type="download" location="js/jira-sso.js" />
		<context>atl.general</context>
	</web-resource>
	<web-resource key="samlsso.plugin.admin.resources"
		i18n-name-key="samlsso.plugin.admin.resources" name="Admin Resources">
		<dependency>com.atlassian.auiplugin:ajs</dependency>
		<resource name="jira-sso.js" type="download" location="js/jira-sso.js" />
		<resource name="jira-sso.css" type="download" location="css/jira-sso.css" />
		<context>atl.admin</context>
	</web-resource>
	<web-item name="SAML SSO Configuration Menu" i18n-name-key="samlsso.config.menu"
		key="samlsso.config.menu" section="top_system_section/security_section"
		weight="150" application="jira">
		<description key="samlsso.config.menu.desc">This display menu item for configuring
			the plugin in System settings
			under Security.
		</description>
		<label key="samlsso.config.menu.lable">SAML SSO Configuration</label>
		<link linkId="samlsso.config.menu.link">/secure/admin/samlsso.configure.jspa</link>
	</web-item>

	<webwork1 i18n-name-key="samlsso.config.action" key="samlsso.config.action"
		name="SAML SSO Configuration Action" class="java.lang.Object">
		<description key="samlsso.config.action.desc">This helps you configure the SAML SSO
			Plugin.</description>
		<actions>
			<action name="com.miniorange.sso.saml.jira.servlet.ConfigurationAction"
				alias="samlsso.configure">
				<view name="input">/templates/com/miniorange/sso/saml/jira/configure.vm
				</view>
				<view name="success">/templates/com/miniorange/sso/saml/jira/configure.vm
				</view>
				<view name="error">/templates/com/miniorange/sso/saml/jira/configure.vm
				</view>
			</action>
			
			<action
				name="com.miniorange.sso.saml.jira.servlet.DownloadCertificateServlet"
				alias="samlsso.downloadcertificate">
				<view name="input">/templates/com/miniorange/sso/saml/jira/configure.vm
				</view>
			</action>
		</actions>
	</webwork1>

	
	<component i18n-name-key="samlsso.plugin.settings" key="samlsso.plugin.settings"
		name="SAML SSO Plugin Settings" class="com.miniorange.sso.saml.jira.SAMLSettings" />
	<component i18n-name-key="samlsso.plugin.handler" key="samlsso.plugin.handler"
		name="SAML SSO Plugin Handler" class="com.miniorange.sso.saml.jira.PluginHandler" />
	<component i18n-name-key="samlsso.saml.message.handler" key="samlsso.saml.message.handler"
		name="SAML Message Handler" class="com.miniorange.sso.saml.jira.SAMLManager" />
	<component i18n-name-key="samlsso.websudo.session.handler"
		key="samlsso.websudo.session.handler" name="WebSudo Session Handler"
		class="com.miniorange.sso.saml.jira.JiraSAMLSSOWebSudoSessionManager" />
	<component i18n-name-key="samlsso.authenticator" key="samlsso.authenticator"
		name="SAML SSO Authenticator" class="com.miniorange.sso.saml.jira.JiraSAMLSSOAuthenticator" />
	<component-import i18n-name-key="samlsso.plugin.settings.factory"
		key="samlsso.plugin.settings.factory" name="Plugin Settings Factory"
		interface="com.atlassian.sal.api.pluginsettings.PluginSettingsFactory"
		filter="" />
	<component-import i18n-name-key="samlsso.login.uri.provider"
		key="samlsso.login.uri.provider" name="Login URI Provider"
		interface="com.atlassian.sal.api.auth.LoginUriProvider" filter="" />
	<component-import i18n-name-key="samlsso.application.properties"
		key="samlsso.application.properties" name="Application Properties"
		interface="com.atlassian.sal.api.ApplicationProperties" filter="" />
	<component-import i18n-name-key="samlsso.user.manager"
		key="user.manager" name="User Manager" interface="com.atlassian.sal.api.user.UserManager"
		filter="" />
	<component-import i18n-name-key="samlsso.user.util"
		key="user.util" name="User Util" interface="com.atlassian.jira.user.util.UserUtil"
		filter="" />
	<component-import key="PluginLicenseManager" interface="com.atlassian.upm.api.license.PluginLicenseManager"/>
	<!-- SAML LOGIN Servlets & Filters -->
	<servlet name="Get Configuration Servlet" i18n-name-key="samlsso.config.servlet"
		key="samlsso.config.servlet" class="com.miniorange.sso.saml.jira.servlet.GetConfigurationServlet">
		<description key="samlsso.config.servlet.desc">This module handles configuration of your
			Identity Provider.
		</description>
		<url-pattern>/saml/getconfig</url-pattern>
	</servlet>
	<servlet name="Login with IDP" i18n-name-key="samlsso.login"
		key="samlsso.login" class="com.miniorange.sso.saml.jira.servlet.SAMLLoginServlet">
		<description key="samlsso.login.desc">This module handles login with your
			Identity Provider.</description>
		<url-pattern>/saml/auth</url-pattern>
	</servlet>
	<servlet name="SAML Single Logout" i18n-name-key="samlsso.logout"
		key="samlsso.logout" class="com.miniorange.sso.saml.jira.servlet.SAMLLogoutServlet">
		<description key="samlsso.logout.desc">This module handles Single Logout with
			your Identity Provider.</description>
		<url-pattern>/saml/logout</url-pattern>
	</servlet>
	<servlet name="Download Idp Guide" i18n-name-key="samlsso.config.downloadidpguides" key="samlsso.config.downloadidpguides"
             class="com.miniorange.sso.saml.jira.servlet.DownloadIdpGuidesServlet">
        <description key="samlsso.config.downloadidpguides.desc">This module allows you to download Guides for your Identity Provider.
        </description>
        <url-pattern>/downloadidpguides</url-pattern>
    </servlet>
	<servlet name="SP Metadata Generator" i18n-name-key="samlsso.metadata.generator"
		key="samlsso.metadata.generator" class="com.miniorange.sso.saml.jira.servlet.MetadataServlet">
		<description key="samlsso.login.desc">This module generates SP metadata for
			your JIRA Instance.</description>
		<url-pattern>/saml/metadata</url-pattern>
	</servlet>
	
	<servlet-filter name="SAML SSO Filter" key="saml-login-filter"
		location="before-dispatch" class="com.miniorange.sso.saml.jira.servlet.SAMLLoginFilter"
		weight="200">
		<description>
			Force authentication with IdP by redirecting user to IdP's login page
			instead of Jira.
		</description>
		<url-pattern>/secure/Dashboard.jspa</url-pattern>
		<url-pattern>/login.jsp</url-pattern>
		<url-pattern>/plugins/servlet/mobile</url-pattern>
		<url-pattern>/secure/admin/WebSudoAuthenticate!default.jspa
		</url-pattern>
		<dispatcher>REQUEST</dispatcher>
		<dispatcher>FORWARD</dispatcher>
	</servlet-filter>
</atlassian-plugin>

Please let me know if anymore information needs to be included.

Can you include your pom? You likely have SpringScanner enabled and defining component-imports through the atlassian-plugin.xml descriptor is not valid for that approach.

Hi. Thanks for responding. Here’s my pom.xml content. I haven’t included spring scanner. I’ve used atlas sdk 6.2.11 to build the jar file.

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
   <modelVersion>4.0.0</modelVersion>
   <groupId>com.miniorange.sso.saml</groupId>
   <artifactId>jira-sso</artifactId>
   <version>1.1.5</version>
   <organization>
      <name>miniOrange</name>
      <url>http://miniorange.com/</url>
   </organization>
   <name>SAML Single Sign On for JIRA</name>
   <description>SAML Single Sign On for JIRA provides SSO/login to your Atlassian Jira Server with any SAML compliant Identity Provider.</description>
   <packaging>atlassian-plugin</packaging>
   <dependencies>
      <!--
 <dependency> <groupId>org.apache.wss4j</groupId> <artifactId>wss4j-ws-security-common</artifactId> 
			<version>2.1.5</version> <exclusions> <exclusion> <groupId>org.slf4j</groupId> 
			<artifactId>slf4j-api</artifactId> </exclusion> <exclusion> <groupId>org.bouncycastle</groupId> 
			<artifactId>bcpkix-jdk15on</artifactId> </exclusion> <exclusion> <groupId>org.bouncycastle</groupId> 
			<artifactId>bcprov-jdk15on</artifactId> </exclusion> </exclusions> </dependency> 
-->
      <!--
<dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> 
			<version>1.7.14</version> <scope>provided</scope> </dependency> 
-->
      <dependency>
         <groupId>org.opensaml</groupId>
         <artifactId>opensaml</artifactId>
         <version>2.6.4</version>
         <exclusions>
            <exclusion>
               <groupId>xalan</groupId>
               <artifactId>xalan</artifactId>
            </exclusion>
            <exclusion>
               <groupId>xerces</groupId>
               <artifactId>xercesImpl</artifactId>
            </exclusion>
            <exclusion>
               <groupId>xalan</groupId>
               <artifactId>serializer</artifactId>
            </exclusion>
            <exclusion>
               <groupId>xml-resolver</groupId>
               <artifactId>xml-resolver</artifactId>
            </exclusion>
         </exclusions>
      </dependency>
      <dependency>
         <groupId>org.opensaml</groupId>
         <artifactId>xmltooling</artifactId>
         <version>1.4.4</version>
      </dependency>
      <dependency>
         <groupId>xml-resolver</groupId>
         <artifactId>xml-resolver</artifactId>
         <version>1.2</version>
      </dependency>
      <!--
 <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-common-utilities</artifactId> 
			<version>2.5.11</version> </dependency> <dependency> <groupId>org.apache.cxf</groupId> 
			<artifactId>cxf-rt-rs-security-sso-saml</artifactId> <version>3.1.6</version> 
			<exclusions> <exclusion> <groupId>org.apache.geronimo.specs</groupId> <artifactId>geronimo-servlet_3.0_spec</artifactId> 
			</exclusion> </exclusions> </dependency> 
-->
      <dependency>
         <groupId>javax.servlet</groupId>
         <artifactId>javax.servlet-api</artifactId>
         <version>3.1.0</version>
         <scope>provided</scope>
      </dependency>
      <dependency>
         <groupId>com.atlassian.seraph</groupId>
         <artifactId>atlassian-seraph</artifactId>
         <version>2.6.3</version>
         <scope>provided</scope>
      </dependency>
      <dependency>
         <groupId>org.apache.commons</groupId>
         <artifactId>commons-lang3</artifactId>
         <version>3.3.2</version>
         <scope>provided</scope>
      </dependency>
      <dependency>
         <groupId>org.apache.httpcomponents</groupId>
         <artifactId>httpclient</artifactId>
         <version>4.4.1</version>
         <scope>provided</scope>
      </dependency>
      <!--
<dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> 
			<version>2.7.4</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> 
			<artifactId>jackson-annotations</artifactId> <version>2.7.4</version> </dependency> 
			<dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> 
			<version>2.7.4</version> </dependency> 
-->
      <dependency>
         <groupId>commons-codec</groupId>
         <artifactId>commons-codec</artifactId>
         <version>1.9</version>
         <scope>provided</scope>
      </dependency>
      <dependency>
         <groupId>com.atlassian.jira</groupId>
         <artifactId>jira-api</artifactId>
         <version>${jira.version}</version>
         <scope>provided</scope>
      </dependency>
      <dependency>
         <groupId>com.atlassian.crowd</groupId>
         <artifactId>embedded-crowd-api</artifactId>
         <version>2.8.3</version>
         <scope>provided</scope>
      </dependency>
      <!--
 Add dependency on jira-core if you want access to JIRA implementation 
			classes as well as the sanctioned API. 
-->
      <!--
 This is not normally recommended, but may be required eg when migrating 
			a plugin originally developed against JIRA 4.x 
-->
      <dependency>
         <groupId>com.atlassian.jira</groupId>
         <artifactId>jira-core</artifactId>
         <version>${jira.version}</version>
         <scope>provided</scope>
      </dependency>
      <dependency>
         <groupId>junit</groupId>
         <artifactId>junit</artifactId>
         <version>4.10</version>
         <scope>test</scope>
      </dependency>
      <!--  WIRED TEST RUNNER DEPENDENCIES  -->
      <dependency>
         <groupId>com.atlassian.plugins</groupId>
         <artifactId>atlassian-plugins-osgi-testrunner</artifactId>
         <version>${plugin.testrunner.version}</version>
         <scope>test</scope>
      </dependency>
      <dependency>
         <groupId>javax.ws.rs</groupId>
         <artifactId>jsr311-api</artifactId>
         <version>1.1.1</version>
         <scope>provided</scope>
      </dependency>
      <!--
 Uncomment to use TestKit in your project. Details at https://bitbucket.org/atlassian/jira-testkit 
-->
      <!--
 You can read more about TestKit at https://developer.atlassian.com/display/JIRADEV/Plugin+Tutorial+-+Smarter+integration+testing+with+TestKit 
-->
      <!--
 <dependency> <groupId>com.atlassian.jira.tests</groupId> <artifactId>jira-testkit-client</artifactId> 
			<version>${testkit.version}</version> <scope>test</scope> </dependency> 
-->
      <dependency>
         <groupId>org.slf4j</groupId>
         <artifactId>slf4j-api</artifactId>
         <version>1.6.6</version>
         <scope>provided</scope>
      </dependency>
      <dependency>
         <groupId>org.mockito</groupId>
         <artifactId>mockito-all</artifactId>
         <version>1.8.5</version>
         <scope>test</scope>
      </dependency>
      <dependency>
         <groupId>com.atlassian.upm</groupId>
         <artifactId>licensing-api</artifactId>
         <version>2.21.4</version>
         <scope>provided</scope>
      </dependency>
      <dependency>
         <groupId>com.atlassian.upm</groupId>
         <artifactId>upm-api</artifactId>
         <version>2.21</version>
         <scope>provided</scope>
      </dependency>
   </dependencies>
   <build>
      <plugins>
         <plugin>
            <groupId>com.atlassian.maven.plugins</groupId>
            <artifactId>maven-jira-plugin</artifactId>
            <version>${amps.version}</version>
            <extensions>true</extensions>
            <configuration>
               <productVersion>${jira.version}</productVersion>
               <productDataVersion>${jira.version}</productDataVersion>
               <enableQuickReload>true</enableQuickReload>
               <enableFastdev>false</enableFastdev>
               <!--  Uncomment to install TestKit backdoor in JIRA.  -->
               <!--
 <pluginArtifacts> <pluginArtifact> <groupId>com.atlassian.jira.tests</groupId> 
						<artifactId>jira-testkit-plugin</artifactId> <version>${testkit.version}</version> 
						</pluginArtifact> </pluginArtifacts> 
-->
            </configuration>
         </plugin>
         <plugin>
            <artifactId>maven-compiler-plugin</artifactId>
            <configuration>
               <source>1.8</source>
               <target>1.8</target>
            </configuration>
         </plugin>
      </plugins>
   </build>
   <properties>
      <jira.version>7.2.1</jira.version>
      <amps.version>6.2.6</amps.version>
      <plugin.testrunner.version>1.2.3</plugin.testrunner.version>
      <!--  TestKit version 6.x for JIRA 6.x  -->
      <testkit.version>6.3.11</testkit.version>
   </properties>
</project>

Thanks.

I believe you must mark SAMLSettings as a Component plugin module: https://developer.atlassian.com/docs/getting-started/plugin-modules/component-plugin-module.

Thanks for replying but I’ve already done that in atlassian-plugins.xml file

<component i18n-name-key="samlsso.plugin.settings" key="samlsso.plugin.settings"
		name="SAML SSO Plugin Settings" class="com.miniorange.sso.saml.jira.SAMLSettings" />

Is there anything else I need to do to mark it as component plugin module?

Thanks.

Sorry, I missed that somehow. So basically we’re hitting this KB document: https://developer.atlassian.com/docs/faq/troubleshooting/unsatisfieddependencyexception-error-creating-bean-with-name. I thought the error included a link to it.

It seems all we have left it the last line:

If using a component-import doesn’t work you may be able to instantiate the object using ManagerFactory.getMyObject()
or ComponentManager.getInstance().getMyObject(), or even ComponentManager.getInstance().getComponentInstanceOfType(MyObject.class).

  • Try component-import
  • Try ManagerFactor
  • Try ComponentManager

Thanks. I’ll try those options. Actually on restarting the server, the plugin started working. Is it normal?

No, that is not normal. I’m not sure what to make of that fact… If that module is already provided by another plugin and you’re loading it again, that could be problematic.

Hey there,

I highly recommend to use the spring-scanner - actually when creating a plugin the SDK should automatically adds this in the pom (also with atlas sdk 6.2.11).

You defined all your components in the descriptor file:

	<component i18n-name-key="samlsso.plugin.settings" key="samlsso.plugin.settings"
		name="SAML SSO Plugin Settings" class="com.miniorange.sso.saml.jira.SAMLSettings" />
	<component i18n-name-key="samlsso.plugin.handler" key="samlsso.plugin.handler"
		name="SAML SSO Plugin Handler" class="com.miniorange.sso.saml.jira.PluginHandler" />
	<component i18n-name-key="samlsso.saml.message.handler" key="samlsso.saml.message.handler"
		name="SAML Message Handler" class="com.miniorange.sso.saml.jira.SAMLManager" />
	<component i18n-name-key="samlsso.websudo.session.handler"
		key="samlsso.websudo.session.handler" name="WebSudo Session Handler"
		class="com.miniorange.sso.saml.jira.JiraSAMLSSOWebSudoSessionManager" />
	<component i18n-name-key="samlsso.authenticator" key="samlsso.authenticator"
		name="SAML SSO Authenticator" class="com.miniorange.sso.saml.jira.JiraSAMLSSOAuthenticator" />
	<component-import i18n-name-key="samlsso.plugin.settings.factory"
		key="samlsso.plugin.settings.factory" name="Plugin Settings Factory"
		interface="com.atlassian.sal.api.pluginsettings.PluginSettingsFactory"
		filter="" />
	<component-import i18n-name-key="samlsso.login.uri.provider"
		key="samlsso.login.uri.provider" name="Login URI Provider"
		interface="com.atlassian.sal.api.auth.LoginUriProvider" filter="" />
	<component-import i18n-name-key="samlsso.application.properties"
		key="samlsso.application.properties" name="Application Properties"
		interface="com.atlassian.sal.api.ApplicationProperties" filter="" />
	<component-import i18n-name-key="samlsso.user.manager"
		key="user.manager" name="User Manager" interface="com.atlassian.sal.api.user.UserManager"
		filter="" />
	<component-import i18n-name-key="samlsso.user.util"
		key="user.util" name="User Util" interface="com.atlassian.jira.user.util.UserUtil"
		filter="" />
	<component-import key="PluginLicenseManager" interface="com.atlassian.upm.api.license.PluginLicenseManager"/>

In my opinion this is waaay to much…you defined the component with a lot of informations

<component i18n-name-key="samlsso.plugin.settings" key="samlsso.plugin.settings"
	name="SAML SSO Plugin Settings" class="com.miniorange.sso.saml.jira.SAMLSettings" />

What happens if you change the package of your component or just the name? You need to change it as well in the atlassian-plugin.xml manually. Keep it simple…Just add the single word @Component at the top of your class. You dont need any more to define it as a component. Therefore you also keep the atlassian-plugin.xml file clean, you have a lot of modules which you already have defined in this file, and that should be enough.

Now, the exception said “expected at least 1 bean which qualifies as autowire candidate for this dependency.” Autowire is the key-word. Once you defined your component you also have to add the @Autowire Annotation to your ConfigurationAction Constructor. Currently you have definied the SAMLSettings as a simple field in your ConfigurationAction. What you need to do is

    @ComponentImport //
	private PluginLicenseManager pluginLicenseManager;

	private SAMLSettings settings;
	

	@Autowired
	public ConfigurationAction(SAMLSettings settings, PluginHandler pluginHandler, PluginLicenseManager pluginLicenseManager) {
		this.settings = settings;
		this.pluginHandler = pluginHandler;
		this.pluginLicenseManager=pluginLicenseManager;
	}

One last thing: In many cases I also needed to add the @Scanned annotation at the top of the ActionSupport class. The Scanned Annotation makes sure that every given Component for this class will be injected. Thats sounds a bit weird…actually I would expect that every component will be injected but its not in every case…So if you want to get sure that everything will be injected correctly just add the @Scanned annotation always on your classes.

Nice to know: with spring-scanner 2.0+ you don’t need to add the @Scanned annotation, it will be added automatically on every class you create

Thanks for these suggestions. I’ll try this and let you know if everything works out