Last updated Apr 19, 2024

JIRA Developer Documentation : Creating a JIRA SOAP Client

This page has been archived, as it does not apply to the latest version of JIRA (Server or Cloud). The functionality described on this page may be unsupported or may not be present in JIRA at all.

JIRA's SOAP and XML-RPC remote APIs were removed in JIRA 7.0 for Server ( see announcement). We encourage you to use JIRA's REST APIs to interact with JIRA remotely (see migration guide).

Applicable:

This tutorial applies to JIRA 4.3 and higher.

Level of experience:

This is an intermediate tutorial. You should have completed at least one beginner tutorial before working through this tutorial. See the list of tutorials in DAC.

Time estimate:

It should take you approximately 1 hour to complete this tutorial.

Overview of the tutorial

JIRA presents a SOAP interface that client applications can use to invoke JIRA operations remotely. A client application can use the SOAP interface to perform operations such as creating, modifying, and reading JIRA issues.

This document illustrates the use of the JIRA SOAP API to create a remote JIRA client application. However, if developing for JIRA 5.0 or later, we recommend that you use the REST API instead. See JIRA RPC Services for usage guidelines on the remote access APIs in JIRA.

As an alternative to developing client applications against the SOAP API directly, as described in this tutorial, you can use the SOAP API through a client wrapper library instead, such as the JIRA SOAP library. This alleviates you from needing to compile and code against the WSDL directly.

Plugin source

We encourage you to work through this tutorial. If you want to skip ahead or check your work when you have finished, you can find the plugin source code on Atlassian Bitbucket. Bitbucket serves a public Git repository containing the tutorial's code. To clone the repository, issue the following command:

git clone https://bitbucket.org/atlassian_tutorial/jira-java-soap-client

Alternatively, you can download the source using the get source option here: https://bitbucket.org/atlassian_tutorial/jira-java-soap-client.

Environment used in the tutorial

To keep things simple, the client you build in this tutorial invokes operations in a local, developer instance of JIRA. You will install it using the Atlassian SDK. The following instructions use SDK version 4.1, which installs JIRA version 5.1.6 by default. To see Javadoc for this version, see our reference documentation page. If creating an application intended for another version, refer to the JIRA Javadoc for your version. The SOAP API is exposed in JIRA by the RPC JIRA plugin.

The tutorial code relies on Maven 2. If you have the Atlassian SDK, you already have Maven 2. Before starting, make sure you have Maven 2 and, if necessary, install it. 

These instructions use Linux OS for its command examples. The exact commands you need to enter may differ depending on your operating system.

Step 1. Install and configure the local JIRA instance

Start by installing and setting up a local JIRA instance using the Atlassian SDK:

  1. Open a terminal window and run the following command: atlas-run-standalone --product jira The  command downloads and starts a developer's instance of JIRA. This takes a few moments to finish.

  2. When JIRA finishes starting up, open a browser and log in to JIRA using the default administrator account. The default username and password are admin/admin. 

  3. Create a new project named TST. This is the name of the project in which our client application will create issues. Note that, to keep the client code simple, both the name of the project and credentials for the SOAP client user are hard-coded into the client code.

  4. Create a user for the application with the username and password of soaptester.

  5. Open the Administration Console and make sure that the RPC JIRA plugin is present and enabled. Client application invoke SOAP methods through the RPC JIRA plugin. Since JIRA 4.3, the RPC plugin is included and enabled by default in JIRA. You can verify the RPC JIRA Plugin on your instance in the 'Manage Add-ons' page. On the page, expand the System Plugin list and search for 'RPC JIRA plugin'.

  6. Before deploying to a production system, you would also need to ensure that JIRA is configured to accept remote API calls has been enabled. This option appears in the Options list on the System > General Configuration page. It is enabled by default in the JIRA developer instance installed by the SDK.

JIRA is now ready to go.

Step 2. Create the SOAP client project 

From the command line:

  1. Create the project directory that will contain your SOAP client source code and resource files using the following command: mkdir soap_client_jira

  2. Change to the soap_client_jira directory and create a new file named pom.xml, and add to it the following code:

    1
    2
    <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>
        <parent>
            <groupId>com.atlassian.pom</groupId>
            <artifactId>atlassian-public-pom</artifactId>
            <version>23</version>
        </parent>
    
        <groupId>com.atlassian.jira.plugins</groupId>
        <artifactId>atlassian-jira-rpc-parent</artifactId>
        <version>4.1-SNAPSHOT</version>
        <packaging>pom</packaging>
    
        <name>JIRA RPC parent POM</name>
        <description>Contains the JIRA RPC plugin and a sample soap client.</description>
    
        <modules>
            <module>jira-soapclient</module>
        </modules>
    
        <build>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <configuration>
                        <fork>true</fork>
                        <meminitial>128m</meminitial>
                        <maxmem>512m</maxmem>
                    </configuration>
                </plugin>
            </plugins>
        </build>
    
        <properties>
            <jdkLevel>1.6</jdkLevel>
            <jira.version>5.2</jira.version>
            <jira.data.version>5.2</jira.data.version>
        </properties>
    </project>
    

    This will be the parent POM for the Java SOAP client module, jira-soapclient. This makes it easier to expand the project later.

  3. Now, in the same directory, create a new directory for the SOAP client module as follows: mkdir jira-soapclient

  4. In the new directory, create a new file named pom.xml and add the following text to the file:

    1
    2
    <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>
        <parent>
            <groupId>com.atlassian.jira.plugins</groupId>
            <artifactId>atlassian-jira-rpc-parent</artifactId>
            <version>4.1-SNAPSHOT</version>
        </parent>
        <groupId>com.atlassian.jira.plugins</groupId>
        <artifactId>jira-soapclient</artifactId>
        <name>JIRA SOAP Client</name>
        <description>A plugin which provides a sample SOAP implementation.</description>
    
        <repositories>
          <repository>
             <id>atlassian</id>
             <name>Atlassian Repository</name>
             <url>https://maven.atlassian.com/content/groups/public</url>
          </repository>
        </repositories>
    
        <pluginRepositories>
           <pluginRepository>
                    <id>atlassian</id>
                    <name>Atlassian Repository</name>
                    <url>https://maven.atlassian.com/content/groups/public</url>
           </pluginRepository>
        </pluginRepositories>
        <build>
            <plugins>
                <plugin>
                    <groupId>org.codehaus.mojo</groupId>
                    <artifactId>axistools-maven-plugin</artifactId>
                    <version>1.3</version>
                    <dependencies>
                        <dependency>
                            <groupId>axis</groupId>
                            <artifactId>axis</artifactId>
                            <version>1.3</version>
                        </dependency>
                    </dependencies>
                    <configuration>
                        <wsdlFiles>
                            <wsdlFile>jirasoapservice-v2.wsdl</wsdlFile>
                        </wsdlFiles>
                        <packageSpace>com.atlassian.jira.rpc.soap.client</packageSpace>
                    </configuration>
                    <executions>
                        <execution>
                            <id>wsdl2java-generation</id>
                            <phase>generate-sources</phase>
                            <goals>
                                <goal>wsdl2java</goal>
                            </goals>
                        </execution>
                    </executions>
                </plugin>
                <plugin>
                    <artifactId>maven-assembly-plugin</artifactId>
                    <configuration>
                        <descriptorRefs>
                            <descriptorRef>jar-with-dependencies</descriptorRef>
                        </descriptorRefs>
                        <archive>
                            <manifest>
                                <addClasspath>true</addClasspath>
                                <mainClass>com.atlassian.jira_soapclient.SOAPClient</mainClass>
                            </manifest>
                        </archive>
                    </configuration>
                </plugin>
            </plugins>
        </build>
        <profiles>
            <profile>
                <id>buildclient</id>
                <build>
                    <defaultGoal>assembly:assembly</defaultGoal>
                </build>
            </profile>
            <profile>
                <id>fetch-wsdl</id>
                <build>
                    <defaultGoal>generate-sources</defaultGoal>
                    <plugins>
                        <plugin>
                            <artifactId>maven-antrun-plugin</artifactId>
                            <executions>
                                <execution>
                                    <phase>generate-sources</phase>
                                    <goals>
                                        <goal>run</goal>
                                    </goals>
                                    <configuration>
                                        <tasks>
                                            <get src="${jira.soapclient.jiraurl}/rpc/soap/jirasoapservice-v2?wsdl"
                                                 dest="${basedir}/src/main/wsdl/jirasoapservice-v2.wsdl"/>
                                        </tasks>
                                    </configuration>
                                </execution>
                            </executions>
                            <dependencies>
                                <dependency>
                                    <groupId>axis</groupId>
                                    <artifactId>axis-ant</artifactId>
                                    <version>1.3</version>
                                </dependency>
                            </dependencies>
                        </plugin>
                    </plugins>
                </build>
                <properties>
                    <jira.soapclient.jiraurl>http://hostname:2990/jira</jira.soapclient.jiraurl>
                </properties>
            </profile>
        </profiles>
    
        <dependencies>
            <dependency>
                <groupId>axis</groupId>
                <artifactId>axis</artifactId>
                <version>1.3</version>
            </dependency>
            <dependency>
                <groupId>axis</groupId>
                <artifactId>axis-jaxrpc</artifactId>
                <version>1.3</version>
            </dependency>
            <dependency>
                <groupId>axis</groupId>
                <artifactId>axis-saaj</artifactId>
                <version>1.3</version>
            </dependency>
            <dependency>
                <groupId>axis</groupId>
                <artifactId>axis-wsdl4j</artifactId>
                <version>1.5.1</version>
                <scope>compile</scope>
            </dependency>
        </dependencies>
    </project>
    
  5. Replace myhost in the jira.soapclient.jiraurl element with the host name of your JIRA instance.

  6. Create directories under the jira-soapclient directory to form the following source file path: src/main/java/com/atlassian/jira_soapclient/

  7. In the new jira_soapclient directory under src, create the file SOAPSessions.java and add the following code:

    1
    2
    package com.atlassian.jira_soapclient;
    import com.atlassian.jira.rpc.soap.client.JiraSoapService;
    import com.atlassian.jira.rpc.soap.client.JiraSoapServiceService;
    import com.atlassian.jira.rpc.soap.client.JiraSoapServiceServiceLocator;
    import java.net.URL;
    import java.rmi.RemoteException;
    import javax.xml.rpc.ServiceException;
    /**
     * This represents a SOAP session with JIRA including that state of being logged in or not
     */
    public class SOAPSession
    {
        private JiraSoapServiceService jiraSoapServiceLocator;
        private JiraSoapService jiraSoapService;
        private String token;
        public SOAPSession(URL webServicePort)
        {
            jiraSoapServiceLocator = new JiraSoapServiceServiceLocator();
            try
            {
                if (webServicePort == null)
                {
                    jiraSoapService = jiraSoapServiceLocator.getJirasoapserviceV2();
                }
                else
                {
                    jiraSoapService = jiraSoapServiceLocator.getJirasoapserviceV2(webServicePort);
                    System.out.println("SOAP Session service endpoint at " + webServicePort.toExternalForm());
                }
            }
            catch (ServiceException e)
            {
                throw new RuntimeException("ServiceException during SOAPClient contruction", e);
            }
        }
        public SOAPSession()
        {
            this(null);
        }
        public void connect(String userName, String password) throws RemoteException
        {
            System.out.println("\tConnnecting via SOAP as : " + userName);
            token = getJiraSoapService().login(userName, password);
            System.out.println("\tConnected");
        }
        public String getAuthenticationToken()
        {
            return token;
        }
        public JiraSoapService getJiraSoapService()
        {
            return jiraSoapService;
        }
        public JiraSoapServiceService getJiraSoapServiceLocator()
        {
            return jiraSoapServiceLocator;
        }
    }
    

    SOAPSession.java handles the connection to the JIRA SOAP service. 

  8. In the same directory, create the file SOAPClient.java and add the following code:

    1
    2
    package com.atlassian.jira_soapclient;
    
    import com.atlassian.jira.rpc.soap.client.RemoteComment;
    import com.atlassian.jira.rpc.soap.client.RemoteComponent;
    import com.atlassian.jira.rpc.soap.client.RemoteCustomFieldValue;
    import com.atlassian.jira.rpc.soap.client.RemoteFilter;
    import com.atlassian.jira.rpc.soap.client.RemoteIssue;
    import com.atlassian.jira.rpc.soap.client.RemoteVersion;
    import com.atlassian.jira.rpc.soap.client.JiraSoapService;
    import com.atlassian.jira.rpc.soap.client.RemoteProject;
    
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileWriter;
    import java.io.IOException;
    import java.io.InputStream;
    import java.lang.reflect.InvocationTargetException;
    import java.lang.reflect.Method;
    import java.net.URL;
    import java.rmi.RemoteException;
    import java.text.DecimalFormat;
    import java.util.Calendar;
    import java.util.Date;
    
    public class SOAPClient
    {
        static final String LOGIN_NAME = "soaptester";
        static final String LOGIN_PASSWORD = "soaptester";
        static final String PROJECT_KEY = "TST";
        static final String ISSUE_TYPE_ID = "1";
        static final String SUMMARY_NAME = "An issue created via the JIRA SOAPClient sample : " + new Date();
        static final String PRIORITY_ID = "4";
        static final String NEW_COMMENT_BODY = "This is a new comment";
    
        public static void main(String[] args) throws Exception
        {
            String baseUrl = "http://hostname:2990/jira/rpc/soap/jirasoapservice-v2";
            System.out.println("JIRA SOAP client sample");
            SOAPSession soapSession = new SOAPSession(new URL(baseUrl));
            soapSession.connect(LOGIN_NAME, LOGIN_PASSWORD);
            JiraSoapService jiraSoapService = soapSession.getJiraSoapService();
            String authToken = soapSession.getAuthenticationToken();
            RemoteIssue issue = testCreateIssue(jiraSoapService, authToken);
        }
    
        private static RemoteIssue testCreateIssue(JiraSoapService jiraSoapService, String token)
                throws java.rmi.RemoteException
        {
            System.out.println("CreateIssue");
                RemoteIssue issue = new RemoteIssue();
                issue.setProject(PROJECT_KEY);
                issue.setType(ISSUE_TYPE_ID);
                issue.setSummary(SUMMARY_NAME);
                issue.setPriority(PRIORITY_ID);
                issue.setDuedate(Calendar.getInstance());
                issue.setAssignee("");
    
                // Run the create issue code
                RemoteIssue returnedIssue = jiraSoapService.createIssue(token, issue);
                final String issueKey = returnedIssue.getKey();
    
                System.out.println("\tSuccessfully created issue " + issueKey);
                printIssueDetails(returnedIssue);
                return returnedIssue;
        }
    
        private static void printIssueDetails(RemoteIssue issue)
        {
            System.out.println("Issue Details : ");
            Method[] declaredMethods = issue.getClass().getDeclaredMethods();
            for (int i = 0; i < declaredMethods.length; i++)
            {
                Method declaredMethod = declaredMethods[i];
                if (declaredMethod.getName().startsWith("get") && declaredMethod.getParameterTypes().length == 0)
                {
                    System.out.print("\t Issue." + declaredMethod.getName() + "() -> ");
                    try
                    {
                        Object obj = declaredMethod.invoke(issue, new Object[] { });
                        if (obj instanceof Object[])
                        {
                            obj = arrayToStr((Object[]) obj);
                        }
                        else
                        {
                        }
                        System.out.println(obj);
                    }
                    catch (IllegalAccessException e)
                    {
                        e.printStackTrace();
                    }
                    catch (InvocationTargetException e)
                    {
                        e.printStackTrace();
                    }
                }
            }
        }
    
        private static String arrayToStr(Object[] o)
        {
            StringBuffer sb = new StringBuffer();
            for (int i = 0; i < o.length; i++)
            {
                sb.append(o[i]).append(" ");
            }
            return sb.toString();
        }
    
        private static byte[] getBytesFromFile(File file) throws IOException
        {
            InputStream is = new FileInputStream(file);
    
            long length = file.length();
            if (length < Integer.MAX_VALUE)
            {
                byte[] bytes = new byte[(int) length];
                int offset = 0;
                int numRead;
                while (offset < bytes.length && (numRead = is.read(bytes, offset, bytes.length - offset)) >= 0)
                {
                    offset += numRead;
                }
    
                if (offset < bytes.length)
                {
                    throw new IOException("Could not completely read file " + file.getName());
                }
    
                is.close();
                return bytes;
            }
            else
            {
                System.out.println("File is too large");
                return null;
            }
        }
    }
    

    Note that the class defines a few constants it will use for the new JIRA issues. The class does just a few things:

    • Connects to the JIRA instance.

    • Establishes an authenticated session.

    • Creates an issue.

  9. Replace hostname in the baseUrl value assignment with the host name of your JIRA instance. For example:

    1
    2
    String baseUrl = "http://jira-host:2990/jira/rpc/soap/jirasoapservice-v2";
    
  10. Verify that your JIRA instance is serving the WSDL properly by opening the following URL in a browser: http://hostname:2990/jira/rpc/soap/jirasoapservice-v2?wsdl Replace 'hostname' with the hostname appropriate for your JIRA instance. To run our client application, we will need access to this WSDL.

  11. Create a new directory named wsdl at the following location under your project home: /jira-soapclient/src/main/wsdl

That's it! You can now test out the client application.

Step 3. Run the application

Give your application a try:

  1. In the jira-soapclient directory under your project home, run the following command: mvn -Pfetch-wsdl -Djira.soapclient.jiraurl=http://hostname:2990/jira Replace hostname in jiraurl with the one appropriate for your JIRA instance.

    To use the Maven executable included in the Atlassian SDK, prepend atlas- to the Maven command. For example: atlas-mvn -Pfetch-wsdl -Djira.soapclient.jiraurl=http://hostname:2990/jira 

  2. Build the client application: mvn -Pbuildclient

  3. Now run the client application: mvn exec:java -Dexec.mainClass="com.atlassian.jira_soapclient.SOAPClient"

If successful, you should see a message similar to the following in the screen output.

1
2
...
SOAP Session service endpoint at http://atlas-laptop:2990/jira/rpc/soap/jirasoapservice-v2
    Connnecting via SOAP as : soaptester
    Connected
CreateIssue
    Successfully created issue TST-17
...

After the success message, the print out includes details for the new issues. If you navigate to the project in JIRA, you'll see the newly created issue. Each time you execute the command, the client application creates a new issue.

 

Rate this page: