AbstractBlueprintContextProvider API is deprecated?

Hi guys,

A few months ago I was developing a Confluence plugin and all was well. I have since returned with the latest Atlassian SDK. Now when I run the plugin using an 'atlas-run' command the plugin gets disabled.

This is the log output that implies there is an issue some where:

[INFO] <PLUGIN-NAME>/hello_blueprint/MyBlueprintListener.java: Some input files use or override a deprecated API.
[INFO] <PLUGIN-NAME>hello_blueprint/MyBlueprintListener.java: Recompile with -Xlint:deprecation for details.

[INFO] [talledLocalContainer] 2017-04-06 16:21:39,865 ERROR [localhost-startStop-1] [atlassian.plugin.manager.DefaultPluginManager] enableConfiguredPluginModule There was an error loading the descriptor 'null' of plugin '<PLUGIN-NAME>'. Disabling.
[INFO] [talledLocalContainer] com.atlassian.plugin.PluginParseException: Unable to load the module's display conditions: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'com.bsquare.emea.plugins.hello_blueprint.HierarchyContextProvider': Unsatisfied dependency expressed through constructor argument with index 0 of type [com.atlassian.confluence.languages.LocaleManager]: No qualifying bean of type [com.atlassian.confluence.languages.LocaleManager] 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.atlassian.confluence.languages.LocaleManager] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}
[INFO] [talledLocalContainer] at com.atlassian.confluence.plugins.createcontent.extensions.ContentTemplateModuleDescriptor.getContextProvider(ContentTemplateModuleDescriptor.java:265)
[INFO] [talledLocalContainer] at com.atlassian.confluence.plugins.createcontent.extensions.ContentTemplateModuleDescriptor.enabled(ContentTemplateModuleDescriptor.java:232)
[INFO] [talledLocalContainer] at com.atlassian.plugin.manager.DefaultPluginManager.notifyModuleEnabled(DefaultPluginManager.java:1991)
[INFO] [talledLocalContainer] at com.atlassian.plugin.manager.DefaultPluginManager.enableConfiguredPluginModule(DefaultPluginManager.java:1738)
[INFO] [talledLocalContainer] at com.atlassian.plugin.manager.DefaultPluginManager.enableConfiguredPluginModules(DefaultPluginManager.java:1715)
[INFO] [talledLocalContainer] at com.atlassian.plugin.manager.DefaultPluginManager.enableDependentPlugins(DefaultPluginManager.java:1227)
[INFO] [talledLocalContainer] at com.atlassian.plugin.manager.DefaultPluginManager.addPlugins(DefaultPluginManager.java:1188)
[INFO] [talledLocalContainer] at com.atlassian.plugin.manager.DefaultPluginManager.lateStartup(DefaultPluginManager.java:634)
[INFO] [talledLocalContainer] at com.atlassian.confluence.plugin.ConfluencePluginManager.lateStartup(ConfluencePluginManager.java:147)
[INFO] [talledLocalContainer] at com.atlassian.confluence.plugin.PluginFrameworkContextListener.contextInitialized(PluginFrameworkContextListener.java:79)
[INFO] [talledLocalContainer] at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4842)
[INFO] [talledLocalContainer] at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5303)
[INFO] [talledLocalContainer] at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:147)
[INFO] [talledLocalContainer] at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:725)
[INFO] [talledLocalContainer] at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:701)
[INFO] [talledLocalContainer] at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:717)
[INFO] [talledLocalContainer] at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:940)
[INFO] [talledLocalContainer] at org.apache.catalina.startup.HostConfig$DeployWar.run(HostConfig.java:1816)
[INFO] [talledLocalContainer] at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
[INFO] [talledLocalContainer] at java.util.concurrent.FutureTask.run(FutureTask.java:266)
[INFO] [talledLocalContainer] at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
[INFO] [talledLocalContainer] at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
[INFO] [talledLocalContainer] at java.lang.Thread.run(Thread.java:745)
[INFO] [talledLocalContainer] Caused by: com.atlassian.plugin.web.conditions.ConditionLoadingException: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name '<PLUGIN-NAME>.HierarchyContextProvider': Unsatisfied dependency expressed through constructor argument with index 0 of type [com.atlassian.confluence.languages.LocaleManager]: No qualifying bean of type [com.atlassian.confluence.languages.LocaleManager] 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.atlassian.confluence.languages.LocaleManager] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}
[INFO] [talledLocalContainer] at com.atlassian.confluence.plugin.descriptor.web.ConfluenceWebFragmentHelper.loadComponent(ConfluenceWebFragmentHelper.java:35)
[INFO] [talledLocalContainer] at com.atlassian.confluence.plugin.descriptor.web.ConfluenceWebFragmentHelper.loadContextProvider(ConfluenceWebFragmentHelper.java:58)
[INFO] [talledLocalContainer] at com.atlassian.confluence.plugins.createcontent.extensions.ContentTemplateModuleDescriptor.getContextProvider(ContentTemplateModuleDescriptor.java:255)
[INFO] [talledLocalContainer] ... 22 more
[INFO] [talledLocalContainer] Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name '<PACKAGE_NAME>.HierarchyContextProvider': Unsatisfied dependency expressed through constructor argument with index 0 of type [com.atlassian.confluence.languages.LocaleManager]: No qualifying bean of type [com.atlassian.confluence.languages.LocaleManager] 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.atlassian.confluence.languages.LocaleManager] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}
[INFO] [talledLocalContainer] at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:749)
[INFO] [talledLocalContainer] at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:185)
[INFO] [talledLocalContainer] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1143)
[INFO] [talledLocalContainer] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1046)
[INFO] [talledLocalContainer] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:510)
[INFO] [talledLocalContainer] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482)
[INFO] [talledLocalContainer] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:342)
[INFO] [talledLocalContainer] at sun.reflect.GeneratedMethodAccessor171.invoke(Unknown Source)
[INFO] [talledLocalContainer] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
[INFO] [talledLocalContainer] at java.lang.reflect.Method.invoke(Method.java:498)
[INFO] [talledLocalContainer] at com.atlassian.plugin.osgi.spring.DefaultSpringContainerAccessor.createBean(DefaultSpringContainerAccessor.java:97)
[INFO] [talledLocalContainer] at com.atlassian.confluence.plugin.ConfluencePluginUtils.instantiatePluginModule(ConfluencePluginUtils.java:150)
[INFO] [talledLocalContainer] at com.atlassian.confluence.plugin.descriptor.web.ConfluenceWebFragmentHelper.loadComponent(ConfluenceWebFragmentHelper.java:33)
[INFO] [talledLocalContainer] ... 24 more

It seems that something in my HierarchyContextProvider method is deprecated. This is taken from the example class in the "intermediate" blueprint example that uses this class to generate a page title.  The tutorial (that is found here:  https://developer.atlassian.com/confdev/confluence-plugin-guide/confluence-blueprints/write-an-intermediate-blueprint-plugin) doesn't seem to reflect this change.

It should also be noted that I had changed my pom.xml to reflect the new changes to the Atlassian Spring Byte Code Scanner. The changes follow this guide: https://bitbucket.org/atlassian/atlassian-spring-scanner. 

I'm unfamiliar with Java Spring but I had placed a "@Hardwired" directive about the method to see if that would achieve anything. I'm not sure it did!

 

If anyone has a fix/workaround for this, any help would be much appreciated!

Thanks,

Russell Bateman

2 answers

1 accepted

1 vote
Accepted answer

What is your scanner version? 2 and higher or 1.xx?

First do this:

  1. Mark your class with @Scanned
  2. Mark the LocaleManager with @ComponentImport
  3. Mark the constructor of the class with @Inject

It should look like this:

@Scanned
public class HierarchyContextProvider
{
    @ComponentImport
    private final LocaleManager localeManager;
    @Inject
    public HierarchyContextProvider(LocaleManager localeManager){
        this.localeManager=localeManager;
    }
}

Otherwise, you need to use <component-import> in the atlassian-plugin.xml file to import the localemanager, remove  the @Scanned, @ComponentImport and replace the @Inject with @Autowired (not @hardwired)  

Atlassian scanner for >2.x version will complain if <component> or <component-import> are found in the atlassian-plugin.xml so you can't mix both.

Edit: It is not deprecated, just Spring can't find the bean

Hi Panos,

Thank you for your detailed answer! However when I make these changes I get these compilation errors:

[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.6.1:compile (default-compile) on project <PROJECT_NAME>: Compilation failure: Compilation failure:
[ERROR] <PROJECT_NAME>/hello_blueprint/HierarchyContextProvider.java:[14,52] cannot find symbol
[ERROR] symbol:   class Scanned
[ERROR] location: package org.springframework.beans.factory.annotation
[ERROR] <PROJECT_NAME>/hello_blueprint/HierarchyContextProvider.java:[15,52] cannot find symbol
[ERROR] symbol:   class ComponentImport
[ERROR] location: package org.springframework.beans.factory.annotation
[ERROR] <PROJECT_NAME>/hello_blueprint/HierarchyContextProvider.java:[16,13] cannot find symbol
[ERROR] symbol:   class inject
[ERROR] location: package javax <PROJECT_NAME>/hello_blueprint/HierarchyContextProvider.java:[22,2] cannot find symbol
[ERROR] symbol: class Scanned
[ERROR] <PROJECT_NAME>/hello_blueprint/HierarchyContextProvider.java:[25,6] cannot find symbol
[ERROR] symbol:   class ComponentImport
[ERROR] location: class <PROJECT_NAME>/hello_blueprint/HierarchyContextProvider.java:[30,6] cannot find symbol
[ERROR] symbol:   class Inject
[ERROR] location: class <PROJECT_NAME>.HierarchyContextProvider

I have added these imports to the top of my HierarchyContextProvider.java file:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Scanned;
import org.springframework.beans.factory.annotation.ComponentImport;
import javax.inject;

Any assistance would be appreciated!

 

Post your pom.xml and these are the imports

import org.springframework.beans.factory.annotation.Autowired;
import com.atlassian.plugin.spring.scanner.annotation.component.Scanned;
import com.atlassian.plugin.spring.scanner.annotation.imports.ComponentImport;
import javax.inject.Inject;

Remember, either (Scanned and Inject) or Autowired 

Hi Panos,

Those imports allieviated the compiliation errors I was getting! There is still an issue somewhere. The example featured other Java components that I will probably need to go through and add these "Scanned", "Inject" or "Autowire"  directives to. 

Here is the copy of my pom.xml: https://pastebin.com/bjgNHJ3H

What specifies which directive I need for a class/method?

Once again thanks for all the help

Still an issue? Are you still getting the same error or other errors?

There still is an issue I'm afraid, but at least its different! This is the error log:

[INFO] [talledLocalContainer] 2017-04-07 14:27:05,581 INFO [localhost-startStop-1] [atlassian.plugin.manager.DefaultPluginManager] broadcastPluginDisabling Disabling <PLUGIN_NAME>
[INFO] [talledLocalContainer] 2017-04-07 14:27:05,583 ERROR [localhost-startStop-1] [plugin.osgi.factory.OsgiPlugin] logAndClearOustandingDependencies Plugin 'PLUGIN_NAME' never resolved service '&helloService' with filter '(&(objectClass=<PLUGIN_NAME>.HelloService)(objectClass=<PLUGIN_NAME>.HelloService))'

It's got something to do with the 'HelloService.java' file (taken from the example mentioned earlier).  There is hardly any code inside it, but I have not placed the directives there yet.

Also in my atlassian-plugin.xml I have these tags:

<!-- import from the product container -->
 <component-import key="applicationProperties" interface="com.atlassian.sal.api.ApplicationProperties" />

 <!-- import from the product container -->
  <component-import key="eventPublisher" interface="com.atlassian.event.api.EventPublisher"/>
 <component key="eventListener" class="com.bsquare.emea.plugins.hello_blueprint.MyBlueprintListener"/>

Should they be removed?

Good. Now on your HelloService class add @ExportAsService. That should fix it. If not instead of above use @Component. Since you use 1.2.13 scanner you dont have to remove from thr xml, but if you do you need to use @ComponentImport

In the class! Not interface

What would be the imports for the "ExportAsService" and "Component" directives?

Okay I added the directives for ExportAsService next to the HelloService class. So now it looks like this:

@ExportAsService
public class DefaultHelloService implements HelloService
{
    @Override
    public String getFriendlyDate()
    {
        return DateFormat.getDateInstance(DateFormat.LONG).format(new Date());
    }

    @Override
    public String getFriendlyDateTime()
    {
        return DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG).format(new Date());
    }
}

The error still seems to persist. So I placed an "@Component" directive instead of an "@ExportAsService". However this seemed to generate compiliation errors (symbol not found) when I imported this package: import org.springframework.stereotype.Component;.

Thanks for all your help so far!

Any assistance you can give with this would be much appreciated!

oh you need also the @named along with @exportasservice. Sorry it slipped my mind:

import javax.inject.Named;

@ExportAsService
@Named("defaultHelloService") public class DefaultHelloService implements HelloService { @Override public String getFriendlyDate() { return DateFormat.getDateInstance(DateFormat.LONG).format(new Date()); } @Override public String getFriendlyDateTime() { return DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG).format(new Date()); } }

 

Hi Panos,

Thanks for your reply! I have tried putting the @Named directive in the class definition as you recommended but I still get the same issue.

In the tutorial it gives you an example component ("MyPluginComponent"). In there it seems to have all of these "@" directives. I've noticed that the "@ExportAsService" directive has a name at the end of it, here is what it looks like:

@ExportAsService ({MyPluginComponent.class})
@Named ("myPluginComponent")
public class MyPluginComponentImpl implements MyPluginComponent
{
     @ComponentImport
      private final ApplicationProperties applicationProperties;

      @Inject
      public MyPluginComponentImpl(final ApplicationProperties  applicationProperties)
       {
                this.applicationProperties = applicationProperties;
        }

      public String getName()
      {
         if(null != applicationProperties)
         {
             return "myComponent:" + applicationProperties.getDisplayName();
         }

          return "myComponent";
       }
}

I tried putting "@ExportAsService ({HelloService.class})"  in the service class but this made no difference.

Any other ideas?

Thanks,

Russell Bateman

a) You miss the @Scanned. If you are using componets from confluence, you need the scanned. In your case you are using the ApplicationProperties

b) Check your resources/META-INF/spring/plugin-context.xml file. Should looke like 

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:atlassian-scanner="http://www.atlassian.com/schema/atlassian-scanner"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
        http://www.atlassian.com/schema/atlassian-scanner
        http://www.atlassian.com/schema/atlassian-scanner/atlassian-scanner.xsd">
    <atlassian-scanner:scan-indexes/>
</beans>

Hi Panos,

Thanks for the prompt reply. I checked my plugin-context.xml file and it does match your example correctly.  Theres still an issue with the HelloService class, this is what it currently looks like:

import com.atlassian.plugin.spring.scanner.annotation.export.ExportAsService;
import javax.inject.Named;

import java.text.DateFormat;
import java.util.Date;

/**
 * An unnecessary service that shows how a ContextProvider can retrieve information from *any* plugin-available
 * Component.
 *
 * @since 5.0
 */
 @ExportAsService ({HelloService.class})
 @Named ("defualtHelloService")
public class DefaultHelloService implements HelloService
{
    @Override
    public String getFriendlyDate()
    {
        return DateFormat.getDateInstance(DateFormat.LONG).format(new Date());
    }

    @Override
    public String getFriendlyDateTime()
    {
        return DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG).format(new Date());
    }
}

Is there anything else that should be here?

Also, I took out the <component> and <component-import> statements from my atlassian-plugin.xml file as it starting failing to validate it, once I had enabled validation in my POM.xml. Could it be something there causing this issue?

Weird.. Although the spelling in @named is wrong, that shouldnot be the case. I can only suggest fix the spelling (just hurts my eyes :) ) and then add a default constructor 

I fixed the spelling of "default" in the @Named directive and tried adding a default constructor to the class but its still getting the same error.


Thanks for your help anyway! I'll mark your initial response as the answer as it fixed the original issue. I'll see if anyone on the dev-forums can think of anything else. But really I could just remove the HelloService component altogether as it doesn't do much.

Can you post your source code to the github or something public? I am really curious...

Hi Panos,

Yeah I'll put it up on GitHub later if you want to take a look at it. I'll post a link when it's up!

Thanks for all the help!

So, a) your <export> in pom.xml is wrong. You are exporting some api package, but the helloservice interface exists in another package.

b) Your pom.xml uses wrongly the scanner (as if it was v2)

c) You have declared a lot of blueprints without i18n-key:

init i18n-name-key is a required attribute of <content-template> for module: com.bsquare.emea.plugins.EMEAPlugin:customermeetings-template

d) HelloService must not be marked as @ComponentImport

The fix for a and b is in here
Or you can clone the whole project here. Apologies for the rebase in a new project, i realized i didn't fork way too late.

Hi Panos,

Thanks very much for your time. The plugin works fine now!

Thanks,

Russell Bateman

0 votes
Sam Hall Community Champion Apr 06, 2017

Hi Russell - Welcome to the community. Since your question is development related, you might want to try asking this over at: https://community.developer.atlassian.com as well (if you haven't already).

There are a lot of helpful and experienced people over there, so you will probably get a quicker response.

You can read more about the Developer Community in this article: https://community.atlassian.com/t5/Feedback-Forum-articles/The-Atlassian-Developer-Community/ba-p/459061

Hi Sam,

Thank you for your reply! I'll make sure I use the dedicated developer community section in the future.

Thanks,

Russell Bateman

Suggest an answer

Log in or Sign up to answer
Community showcase
Posted Oct 24, 2018 in Confluence

Atlassian Research opportunity with Confluence templates

Do you use templates with Confluence? Take part in a remote 1-hr workshop. You'll receive USD $100 for your time!   We're looking for people to participate in a   remote 1-hr workshop...

1,561 views 26 14
Join discussion

Atlassian User Groups

Connect with like-minded Atlassian users at free events near you!

Find a group

Connect with like-minded Atlassian users at free events near you!

Find my local user group

Unfortunately there are no AUG chapters near you at the moment.

Start an AUG

You're one step closer to meeting fellow Atlassian users at your local meet up. Learn more about AUGs

Groups near you