J tricks - Little JIRA Tricks
  • Home
  • Plugins ↓
    • JQL Tricks Plugin
      • JQL Tricks Plugin - Cloud
        • JQLT Cloud Installation
        • JQLT Cloud Configuration
        • JQLT Cloud Usage
        • JQLT Cloud License
        • JQLT Cloud FAQ
      • JQL Tricks Plugin - DC
        • JQLT DC Installation
        • JQLT DC Configuration
        • JQLT DC Usage
          • JQLT Issue Functions
          • JQLT Subtask Functions
          • JQLT Links Functions
          • JQLT Development Functions
          • JQLT Worklog Functions
          • JQLT Project Functions
          • JQLT Component Functions
          • JQLT Version Functions
          • JQLT Group Functions
          • JQLT User Functions
          • JQLT Date Functions
        • JQLT DC License
        • JQLT DC FAQ
        • JQLT DC Known Issues
        • JQLT DC Performance
      • JQL Tricks Cloud Migration
    • Simplified Planner
      • J-Planner Installation
      • J-Planner Configuration
      • J-Planner Usage
        • Creating a plan
        • Editing a plan
        • Deleting a plan
        • Viewing a plan
        • Modifying a plan
      • J-Planner FAQ
    • Atla-Search Plugin
      • Atla-Search Installation
      • Atla-Search Configuration
      • Atla-Search Usage
      • Atla-Search License
      • Atla-Search FAQ
    • Copy to subtask Plugin
    • All Plugins
  • Tutorials
  • The Book
  • Contact Us
  • Home
  • Plugins ↓
    • JQL Tricks Plugin
      • JQL Tricks Plugin - Cloud
        • JQLT Cloud Installation
        • JQLT Cloud Configuration
        • JQLT Cloud Usage
        • JQLT Cloud License
        • JQLT Cloud FAQ
      • JQL Tricks Plugin - DC
        • JQLT DC Installation
        • JQLT DC Configuration
        • JQLT DC Usage
          • JQLT Issue Functions
          • JQLT Subtask Functions
          • JQLT Links Functions
          • JQLT Development Functions
          • JQLT Worklog Functions
          • JQLT Project Functions
          • JQLT Component Functions
          • JQLT Version Functions
          • JQLT Group Functions
          • JQLT User Functions
          • JQLT Date Functions
        • JQLT DC License
        • JQLT DC FAQ
        • JQLT DC Known Issues
        • JQLT DC Performance
      • JQL Tricks Cloud Migration
    • Simplified Planner
      • J-Planner Installation
      • J-Planner Configuration
      • J-Planner Usage
        • Creating a plan
        • Editing a plan
        • Deleting a plan
        • Viewing a plan
        • Modifying a plan
      • J-Planner FAQ
    • Atla-Search Plugin
      • Atla-Search Installation
      • Atla-Search Configuration
      • Atla-Search Usage
      • Atla-Search License
      • Atla-Search FAQ
    • Copy to subtask Plugin
    • All Plugins
  • Tutorials
  • The Book
  • Contact Us

Active Objects Injection

7/22/2012

20 Comments

 
One fine morning. While zipping coffee on the couch, I made up my design. It is going to be a service that reads configuration data saved using Active Objects. Easy peasy. So I thought!

I wrote my service faster than I planned, looking at my own tutorial, compiled it and everything looked fine.

And then I started testing it using atlas-run. (Suspense music ♪♫♫).

Boom..Null pointer Exception where the injected ActiveObjects component is used. Surely, ActiveObjects in not injected properly in the constructor of a service. Now, it makes sense because the service is probably initialized before the Active Objects plugin is loaded.

Backup plan (Plan B) - Get the ActiveObjects object suing ComponentManager.

ActiveObjects ao = ComponentManager.getOSGiComponentInstanceOfType(ActiveObjects.class);

In the run method, I initialized ActiveObjects for the first time as mentioned above and yes! I got a valid object. But then came across this error:

atlassian.activeobjects.osgi.ActiveObjectsServiceFactory] Could not find any active objects configurations for bundle org.apache.felix.framework.
Did you define an 'ao' module descriptor in your plugin?
Try adding this in your atlassian-plugin.xml file: <ao key='some-key' />


And this, in spite of having a valid definition in the atlassian-plugin.xml. Surely, something is not right.

Backup plan (Plan C) - Use the powers of Google, when yours is not working.

Google, now effectively crawling answers.atlassian.com, brought me a similar thread (hail Google!) where Stefan Chapuis stumbled up on a similar issue for mail handlers. And Wojciech Seliga had a brilliant workaround based on the reasoning - ActiveObjects can only be injected.

The workaround is pretty simple:

  1. Create you own component in the plugin using component plugin module.

    <component key="jtricks-manager" name="J-Tricks Manager" public="true">
        <interface>com.jtricks.manager.JTricksManager</interface>
    </component>
  2. Inject ActiveObjects in your component.

    package com.jtricks.manager;
    import com.atlassian.activeobjects.external.ActiveObjects;

    public class JTricksManagerImpl implements JTricksManager{

        private final ActiveObjects ao;
        public JTricksManagerImpl(ActiveObjects ao) {
            this.ao = ao;
        }

        @Override
        public ActiveObjects getActiveObjects() {
            return this.ao;
        }
    }
  3. Get an instance of the component in the service's run method using ComponentManager

    if (this.jTricksManager == null)
        this.jTricksManager = ComponentAccessor.getOSGiComponentInstanceOfType(JTricksManager.class);


  4. Retrieve the ActiveObjects object from the component

        ActiveObjects ao = this.jTricksManager.getActiveObjects();

Everything else, business as usual. Maybe a recipe for the next book?

Hope this helps someone stumbling up on the same/similar issue. And if you know a better trick, or if it is working for you in some other way, please do comment.

20 Comments
Sim Hua Soon link
9/28/2012 04:36:29 pm

Thanks for the useful reference.

I also came across from SaM's
<a href="https://answers.atlassian.com/questions/14922/active-object-service-fails-to-load-when-a-component-is-marked-public-true">posting</a>

that the "Could not find any active objects configurations" is more likely to be due to calling Active Object too early.

<blockquote>
The issue here is not linked to making the component public but to implementing InitialisingBean and calling the Active Object component too early.

The Active Objects component will only be truly available once the whole context is properly setup. Before that what gets injected by Spring is a proxy of the component since it is actually an OSGi service.

So to avoid this situation to not use Active Object inside when initialising an InitialisingBean. A good alternative is usually to do things lazily, i.e. if you need to prepare some AO data, do it on first call to the AO component.
</blockquote>

Reply
J-Tricks
9/29/2012 01:48:39 am

Thanks Sim. That should work. If you have an example, please do share :)

Reply
windows8installation.com link
7/10/2013 11:20:25 pm

Such an article really helps us to start a service that can read configuration data. It can make us write faster than we have planned. This trick can really help anyone stumbling upon the similar issue. I hope you will continue your efforts by posting more of such tricks in future.

Samuel Le Berrigaud link
10/28/2012 10:25:23 pm

Plan B will not work. The issue here is that there are multiple instances of Active Objects available throughout your product (be it JIRA, Confluence, etc.) instance.

Indeed there is one instance for each plugin using AO. However the ComponentManager#getOSGiComponentInstanceOfType does not know about those multiple instances and is expecting a singleton service. So it will never work.

Use plan C. ;-)

Side note. When using ComponentManager#getOSGiComponentInstanceOfType prefer using SAL's component locator (https://developer.atlassian.com/display/SAL/SAL+Services) which will work across all products.

Reply
J-Tricks
10/29/2012 01:48:55 am

Yup, Plan B won't work. If only it was that easy ;)

Thanks for the hint about SAL's component locator. That will make life eaiser for building plugins across apps.

Reply
Fatma
5/3/2013 02:46:35 am

teşekkürler

Reply
arthur
2/13/2014 09:03:20 pm

Hahaha! Very creative XD Plan C is beautiful

Reply
J-Tricks
2/14/2014 01:02:32 am

Works 99% of the times ;)

Reply
Sven link
3/18/2014 05:33:23 am

Hey Jobin,

I loved your book !

Could you please provide us a complete sample code for this ?

Regards,
Sven.

Reply
J-Tricks
3/31/2014 05:38:08 am

Hi,

Looks like the example I used in this post is missing. Are you stuck at some point? I can hopefully guide you if you have specific questions.

Glad to know you like the book :)

Reply
Tom Heideman
4/30/2015 02:35:51 pm

when you say in step 3, "Get an instance of the component in the service's run method using ComponentManager", what do you mean by "the service's run method"? Which method does this go in? is there literally a "run()" method that needs to be created in one of my classes?

Then in step 4, where should this code be?

Thanks

J-Tricks
5/2/2015 06:05:11 am

Yes, there is a 'run' method. Check out http://www.j-tricks.com/tutorials/jira-service for more details.

Jordan
6/26/2014 10:04:33 pm

Hello i try to do this but i have an error :

<component key="injection-ao" name="Injection ao" public="true">
<interface>com.atlassian.tutorial.helloworld.InjectionAo</interface>
<description>Injection ActiveObjects in service</description>
</component>

My log :

com.atlassian.plugin.util.validation.ValidationException: The class is required: <component key="injection-ao" name="Injection ao" public="true"><interface>com.atlassian.tutorial.helloworld.InjectionAo</interface><description>Injection ActiveObjects in service</description></component>
...

I don't know why because I have done all you have done in the same order.
Thanks

Reply
J-Tricks
6/27/2014 01:03:10 am

Give the fully qualified name of the class (that implements InjectionAo) as an attribute in the component definition. Something like the following:

<component key="injection-ao" name="Injection ao" class="com.atlassian.tutorial.helloworld.InjectionAoImpl" public="true">
<interface>com.atlassian.tutorial.helloworld.InjectionAo</interface>
<description>Injection ActiveObjects in service</description>
</component>

Reply
jordan
6/27/2014 01:37:46 am

Thanks a lot it works

Jira Plugin Developer
7/15/2014 01:50:01 am

What stands in the interface and where do you get it?
<interface>com.jtricks.manager.JTricksManager</interface>

Reply
J-Tricks
7/15/2014 02:25:49 am

Just the empty method:

public ActiveObjects getActiveObjects()

The class implements this interface.

Reply
Pavel
2/1/2016 05:57:10 am

What am I doing wrong? I still giving NPE.
JTricksManager - interface
JTricksManagerImpl - class

atlassian-plugin.xml:
<component key="jtricks-manager"
class="com.pavel.plugin.laboratory.JTricksManagerImpl"
name="J-Tricks Manager" public="true">
<interface>com.pavel.plugin.laboratory.JTricksManager</interface>
</component>

class:
public class MyPlugin extends JiraWebActionSupport {
JTricksManager jTricksManager;

public String doAdd() throws Exception {
if (this.jTricksManager == null)
this.jTricksManager = ComponentAccessor.getOSGiComponentInstanceOfType(JTricksManager.class);
jTricksManager.getActiveObjects(); // <----------NullPointException here
}
}

Thanks

Reply
J-Tricks
2/15/2016 09:52:42 pm

If you are using Atlassian Spring Scanner, that could be the issue. See http://www.j-tricks.com/tutorials/atlassian-spring-scanner-and-nosuchbeandefinitionexception for more details.

Reply
Nitin Prashar
9/13/2016 09:29:54 am

Hi tried your solution and want JtrickPluginManager dependency in Servlet.

Found error..."Unable to create new reference LazyLoadedServletReference{descriptor=com.atlassian.jira.demo.aoDemo:address-list (A servlet to add and list Address), servletContext=org.apache.catalina.core.ApplicationContextFacade@534b9782}"

Reply

Your comment will be posted after it is approved.


Leave a Reply.

    Enter your email address:

    Author

    Jobin Kuruvilla - Works in Adaptavist as Head of DevOps Professional Services. 

    Author of JIRA Development Cookbook and JIRA 5.x Development Cookbook.


    RSS Feed

    Categories

    All
    Acive Objects
    Ajs
    Book
    Components
    Condition
    Custom Fields
    Customization
    Events
    Gadgets
    Javascript
    Jql
    Listener
    Mail
    Permissions
    Plugin Framework
    Post Function
    Properties
    Remote Invocation
    Reporting
    Rest
    Scheduled Tasks
    Search
    Services
    Soap
    Summit
    User Interface
    Validator
    Webwork Actions
    Workflow

    Archives

    October 2016
    August 2016
    March 2016
    January 2016
    December 2015
    May 2014
    December 2013
    November 2013
    July 2013
    June 2013
    April 2013
    October 2012
    September 2012
    August 2012
    July 2012
    May 2012
    March 2012
    February 2012
    January 2012
    December 2011
    November 2011
    June 2011
    May 2011
    April 2011
    March 2011
    February 2011
    January 2011
    November 2010
    October 2010
    September 2010
    August 2010

SUPPORT
APPS
TUTORIALS
THE BOOK
© J-Tricks