AbstractBlueprintContextProvider API is deprecated?

Russell Bateman April 6, 2017

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
Answer accepted
Panos
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.
April 7, 2017

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

Russell Bateman April 7, 2017

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!

 

Panos
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.
April 7, 2017

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 

Russell Bateman April 7, 2017

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

Panos
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.
April 7, 2017

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

Russell Bateman April 7, 2017

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?

Panos
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.
April 7, 2017

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

Panos
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.
April 7, 2017

In the class! Not interface

Russell Bateman April 7, 2017

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

Russell Bateman April 7, 2017

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!

Panos
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.
April 7, 2017

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()); } }

 

Russell Bateman April 10, 2017

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

Panos
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.
April 10, 2017

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>
Russell Bateman April 10, 2017

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?

Panos
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.
April 10, 2017

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 

Russell Bateman April 10, 2017

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.

Panos
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.
April 10, 2017

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

Russell Bateman April 10, 2017

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!

Russell Bateman April 10, 2017

Here is the repo:

https://github.com/RussellSBateman/EMEAConfluencePlugin

Thanks again,

Russell Bateman

Panos
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.
April 10, 2017

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.

Russell Bateman April 11, 2017

Hi Panos,

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

Thanks,

Russell Bateman

0 votes
Sam Hall
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.
April 6, 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

Russell Bateman April 7, 2017

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
TAGS
AUG Leaders

Atlassian Community Events