Can't create JQL plugin

Hi everyone

I've just started learning how to create plugins for JIRA. I was trying to complete this tutorial but there are some errors and I don't know why it isn't working. My JIRA version is 7.2.6. Here is my code:

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.jira</groupId>
    <artifactId>jira-simple-jql-function</artifactId>
    <version>1.0-SNAPSHOT</version>
    <organization>
        <name>company</name>
        <url>http://www.google.com/</url>
    </organization>
    <name>jira-simple-jql-function</name>
    <description>Adds a custom JQL function named recentProjects to 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>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.6.6</version>
            <scope>provided</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>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>
					-->
                    <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.example.plugins.tutorial.jira.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.6</jira.version>
        <amps.version>6.2.6</amps.version>
        <plugin.testrunner.version>1.2.3</plugin.testrunner.version>
        <atlassian.spring.scanner.version>1.2.13</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>

atlassian-plugin.xml:

<?xml version="1.0" encoding="UTF-8"?>
<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="jira-simple-jql-function"/>
  <!-- add our web resources -->
  <web-resource key="jira-simple-jql-function-resources" name="jira-simple-jql-function Web Resources">
    <dependency>com.atlassian.auiplugin:ajs</dependency>
    <resource type="download" name="jira-simple-jql-function.css" location="/css/jira-simple-jql-function.css"/>
    <resource type="download" name="jira-simple-jql-function.js" location="/js/jira-simple-jql-function.js"/>
    <resource type="download" name="images/" location="/images"/>
    <context>jira-simple-jql-function</context>
  </web-resource>
  <jql-function name="Recent Project Function" i18n-name-key="recent-project-function.name" key="recent-project-function" class="com.example.plugins.tutorial.jira.jql.RecentProjectFunction">
    <description key="recent-project-function.description">The Recent Project Function Plugin</description>
    <fname>recentProjects</fname>
    <list>true</list>
  </jql-function>
</atlassian-plugin>

 

java class:

package com.example.plugins.tutorial.jira.jql;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.atlassian.jira.JiraDataType;
import com.atlassian.jira.JiraDataTypes;
import com.atlassian.jira.jql.operand.QueryLiteral;
import com.atlassian.jira.jql.query.QueryCreationContext;
import com.atlassian.jira.plugin.jql.function.AbstractJqlFunction;
import com.atlassian.jira.util.MessageSet;
import com.atlassian.jira.util.NotNull;
import com.atlassian.query.clause.TerminalClause;
import com.atlassian.query.operand.FunctionOperand;
import com.google.common.collect.Iterables;
import com.atlassian.jira.user.UserHistoryItem;
import com.atlassian.jira.user.UserProjectHistoryManager;
import java.util.LinkedList;
import java.util.Collections;
import java.util.List;
/**
 * Echoes the the string passed in as an argument.
 */
 @Scanned
 
public class RecentProjectFunction extends AbstractJqlFunction
{
    @ComponentImport
    private final UserProjectHistoryManager userProjectHistoryManager;
    
    public RecentProjectFunction(UserProjectHistoryManager userProjectHistoryManager)
    {
      this.userProjectHistoryManager = userProjectHistoryManager;
    }
    
    private static final Logger log = LoggerFactory.getLogger(RecentProjectFunction.class);
    public MessageSet validate(User searcher, FunctionOperand operand, TerminalClause terminalClause)
    {
        return validateNumberOfArgs(operand, 0);
    }
    public List<QueryLiteral> getValues(QueryCreationContext queryCreationContext, FunctionOperand operand, TerminalClause terminalClause)
    {
        final List<QueryLiteral> literals = new LinkedList<QueryLiteral>();
        final List<UserHistoryItem> projects = userProjectHistoryManager.getProjectHistoryWithoutPermissionChecks(queryCreationContext.getApplicationUser());
        
        for (final UserHistoryItem userHistoryItem : projects) {
        final String value = userHistoryItem.getEntityId();
        try {
            literals.add(new QueryLiteral(operand, Long.parseLong(value)));
        } catch (NumberFormatException e) {
            log.warn(String.format("User history returned a non numeric project IS '%s'.", value));
        }
    }
    return literals;
    }
    public int getMinimumNumberOfExpectedArguments()
    {
        return 0;
    }
    public JiraDataType getDataType()
    {
        return JiraDataTypes.PROJECT;
    }
}

 Errors:

Executing: /usr/share/atlassian-plugin-sdk-6.2.9/apache-maven-3.2.1/bin/mvn com.atlassian.maven.plugins:maven-amps-dispatcher-plugin:6.2.6:run -gs /usr/share/atlassian-plugin-sdk-6.2.9/apache-maven-3.2.1/conf/settings.xml
Java HotSpot(TM) 64-Bit Server VM warning: ignoring option MaxPermSize=256M; support was removed in 8.0
[INFO] Scanning for projects...
[INFO] 
[INFO] Using the builder org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder with a thread count of 1
[INFO]                                                                         
[INFO] ------------------------------------------------------------------------
[INFO] Building jira-simple-jql-function 1.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO] 
[INFO] >>> maven-amps-dispatcher-plugin:6.2.6:run (default-cli) @ jira-simple-jql-function >>>
[INFO] 
[INFO] --- maven-jira-plugin:6.2.6:compress-resources (default-compress-resources) @ jira-simple-jql-function ---
[WARNING] File encoding has not been set, using platform encoding UTF-8, i.e. build is platform dependent!
[INFO] Compiling javascript using YUI
[INFO] 0 Javascript file(s) were minified into target directory /home/kacperkoziel/plugin/jira-simple-jql-function/target/classes
[INFO] 0 CSS file(s) were minified into target directory /home/kacperkoziel/plugin/jira-simple-jql-function/target/classes
[INFO] Compressing XML files
[INFO] 0 XML file(s) were minified into target directory /home/kacperkoziel/plugin/jira-simple-jql-function/target/classes
[INFO] 
[INFO] --- maven-resources-plugin:3.0.2:resources (default-resources) @ jira-simple-jql-function ---
[WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] Copying 7 resources
[INFO] 
[INFO] --- maven-jira-plugin:6.2.6:filter-plugin-descriptor (default-filter-plugin-descriptor) @ jira-simple-jql-function ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 1 resource
[INFO] 
[INFO] --- maven-compiler-plugin:3.6.0:compile (default-compile) @ jira-simple-jql-function ---
[INFO] Changes detected - recompiling the module!
[WARNING] File encoding has not been set, using platform encoding UTF-8, i.e. build is platform dependent!
[INFO] Compiling 3 source files to /home/kacperkoziel/plugin/jira-simple-jql-function/target/classes
[INFO] /home/kacperkoziel/plugin/jira-simple-jql-function/src/main/java/com/example/plugins/tutorial/jira/jql/RecentProjectFunction.java: /home/kacperkoziel/plugin/jira-simple-jql-function/src/main/java/com/example/plugins/tutorial/jira/jql/RecentProjectFunction.java uses or overrides a deprecated API.
[INFO] /home/kacperkoziel/plugin/jira-simple-jql-function/src/main/java/com/example/plugins/tutorial/jira/jql/RecentProjectFunction.java: Recompile with -Xlint:deprecation for details.
[INFO] -------------------------------------------------------------
[ERROR] COMPILATION ERROR : 
[INFO] -------------------------------------------------------------
[ERROR] /home/kacperkoziel/plugin/jira-simple-jql-function/src/main/java/com/example/plugins/tutorial/jira/jql/RecentProjectFunction.java:[25,3] cannot find symbol
  symbol: class Scanned
[ERROR] /home/kacperkoziel/plugin/jira-simple-jql-function/src/main/java/com/example/plugins/tutorial/jira/jql/RecentProjectFunction.java:[40,32] cannot find symbol
  symbol:   class User
  location: class com.example.plugins.tutorial.jira.jql.RecentProjectFunction
[ERROR] /home/kacperkoziel/plugin/jira-simple-jql-function/src/main/java/com/example/plugins/tutorial/jira/jql/RecentProjectFunction.java:[30,6] cannot find symbol
  symbol:   class ComponentImport
  location: class com.example.plugins.tutorial.jira.jql.RecentProjectFunction
[INFO] 3 errors 
[INFO] -------------------------------------------------------------
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 2.254 s
[INFO] Finished at: 2016-12-15T05:28:07-08:00
[INFO] Final Memory: 31M/283M
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.6.0:compile (default-compile) on project jira-simple-jql-function: Compilation failure: Compilation failure:
[ERROR] /home/kacperkoziel/plugin/jira-simple-jql-function/src/main/java/com/example/plugins/tutorial/jira/jql/RecentProjectFunction.java:[25,3] cannot find symbol
[ERROR] symbol: class Scanned
[ERROR] /home/kacperkoziel/plugin/jira-simple-jql-function/src/main/java/com/example/plugins/tutorial/jira/jql/RecentProjectFunction.java:[40,32] cannot find symbol
[ERROR] symbol:   class User
[ERROR] location: class com.example.plugins.tutorial.jira.jql.RecentProjectFunction
[ERROR] /home/kacperkoziel/plugin/jira-simple-jql-function/src/main/java/com/example/plugins/tutorial/jira/jql/RecentProjectFunction.java:[30,6] cannot find symbol
[ERROR] symbol:   class ComponentImport
[ERROR] location: class com.example.plugins.tutorial.jira.jql.RecentProjectFunction
[ERROR] -> [Help 1]
[ERROR] 
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR] 
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoFailureException

 

 

Hope you can help me. 

Best regards.

Kacper

 

1 answer

Try removing @Scanned & @ComponentImport which are not longer needed and changing User class, because in JIRA 7 the correct class is ApplicationUser.

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
Julia Dillon
Posted Tuesday in Jira

Tell us how your team runs on Jira!

Hey Atlassian Community! Today we are launching a bunch of customer stories about the amazing work teams, like Dropbox and Twilio, are doing with Jira. You can check out the stories here. The thi...

225 views 1 18
Join discussion

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