Can't inject EntityLinkService, Plugin installer Error

Hi Atlassian Family,

I'm trying to inject EntityLinkService to my servlet module but i am getting this error: 

Plugin installer ERROR [c.a.p.osgi.factory.OsgiPlugin] Plugin 'tr.com.plugin.foo' never resolved service '&entityLinkService' with filter '(&(objectClass=com.atlassian.applinks.api.EntityLinkService)(objectClass=com.atlassian.applinks.api.EntityLinkService))

 

And also i cant use @Autowired annotation because package does not exist.

Can you help me solve my problem?

 

Here is my Servlet:

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

import javax.inject.Inject;
import javax.inject.Named;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.atlassian.applinks.api.ApplicationLinkRequestFactory;
import com.atlassian.applinks.api.EntityLink;
import com.atlassian.applinks.api.EntityLinkService;
import com.atlassian.applinks.api.application.bitbucket.BitbucketProjectEntityType;
import com.atlassian.jira.component.ComponentAccessor;
import com.atlassian.jira.project.Project;
import com.atlassian.plugin.spring.scanner.annotation.imports.ComponentImport;
import com.atlassian.templaterenderer.TemplateRenderer;

@Named
public class FooServlet extends HttpServlet{

private static final String VIEW_NAME = "template/fooservlet.vm";

private static final long serialVersionUID = 1L;
private static final Logger log = LoggerFactory.getLogger(ProjectMapperServlet.class);
public static Map<String, Object> context = new HashMap();
@ComponentImport
private TemplateRenderer templateRenderer;
@ComponentImport
private EntityLinkService entityLinkService;


@Inject
public ProjectMapperServlet(final TemplateRenderer templateRenderer, final EntityLinkService entityLinkService) {
this.templateRenderer = templateRenderer;
this.entityLinkService = entityLinkService;
}


@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
{
resp.setContentType("text/html;charset=utf-8");
List<Project> allProjectList = ComponentAccessor.getProjectManager().getProjectObjects();
Map<String, Project> projects= allProjectList.stream().collect(Collectors.toMap(Project::getName, Function.identity()));
context.put("project", allProjectList);
templateRenderer.render(VIEW_NAME, context, resp.getWriter());
}

Here is my pom.xml

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.plugin</groupId>
<artifactId>foo</artifactId>
<version>1.0.8</version>
<organization>
<name>myName</name>
<url>http://www.foo.com.tr/</url>
</organization>
<name></name>
<description>This is the plugin for Atlassian JIRA.</description>
<packaging>atlassian-plugin</packaging>
<dependencies>
<dependency>
<groupId>com.atlassian.jira</groupId>
<artifactId>jira-api</artifactId>
<version>${jira.version}</version>
<scope>provided</scope>
</dependency>
<!-- Add dependency on jira-core if you want access to JIRA implementation classes as well as the sanctioned API. -->
<!-- This is not normally recommended, but may be required eg when migrating a plugin originally developed against JIRA 4.x -->
<!--
<dependency>
<groupId>com.atlassian.jira</groupId>
<artifactId>jira-core</artifactId>
<version>${jira.version}</version>
<scope>provided</scope>
</dependency>
-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.atlassian.plugin</groupId>
<artifactId>atlassian-spring-scanner-annotation</artifactId>
<version>${atlassian.spring.scanner.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.atlassian.plugin</groupId>
<artifactId>atlassian-spring-scanner-runtime</artifactId>
<version>${atlassian.spring.scanner.version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>1</version>
<scope>provided</scope>
</dependency>
<!-- WIRED TEST RUNNER DEPENDENCIES -->
<dependency>
<groupId>com.atlassian.plugins</groupId>
<artifactId>atlassian-plugins-osgi-testrunner</artifactId>
<version>${plugin.testrunner.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.ws.rs</groupId>
<artifactId>jsr311-api</artifactId>
<version>1.1.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.2.2-atlassian-1</version>
</dependency>
<!-- Uncomment to use TestKit in your project. Details at https://bitbucket.org/atlassian/jira-testkit -->
<!-- You can read more about TestKit at https://developer.atlassian.com/display/JIRADEV/Plugin+Tutorial+-+Smarter+integration+testing+with+TestKit -->
<!--
<dependency>
<groupId>com.atlassian.jira.tests</groupId>
<artifactId>jira-testkit-client</artifactId>
<version>${testkit.version}</version>
<scope>test</scope>
</dependency>
-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.4</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.6.6</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.1.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
<version>1.8.5</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.atlassian.templaterenderer</groupId>
<artifactId>atlassian-template-renderer-api</artifactId>
<scope>provided</scope>
<version>3.0.0</version>
<type>atlassian-plugin</type>
</dependency>
<dependency>
<groupId>com.atlassian.applinks</groupId>
<artifactId>applinks-api</artifactId>
<version>5.0.3</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.2</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>com.atlassian.maven.plugins</groupId>
<artifactId>maven-jira-plugin</artifactId>
<version>${amps.version}</version>
<extensions>true</extensions>
<configuration>
<productVersion>${jira.version}</productVersion>
<productDataVersion>${jira.version}</productDataVersion>
<!-- Uncomment to install TestKit backdoor in JIRA. -->
<!--
<pluginArtifacts>
<pluginArtifact>
<groupId>com.atlassian.jira.tests</groupId>
<artifactId>jira-testkit-plugin</artifactId>
<version>${testkit.version}</version>
</pluginArtifact>
</pluginArtifacts>
-->
<skipManifestValidation>true</skipManifestValidation>
<enableQuickReload>true</enableQuickReload>
<enableFastdev>false</enableFastdev>
<!-- See here for an explanation of default instructions: -->
<!-- https://developer.atlassian.com/docs/advanced-topics/configuration-of-instructions-in-atlassian-plugins -->
<instructions>
<Atlassian-Plugin-Key>${atlassian.plugin.key}</Atlassian-Plugin-Key>
<!-- Add package to export here -->
<Export-Package>com.plugin.api,</Export-Package>
<!-- Add package import here -->
<Import-Package>org.springframework.osgi.*;resolution:="optional", org.eclipse.gemini.blueprint.*;resolution:="optional", *</Import-Package>
<!-- Ensure plugin is spring powered -->
<Spring-Context>*</Spring-Context>
</instructions>
</configuration>
</plugin>
<plugin>
<groupId>com.atlassian.plugin</groupId>
<artifactId>atlassian-spring-scanner-maven-plugin</artifactId>
<version>${atlassian.spring.scanner.version}</version>
<executions>
<execution>
<goals>
<goal>atlassian-spring-scanner</goal>
</goals>
<phase>process-classes</phase>
</execution>
</executions>
<configuration>
<scannedDependencies>
<dependency>
<groupId>com.atlassian.plugin</groupId>
<artifactId>atlassian-spring-scanner-external-jar</artifactId>
</dependency>
</scannedDependencies>
<verbose>false</verbose>
</configuration>
</plugin>
</plugins>
</build>
<properties>
<jira.version>7.2.2</jira.version>
<amps.version>6.2.11</amps.version>
<plugin.testrunner.version>1.2.3</plugin.testrunner.version>
<atlassian.spring.scanner.version>2.1.3</atlassian.spring.scanner.version>
<!-- This key is used to keep the consistency between the key in atlassian-plugin.xml and the key to generate bundle. -->
<atlassian.plugin.key>${project.groupId}.${project.artifactId}</atlassian.plugin.key>
<!-- TestKit version 6.x for JIRA 6.x -->
<testkit.version>6.3.11</testkit.version>
</properties>
</project>

 

1 answer

1 accepted

1 vote
Alexey Matveev Community Champion Nov 10, 2017

Hello,

Change the constructor line with the following

 @Inject 
public ProjectMapperServlet(@ComponentImport final TemplateRenderer templateRenderer, @ComponentImport final EntityLinkService entityLinkService) {
this.templateRenderer = templateRenderer;
this.entityLinkService = entityLinkService;
}

should i delete other @componentImport annotations above the variables?

Alexey Matveev Community Champion Nov 10, 2017

Yes,  you should

Thank you for helping.

Bu still getting the same error.

Alexey Matveev Community Champion Nov 10, 2017

Just to make sure execute

Atlas-mvn clean package

Here is the command line error.PNG

Alexey Matveev Community Champion Nov 10, 2017

Ok. I guess the problem is here

<dependency>
<groupId>com.atlassian.applinks</groupId>
<artifactId>applinks-api</artifactId>
<version>5.0.3</version>
<scope>provided</scope>
</dependency>

The scope must be provided. Also in pom.xml the following dependency is missing

<dependency>
<groupId>com.atlassian.templaterenderer</groupId>
<artifactId>atlassian-template-renderer-api</artifactId>
<version>1.3.1</version>
<scope>provided</scope>
</dependency>

 

Also your servlet class must be called ProjectMapperServlet not FooServlet. I made it work in my Jira. Make the changes and I am sure it will work for you

Alexey Matveev Community Champion Nov 10, 2017
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.*;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

import javax.inject.Inject;
import javax.inject.Named;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.atlassian.applinks.api.ApplicationLinkRequestFactory;
import com.atlassian.applinks.api.EntityLink;
import com.atlassian.applinks.api.EntityLinkService;
import com.atlassian.applinks.api.application.bitbucket.BitbucketProjectEntityType;
import com.atlassian.jira.component.ComponentAccessor;
import com.atlassian.jira.project.Project;
import com.atlassian.plugin.spring.scanner.annotation.imports.ComponentImport;
import com.atlassian.templaterenderer.TemplateRenderer;

@Named
public class ProjectMapperServlet extends HttpServlet {

private static final String VIEW_NAME = "template/fooservlet.vm";

private static final long serialVersionUID = 1L;
private static final Logger log = LoggerFactory.getLogger(ProjectMapperServlet.class);
public static Map<String, Object> context = new HashMap();

private TemplateRenderer templateRenderer;

private EntityLinkService entityLinkService;


@Inject
public ProjectMapperServlet( @ComponentImport final TemplateRenderer templateRenderer, @ComponentImport final EntityLinkService entityLinkService) {
this.templateRenderer = templateRenderer;
this.entityLinkService = entityLinkService;
}


@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html;charset=utf-8");
List<Project> allProjectList = ComponentAccessor.getProjectManager().getProjectObjects();
Map<String, Project> projects = allProjectList.stream().collect(Collectors.toMap(Project::getName, Function.identity()));
context.put("project", allProjectList);
templateRenderer.render(VIEW_NAME, context, resp.getWriter());
}
}

It worked. Thanks a lot, much appreciated.

But why we did the scope provided?

In future cases which dependencies' scopes should we change as provieded?

Alexey Matveev Community Champion Nov 10, 2017

Provided  means that the library already exists in Jira. If you do not put scope then this library will be extracted in your jar. The library in your jar is not initialized properly that is why you had this error.

If Jira does not provide a library which you use, you need to extract it your jar. That is why this option depends on what you need.

Suggest an answer

Log in or Sign up to answer
Atlassian Community Anniversary

Happy Anniversary, Atlassian Community!

This community is celebrating its one-year anniversary and Atlassian co-founder Mike Cannon-Brookes has all the feels.

Read more
Community showcase
Fadoua M. Boualem
Published Monday in Trello

Using Trello to manage events

As a Jira power user, I was at first doubtful that Trello could benefit my workflow. Jira already uses boards (ones you can customize!), so why would I even need to use Trello?! In this post you will...

505 views 8 9
Read article

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