How to create Service in Jira Plugin? (with details)

Acroo April 20, 2017

 


Hello to all dear friends. 
This is the third question on this topic.

I try create Service with JIRA 5.X Development Cookbook

So this is really a copy of what is written in the book, because I want to see how it works and after that add my logic.

JTricksService

 

package services;

import com.atlassian.configurable.ObjectConfiguration;
import com.atlassian.configurable.ObjectConfigurationException;
import com.atlassian.jira.service.AbstractService;
import com.opensymphony.module.propertyset.PropertySet;

public class JTricksService extends AbstractService {

private static final String TUTORIAL = "Tutorial";

private String tutorial;

@Override
public void init(PropertySet props) throws ObjectConfigurationException {
super.init(props);

if (hasProperty(TUTORIAL)) {
tutorial = getProperty(TUTORIAL);
} else {
tutorial = "I don't like tutorials!";
}

}

@Override
public void run() {
System.out.println("Running the JTricks service!! Tutorial? " + tutorial);
}

@Override
public void destroy() {
System.out.println("Let me do this before destory!");
super.destroy();
}

public ObjectConfiguration getObjectConfiguration() throws ObjectConfigurationException {
return getObjectConfiguration("MYNEWSERVICE", "com/jtricks/services/myjtricksservice.xml", null);
}

}
 

 

myjtricksservice.xml

<someservice id="jtricksserviceid">
<description>My New Service</description>
<properties>
<property>
<key>Tutorial</key>
<name>The tutorial you like</name>
<type>string</type>
</property>
</properties>
</someservice>


 

atlassian-plugin.xml

<atlassian-plugin key="${atlassian.plugin.key}" name="${project.name}" plugins-version="2">
<plugin-info>
<description>${project.description}</description>
<version>${project.version}</version>
<vendor name="${project.organization.name}" url="${project.organization.url}" />
<param name="plugin-icon">images/pluginIcon.png</param>
<param name="plugin-logo">images/pluginLogo.png</param>
</plugin-info>

<!-- add our i18n resource -->
<resource type="i18n" name="i18n" location="testservice"/>

<!-- add our web resources -->
<web-resource key="testservice-resources" name="testservice Web Resources">
<dependency>com.atlassian.auiplugin:ajs</dependency>

<resource type="download" name="testservice.css" location="/css/testservice.css"/>
<resource type="download" name="testservice.js" location="/js/testservice.js"/>
<resource type="download" name="images/" location="/images"/>

<context>testservice</context>
</web-resource>

</atlassian-plugin>
 

 

 

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>akrotov</groupId>
<artifactId>testservice</artifactId>
<version>1.0.0-SNAPSHOT</version>

<organization>
<name>Example Company</name>
<url>http://www.example.com/</url>
</organization>

<name>testservice</name>
<description>This is the akrotov:testservice 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>

<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>

<dependency>
<groupId>javax.ws.rs</groupId>
<artifactId>jsr311-api</artifactId>
<version>1.1.1</version>
<scope>provided</scope>
</dependency>

</dependencies>

<build>
<plugins>
<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>
<enableQuickReload>true</enableQuickReload>
<enableFastdev>false</enableFastdev>
<instructions>
<Atlassian-Plugin-Key>${atlassian.plugin.key}</Atlassian-Plugin-Key>
<Export-Package>
akrotov.api,
</Export-Package>
<Import-Package>
org.springframework.osgi.*;resolution:="optional",
org.eclipse.gemini.blueprint.*;resolution:="optional",
*
</Import-Package>
<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>1.2.13</atlassian.spring.scanner.version>
<atlassian.plugin.key>${project.groupId}.${project.artifactId}</atlassian.plugin.key>
<testkit.version>6.3.11</testkit.version>
</properties>

</project>

 


On the output, I want to get messages like: "Running the JTricks service !! Tutorial?"

Github: https://github.com/arkrotov/atlassian-study



 

 

 

 

 


Question:
What is the problem? Where was I wrong?

1 answer

1 accepted

1 vote
Answer accepted
Jobin Kuruvilla [Adaptavist]
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.
April 20, 2017

First of all, you are posting the entire copy righted content in your question. Please remove the screenshots and explain what "you did".

Secondly, translate the error to English so that majority of us can understand it and try to help.

Thanks.

Btw, I am th author of the book. I am more than happy to help but please tell us what you did and not what is in the book. I know that works and it is also tested by reviwers but there must be something different you are doing or in the settings.

Acroo April 20, 2017

The screenshots show the steps from the book and what I do.

Steps 1-4. I create a plugin and compile it into a jar file ( <packaging>atlassian-plugin</packaging>). The structure and code are shown in the screenshots.

Step 5. I load my plugin through the UPM.

Step 6.  I'm trying to find the class (JTricksService) in Services project and i get an error. 

Class [com.atlassian.jira.services.JTricksService] Not found. I'm sure that you introduced it correctly, and it is in the way of the class.


Maybe I'm doing something wrong. But the clear explanation of the process ends in the fifth step in your book.

Thanks.

Jobin Kuruvilla [Adaptavist]
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.
April 20, 2017

Can you replace the screenshots with the code you have written? As I mentioned before, it is copy righted content.

And regarding the error, it looks like you class is under a different package?

Acroo April 20, 2017

So this is really a copy of what is written in the book, because I want to see how it works and after that add my logic.

 

JTricksService

ackage services;

import com.atlassian.configurable.ObjectConfiguration;
import com.atlassian.configurable.ObjectConfigurationException;
import com.atlassian.jira.service.AbstractService;
import com.opensymphony.module.propertyset.PropertySet;

public class JTricksService extends AbstractService {

 private static final String TUTORIAL = "Tutorial";

 private String tutorial;

 @Override
 public void init(PropertySet props) throws ObjectConfigurationException {
  super.init(props);

  if (hasProperty(TUTORIAL)) {
   tutorial = getProperty(TUTORIAL);
  } else {
   tutorial = "I don't like tutorials!";
  }

 }

 @Override
 public void run() {
  System.out.println("Running the JTricks service!! Tutorial? " + tutorial);
 }
 
 @Override
 public void destroy() {
  System.out.println("Let me do this before destory!");
  super.destroy();
 }

 public ObjectConfiguration getObjectConfiguration() throws ObjectConfigurationException {
  return getObjectConfiguration("MYNEWSERVICE", "com/jtricks/services/myjtricksservice.xml", null);
 }

}

 

 

myjtricksservice.xml

 

<someservice id="jtricksserviceid">
    <description>My New Service</description>
    <properties>
     <property>
   <key>Tutorial</key>
   <name>The tutorial you like</name>
   <type>string</type>
  </property>
    </properties>
</someservice>

 

atlassian-plugin.xml

 

<atlassian-plugin key="${atlassian.plugin.key}" name="${project.name}" plugins-version="2">
    <plugin-info>
        <description>${project.description}</description>
        <version>${project.version}</version>
        <vendor name="${project.organization.name}" url="${project.organization.url}" />
        <param name="plugin-icon">images/pluginIcon.png</param>
        <param name="plugin-logo">images/pluginLogo.png</param>
    </plugin-info>

    <!-- add our i18n resource -->
    <resource type="i18n" name="i18n" location="testservice"/>
    
    <!-- add our web resources -->
    <web-resource key="testservice-resources" name="testservice Web Resources">
        <dependency>com.atlassian.auiplugin:ajs</dependency>
        
        <resource type="download" name="testservice.css" location="/css/testservice.css"/>
        <resource type="download" name="testservice.js" location="/js/testservice.js"/>
        <resource type="download" name="images/" location="/images"/>

        <context>testservice</context>
    </web-resource>
    
</atlassian-plugin>

 

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>akrotov</groupId>
    <artifactId>testservice</artifactId>
    <version>1.0.0-SNAPSHOT</version>

    <organization>
        <name>Example Company</name>
        <url>http://www.example.com/</url>
    </organization>

    <name>testservice</name>
    <description>This is the akrotov:testservice 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>
        
        <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>

        <dependency>
            <groupId>javax.ws.rs</groupId>
            <artifactId>jsr311-api</artifactId>
            <version>1.1.1</version>
            <scope>provided</scope>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <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>
                    <enableQuickReload>true</enableQuickReload>
                    <enableFastdev>false</enableFastdev>
                    <instructions>
                        <Atlassian-Plugin-Key>${atlassian.plugin.key}</Atlassian-Plugin-Key>
                        <Export-Package>
                            akrotov.api,
                        </Export-Package>
                        <Import-Package>
                            org.springframework.osgi.*;resolution:="optional",
                            org.eclipse.gemini.blueprint.*;resolution:="optional",
                            *
                        </Import-Package>
                        <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>1.2.13</atlassian.spring.scanner.version>
        <atlassian.plugin.key>${project.groupId}.${project.artifactId}</atlassian.plugin.key>
        <testkit.version>6.3.11</testkit.version>
    </properties>

</project>

On the output, I want to get messages like: "Running the JTricks service !! Tutorial?"

Github: https://github.com/arkrotov/atlassian-study

Jobin Kuruvilla [Adaptavist]
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.
April 20, 2017

I can see what you are doing wrong. However, can you replace the book screenshots in your question with the code you pasted here?

 

Acroo April 20, 2017

Ok, I did it

Jobin Kuruvilla [Adaptavist]
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.
April 20, 2017

Great, thanks. It looks like you are trying to add com.atlassian.jira.services.JTricksService as the service but your class is created in services package.

Can you try to add services.JTricksService instead?

Also, make sure the path: com/jtricks/services/myjtricksservice.xml is valid. I see that you removed screenshots of your code as well :)

Acroo April 20, 2017

Can you try to add services.JTricksService instead? - It's work!

Thank you very much helped me. I'll go on to study the material of your book.

P.S. The path to the class is not well-defined in the book. Only with your help did I understand this topic

 

Jobin Kuruvilla [Adaptavist]
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.
April 20, 2017

Sorry that it isn't obvious. It is actually described in the JIRA documentation.

Step 3 at https://confluence.atlassian.com/adminjiraserver071/services-802592250.html#Services-editing_service_propertiesRegisteringaservice

I will make it a point to explain it in the next version. Glad you got it working!

Ana Gonzalez February 27, 2018

Suggest an answer

Log in or Sign up to answer