Accessing UserSettingsService from SAL

Hi all,

I’m trying to inject com.atlassian.sal.api.usersettings.UserSettingsService into my object using the following approach:

public class ProductInfo {

    private final UserSettingsService uss;
    private ApplicationProperties applicationProperties;
    private PluginAccessor pluginAccessor;
    private LicenseHandler licenceHandler;

    public ProductInfo(
        ApplicationProperties applicationProperties,
        PluginAccessor pluginAccessor,
        LicenseHandler licenseHandler,
            @ComponentImport UserSettingsService uss
        this.pluginAccessor = pluginAccessor;
        this.applicationProperties = applicationProperties;
        this.licenceHandler = licenseHandler;
        this.uss = uss;

but I get an exception when plugin is reloaded with quick reload plugin:

org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type ‘com.atlassian.sal.api.usersettings.UserSettingsService’ available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: This text will be hidden{@com.atlassian.plugin.spring.scanner.annotation.imports.ComponentImport(value=)}

I will just mention that other constructor arguments like ApplicationProperties and LicenseHandler comes also from SAL and are injected without any problems.

The exception occurred on Confluence 7.4.0. I tried this code on Jira 8.8.1 and result is the same.
How to get access UserSettingsService?

Hei hei @psz

I am unable to reproduce the issue on Confluence 7.4.0, this is what I have

public class SampleCommunityService {

    private final ContentService contentService;
    private final ApplicationProperties applicationProperties;
    private final PluginAccessor pluginAccessor;
    private final LicenseHandler licenceHandler;
    private final UserSettingsService userSettingsService;

    public SampleCommunityService(
            @ComponentImport ContentService contentService,
            @ComponentImport ApplicationProperties applicationProperties,
            @ComponentImport PluginAccessor pluginAccessor,
            @ComponentImport LicenseHandler licenceHandler,
            @ComponentImport UserSettingsService userSettingsService) {
        this.contentService = contentService;
        this.applicationProperties = applicationProperties;
        this.pluginAccessor = pluginAccessor;
        this.licenceHandler = licenceHandler;
        this.userSettingsService = userSettingsService;

The only difference between my setup and yours that I can think of is the spring-scanner version, I am on 2.2.0, and I believe you are on a 1.x version (I can tell you are by the @Scanned annotation there, we did remove it in 2.x). That said, I doubt it would break the plugin … :thinking:

Can you check on the state of Confluence SAL Plugin in your Manage Apps admin settings ? also what does your ` look like ?

My suggestion would be to upgrade spring-scanner

Hi @viqueen,

thank you for your answer and suggestion.

Concerning Confluence SAL Plugin I can see in the app manager that all the modules are enabled:

and also there is a module UserSettingsService (which I want to use):

In my plugin all modules are disabled (due to NoSuchBeanDefinitionException), if I remove that dependency my plugin’s state is ok.

In the OSGI browser I can also see that package com.atlassian.sal.api.usersettings (which contains UserSettingsService) from the System Bundle is marked as exported.

Today I tried to use new version of the spring-scanner (2.2.0) Unfortunately it did not helped. The same exception still occurred.

I also read the readme from atlassian-spring-scanner repository and try to migrate everything properly.
I also debugged the atlassian-spring-scanner.runtime, when my plugin was loading. It looks that class com.atlassian.plugin.spring.scanner.runtime.impl.ComponentImportBeanFactoryPostProcessor is finding a UserSettingsSerivice component and registers it:

in the above selected line the beanClass is non null and no exception is thrown. So it looks as if spring scanner finds the class - but the Spring it self later not…