Create
cancel
Showing results for 
Search instead for 
Did you mean: 
Sign up Log in

Next challenges

Recent achievements

  • Global
  • Personal

Recognition

  • Give kudos
  • Received
  • Given

Leaderboard

  • Global

Trophy case

Kudos (beta program)

Kudos logo

You've been invited into the Kudos (beta program) private group. Chat with others in the program, or give feedback to Atlassian.

View group

It's not the same without you

Join the community to find out what other Atlassian users are discussing, debating and creating.

Atlassian Community Hero Image Collage

Dependency Injection in Service constructor not working?

Deleted user Jun 21, 2018

In my JIRA plugin, I want to implement a service (which can be scheduled via the Services admin interface) which shall receive required objects via constructor injection, e.g. like this:

@ExportAsService
public class MyPluginService extends AbstractService {

private final SomeHelloWorldInterface helloWorld;

@Inject
public MyPluginService(final SomeHelloWorldInterface helloWorld) {
this.helloWorld = helloWorld;
}

An implementation is also present within my plugin:

@JiraComponent
public class SomeHelloWorldClass implements SomeHelloWorldInterface {

@Override
public String sayHelloWorld() {
return "Hello World!";
}

}

Unfortunately, when trying to activate this as a Service, I receive this error:

  • Error adding service: org.picocontainer.injectors.AbstractInjector$UnsatisfiableDependenciesException: com.....impl.MyPluginService has unsatisfied dependency 'interface com.....api.SomeHelloWorldInterface' for constructor 'public com.....impl.MyPluginService(com....api.SomeHelloWorldInterface)' from org.picocontainer.DefaultPicoContainer@7ba6a405:1<[Immutable]:com.atlassian.jira.component.CachingMutablePicoContainer@466051b1.

For whatever reason, the dependency from the Service to the (plugin-internal) component cannot be resolved. I tried several different annotations (e.g. @Autowired), but to no avail.

Any idea what I am doing wrong here? Or does @ExportAsService block plugin-internal dependency resolution?

3 answers

1 accepted

1 vote
Answer accepted
Deleted user Jul 05, 2018

I found the "solution", or at least the root cause, myself. 

If one uses the "Services" functionality of JIRA, the given class name is instantiated within the Pico IoC container context only. This means, no Spring resolution available.

To access and autowire a component scanned by Spring within your service's constructor, use this:

ComponentAccessor.getOSGiComponentInstanceOfType(SomeHelloWorldInterface.class);

Standard JIRA components can, of course, be autowired as usual (as they are available via the Pico container).

This only took one week to be discovered and understood. I'd appreciate if this was documented e.g. in the Javadoc of AbstractService.

1 vote

Try to do like this

@ExportAsService
@Named

public class MyPluginService extends AbstractService {

private final SomeHelloWorldInterface helloWorld;

@Inject
public MyPluginService(final SomeHelloWorldInterface helloWorld) {
this.helloWorld = helloWorld;
}

 

@Named
public class SomeHelloWorldClass implements SomeHelloWorldInterface {

@Override
public String sayHelloWorld() {
return "Hello World!";
}

}
Deleted user Jun 21, 2018

Thanks for your suggestion! Unfortunately, exactly the same effect.

This works. Thanks @Alexey Matveev _cPrime_  you saved me so much time. Cheers!

Hi everyone, I'm writing a custom Jira plugin of type Service.

I have

@Named
@ExportAsService
public class ENGSLAService extends AbstractService {

@JiraImport
private JqlQueryParser jqlQueryParser;

@JiraImport
private SearchService searchService;

private InsightReader insightReader;

@Inject
public ENGSLAService(JqlQueryParser jqlQueryParser, SearchService searchService) {

this.jqlQueryParser = jqlQueryParser;
this.searchService = searchService;
this.insightReader = ComponentAccessor.getOSGiComponentInstanceOfType(InsightReader.class);
log.warn("insightReader is " + insightReader);
}

...

}
@JiraComponent
public class InsightReader {

@JiraImport
private ObjectFacade objectFacade;
@JiraImport
private IQLFacade iqlFacade;

...

}

Basically I don't know how I can initialize a InsightReader's object inside my ENGSLAService constructor. I tryied different arrangements with annotations and non-empty constructor in InsightReader's class but nothing seems to work. Sometimes I get a PicoContainer Exception, sometimes (like for the above code) the object of type InsightReader is null after invoking ComponentAccessor.getOSGiComponentInstanceOfType. I probably messed up with Spring/OSGi annotations. Could you please suggest how to make it work?

Thank you

Suggest an answer

Log in or Sign up to answer
TAGS

Community Events

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

Find an event

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

Unfortunately there are no Community Events near you at the moment.

Host an event

You're one step closer to meeting fellow Atlassian users at your local event. Learn more about Community Events

Events near you