Forums

Articles
Create
cancel
Showing results for 
Search instead for 
Did you mean: 

the @Scanned cannot use and cannot import the jar

white October 18, 2022
@Scanned
public class IssueCRUD extends HttpServlet{
private static final Logger log = LoggerFactory.getLogger(IssueCRUD.class);

@JiraImport
private IssueService issueService;
@JiraImport
private ProjectService projectService;
@JiraImport
private SearchService searchService;

the @Scanned cannot use and cannot import the jar

 

1 answer

1 accepted

0 votes
Answer accepted
Radek Dostál
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.
October 18, 2022

Without pom.xml we have no idea about how your plugin handles dependencies.

As far as I know, no Jira plugin requires @Scanned anotations, because everything is "@Scanned" automatically.

Lastly, you do not just "import" a dependency - you need to route it via a constructor.

If you stick with the atl. tutorials https://developer.atlassian.com/server/framework/atlassian-sdk/create-a-helloworld-plugin-project you will find how to structure it.

Sadly, those tutorials are largely outdated, do not match current SDK versions, so it's quite a frustration to get the ropes, but in majority the information there is correct, you're usually looking at differences between versions.

white October 19, 2022

Thank you for your response, Firstly.In the develop ways,It is a little sad that those tutorials are largely outdated, do not match current SDK versions.

In some tutorials.I find the @Scanned cannot work well.

Here are 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.example.plugins.tutorial</groupId>
<artifactId>tutorial-jira-simple-issue-crud</artifactId>
<version>1.0.0-SNAPSHOT</version>
<organization>
<name>Example Company</name>
<url>http://www.example.com/</url>
</organization>
<name>tutorial-jira-simple-issue-crud</name>
<description>This plugin demonstrates how to perform basic CRUD operations on JIRA Issues using the IssueService and SearchService interface through a servlet module.</description>
<packaging>atlassian-plugin</packaging>
<dependencies>
<dependency>
<groupId>com.atlassian.templaterenderer</groupId>
<artifactId>atlassian-template-renderer-api</artifactId>
<version>2.0.0</version>
<scope>provided</scope>
</dependency>
<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>provided</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>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>com.atlassian.maven.plugins</groupId>
<artifactId>jira-maven-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>
-->
<enableQuickReload>true</enableQuickReload>
<!-- 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.example.plugins.tutorial.api,
com.atlassian.plugin.spring.scanner,
com.atlassian.plugin.spring.scanner.annotation.component,
com.atlassian.plugin.spring.scanner.annotation.export,
com.atlassian.plugin.spring.scanner.annotation.imports,
com.atlassian.plugin.spring.scanner.annotation,
<!-- CommonConstants is not meant as API, but I don't want to add another module
just to share this one class between build-time scanners and runtime -->
com.atlassian.plugin.spring.scanner.util
</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>
<verbose>false</verbose>
</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>
<!-- process-classes seems to be skipped if you are using scala
so perhaps use prepare-package -->
<phase>process-classes</phase>
</execution>
</executions>
<configuration>
<!-- Enable this to get build-time logging of annotations atlassian-spring-scanner-maven-plugin has noticed -->
<verbose>false</verbose>
</configuration>
</plugin>
</plugins>
</build>
<properties>
<jira.version>7.13.0</jira.version>
<amps.version>8.1.2</amps.version>
<plugin.testrunner.version>2.0.2</plugin.testrunner.version>
<atlassian.spring.scanner.version>2.1.7</atlassian.spring.scanner.version>
<!-- This property ensures consistency between the key in atlassian-plugin.xml and the OSGi bundle's key. -->
<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>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
</project>

 

Radek Dostál
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.
October 20, 2022 edited

Alright, cool. Mostly I was looking for the spring scanner version, because most tutorials are built with 1.x even though 2.x is out for years.

 

Now, take the following with a grain of salt, this is just what I think:

 

The old '<atlassian.spring.scanner.version>' 1.x is pain and suffering, because you had to manually declare your Jira dependencies, which was both annoying, and made a disgusting clutter in the plugin's module list.

Since you have 2.x, we don't have to worry about it and we can just use any dependencies from Jira we need, and spring scanner will provide them to us.

 

So the following should be working:

public class TestConfigurationPage extends HttpServlet {

@ComponentImport private final TemplateRenderer templateRenderer;
private final AOManager aoManager;

public TestConfigurationPage(TemplateRenderer templateRenderer, AOManager aoManager) {
this.templateRenderer = templateRenderer;
this.aoManager = aoManager;
}

//whatever other methods, doGet, doPost, etc.
}

 

This is where the spring scanner comes in. When we install the plugin, it will start instantiating our classes and it will be routing dependencies into constructors.

Note that the 'AOManager' is a class in this plugin, which is why it needs no annotation. Because of the dependency on it, AOManager will be initialized first, then TestConfigurationPage will be initialized after it, with the instance of AOManager being injected into it's constructor via spring.

The dependency from Jira is annotated with @ComponentImport - this is the same as @JiraImport in your example, but the difference is you can use the same annotation in Confluence as well (I think other atl. apps too, but not sure). This is what tells spring to get this from Jira and if Jira has such a thing, then spring will route it to the constructor.

 

Source of info: https://bitbucket.org/atlassian/atlassian-spring-scanner/src/master/README.md

white October 20, 2022

Cool,Thank you my friends 

Suggest an answer

Log in or Sign up to answer