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:
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?
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.
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!";
}
}
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Thanks for your suggestion! Unfortunately, exactly the same effect.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
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
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.