Creating a XML-RPC Client

JIRA Documentation

Index

JIRA 3.0 and above ships with the JIRA XML-RPC Plugin which enables remote access through XML-RPC and SOAP. Utilising this feature with XML-RPC couldn't be much easier with some help from the Apache XML-RPC package. In this tutorial, we write a basic XML-RPC client (using Apache XML-RPC) that logs in, retrieves projects and then log out again. A Python client is also demonstrated.

You may also be interested in the Creating a SOAP Client (more methods are exposed via SOAP than XML-RPC).

Getting the latest XML-RPC client

You can download the latest XML-RPC client with the JIRA Plugin Development Kit

Enabling the RPC plugin

The methods exposed via XML-RPC are listed in the RPC plugin Javadoc for the XmlRpcService class. The JIRA XML-RPC API Spec has more information (though not guaranteed to be up-to-date).

To run the Java client in this tutorial, you'll need to download the Apache XML-RPC libraries and make it available in your classpath.

You should also ensure that the XML-RPC plugin has is enabled on the JIRA installation you are targeting. If you simply want to create a client to http://jira.atlassian.com/ then you can skip this step. First you need to check if the Accept Remote API Calls has been enabled in the General Configuration tab under Global Settings.

Then you need to enable the JIRA RPC Plugin as below.

If the plugin does not appear as above then your XML-RPC jar has not been properly installed. Download the jar from the repository and copy it to the atlassian-jira/WEB-INF/lib folder of your JIRA installation. Perform a restart and your plugin should appear

Now that your server is ready to accept remote procedure calls, we begin creating a Java XML-RPC client.

Python XML-RPC client

XML-RPC in Python is very easy. Here is a sample client that creates test issues on http://jira.atlassian.com:

#!/usr/bin/python

# Sample Python client accessing JIRA via XML-RPC. Methods requiring
# more than basic user-level access are commented out.
#
# Refer to the XML-RPC Javadoc to see what calls are available:
# http://docs.atlassian.com/software/jira/docs/api/rpc-jira-plugin/latest/com/atlassian/jira/rpc/xmlrpc/XmlRpcService.html

import xmlrpclib

s = xmlrpclib.ServerProxy('http://jira.atlassian.com/rpc/xmlrpc')
#s = xmlrpclib.ServerProxy('http://192.168.0.87:8080/rpc/xmlrpc')
auth = s.jira1.login('xmlrpctester', 'xmlrpctester')

newissue = s.jira1.createIssue(auth, { 'project': 'TST', 'type': 2,
        'summary': 'Issue created via XML-RPC', 'description': 'Created with a Python client'})

print "Created %s/browse/%s" % (s.jira1.getServerInfo(auth)['baseUrl'], newissue['key'])

print "Commenting on issue.."
s.jira1.addComment(auth, newissue['key'], 'Comment added with XML-RPC')

print "Modifying issue..."
s.jira1.updateIssue(auth, newissue['key'], {
                "summary": ["[Updated] issue created via XML-RPC"],

                # Setting a custom field. The id (10010) is discoverable from
                # the database or URLs in the admin section

                "customfield_10010": ["Random text set in updateIssue method"],

                # Demonstrate setting a cascading selectlist:
                "customfield_10061": ["10098"],
                "customfield_10061_1": ["10105"],
                "components": ["10370"]

                })


print "Done!"

Java client

The goal of this tutorial is to create a client that makes three simple remote calls to JIRA. Here we login, retrieve the project information and then logout again. You can take a look at the full source code here (xmlrpc-2.x) or here (xmlrpc-3.x).

The first step is to configure your details.

public static final String JIRA_URI  = "http://jira.atlassian.com";
public static final String RPC_PATH  = "/rpc/xmlrpc";
public static final String USER_NAME = "enteryourlogin@atlassian.com";
public static final String PASSWORD  = "yourpassword";

All XML-RPC calls are invoked at with the path /rpc/xmlrpc by default. You need to configure your username and password appropriately.

// Initialise RPC Client
XmlRpcClient rpcClient = new XmlRpcClient(JIRA_URI + RPC_PATH);

// Login and retrieve logon token
Vector loginParams = new Vector(2);
loginParams.add(USER_NAME);
loginParams.add(PASSWORD);
String loginToken = (String) rpcClient.execute("jira1.login", loginParams);

Method calls to JIRA via XML-RPC need to be prefixed with "jira1.". Parameters to methods are passed as sequenced Objects in a Vector. In the above code, we log into jira.atlassian.com. We receive back a loginToken which will need to be passed to all subsequent method calls.

// Retrieve projects
Vector loginTokenVector = new Vector(1);
loginTokenVector.add(loginToken);
List projects = (List)rpcClient.execute("jira1.getProjects", loginTokenVector);

// Print projects
for (Iterator iterator = projects.iterator(); iterator.hasNext();)
{
    Map project =  (Map) iterator.next();
    System.out.println(project.get("name") + " with lead " + project.get("lead"));
}

The RPC client calls the getProjects method passing the loginToken. This returns with a Vector of projects which are represented by HashTable objects. For information on what methods are available as well as what properties are available on returned projects, you'll again need to look at the JIRA XML-RPC API Spec.

// Log out
Boolean bool = (Boolean) rpcClient.execute("jira1.logout", loginTokenVector);
System.out.println("Logout successful: " + bool);

Lastly, we log out of the system, again passing the loginToken in a Vector form.

There it is! A simple client for JIRA XML-RPC. If you wish to extend or customize the JIRA XML-RPC plugin itself, you can download the latest source from the repository.

Perl Client

Here's an XMLRPC client that uses the XMLRPC::Lite module (distributed with ActivePerl and available for free on CPAN).

#!/usr/bin/perl

# toy jira perl client using XMLRPC
# logs in, creates an issue
# handles failure or prints issue fields
# logs out.

use strict;
use warnings;

use XMLRPC::Lite;
use Data::Dumper;

my $jira = XMLRPC::Lite->proxy('http://localhost:8080/jira/rpc/xmlrpc');
my $auth = $jira->call("jira1.login", "admin", "admin")->result();
my $call = $jira->call("jira1.createIssue", $auth, {
    'project' => 'CEL',
    'type' => 2,
    'summary' => 'Issue created via XMLRPC',
    'assignee' => 'admin',
    'description' => 'Created with a Perl client'});
my $fault = $call->fault();
if (defined $fault) {
    die $call->faultstring();
} else {
    print "issue created:\n";
    print Dumper($call->result());
}
$jira->call("jira1.logout", $auth);

XMLRPC::Lite is poorly documented, using it for this simple example required reading the code - it is not advised for newbie perl hackers.

See also

Creating a SOAP Client

Labels:

Enter labels to add to this page:
Wait Image 
Looking for a label? Just start typing.
  1. Mar 14, 2006

    Adam Downer says:

    It would be nice to see an XMLRPC client written in Perl. I have tried to confer...

    It would be nice to see an XML-RPC client written in Perl. I have tried to confert the python one but am not having too much success.

  2. May 12, 2006

    David Blevins says:

    I've created a Java client for the Jira XMLRPC that is strongly typed and open s...

    I've created a Java client for the Jira XMLRPC that is strongly typed and open source so it can be included in other open source and proprietary projects.

    Example: http://docs.codehaus.org/display/SWIZZLE/Swizzle+Jira
    Library: http://repository.codehaus.org/org/codehaus/swizzle/swizzle-jira/
    Javadoc: http://swizzle.codehaus.org/swizzle-jira/
    Source: http://cvs.codehaus.org/viewrep/swizzle/trunk/swizzle-jira/

  3. Aug 07, 2006

    David Blevins says:

    Added a new tool to the set that makes reporting from Jira as easy as it could p...

    Added a new tool to the set that makes reporting from Jira as easy as it could possibly be. You only need to supply a Velocity template. Works with XML-RPC or RSS.

    To try it out:

    Try this:

    $ wget http://repository.codehaus.org/org/codehaus/swizzle/swizzle-jirareport/1.0/swizzle-jirareport-1.0-nodep.jar
    $ java -jar swizzle-jirareport-1.0-nodep.jar http://svn.codehaus.org/swizzle/tags/swizzle-jirareport-1.0/src/test/resources/jirarss.vm
    $ java -jar swizzle-jirareport-1.0-nodep.jar http://svn.codehaus.org/swizzle/tags/swizzle-jirareport-1.0/src/test/resources/jiraxmlrpc.vm

  4. Dec 20, 2006

    Test User says:

    Hi , I am trying to update my issue summary using XMLRPC calls but its not worki...

    Hi ,

    I am trying to update my issue summary using XML-RPC calls but its not working.Following is my code.

          Hashtable updateIssueHash = new Hashtable();
          String  issueSummary="Updated Issue Summary";
          updateIssueHash.put("summary", issueSummary);
          updateIssueHash.put("description", issueDescription);
          updateIssueHash.put("priority", issuePriority);
      
             XmlRpcClient rpcClient = new XmlRpcClient("http://jira.atlassian.com/rpc/xmlrpc");
             //Procedure for login
                        Vector loginParams = new Vector(2);
             loginParams.add("soaptester");
             loginParams.add("soaptester");
            String loginToken = (String)rpcClient.execute("jira1.login", loginParams);
                  
            Vector UpdateParams=new Vector();
            UpdateParams.add(loginToken);
            UpdateParams.add(issKey);
           UpdateParams.add(updateIssueHash);
                       
           rpcClient.execute("jira1.updateIssue", UpdateParams);
                       
                       
           Vector loginTokenVector = new Vector(1);
           loginTokenVector.add(loginToken);
           Boolean bool = (Boolean)rpcClient.execute("jira1.logout", loginTokenVector);
                       
           statMessage = "The issue is updated";

    Its not giving any error but also not updating the issue.What may be the cause for this?

     
    Thanks!

    Amar

    1. Dec 21, 2006

      Yuen-Chi Lian says:

      Hello Amar, The function is expecting each entry as a {{Vector}}, e.g. {{issueS...

      Hello Amar,

      The function is expecting each entry as a Vector, e.g. issueSummary should be put into a "length-1" Vector.

      Please refer to this page for some information about updating an issue via XMLRPC:

      Cheers,
      Yuen-Chi Lian

  5. Feb 12, 2007

    Pablo Costa says:

    Java Client Hello everybody! The example was not working for me, perhaps someth...

    Java Client

    Hello everybody!

    The example was not working for me, perhaps something got out of date as org.apache.xmlrpc evolved. It would be great if someone at Atlassian confirmed this and/or updated the article accordingly. Thank you very much!

    I had to add three JARs to the project. Find them at http://ws.apache.org/xmlrpc/

    • xmlrpc-client-3.0.jar
    • xmlrpc-common-3.0.jar
    • ws-commons-util-1.0.1.jar

    And the client works a bit different, this is what I had to change to get the sample working:

    package jiraxmlrpc;
    
    import java.io.IOException;
    import java.net.MalformedURLException;
    import java.net.URL;
    import java.util.Iterator;
    import java.util.List;
    import java.util.Map;
    import java.util.Vector;
    import org.apache.xmlrpc.client.XmlRpcClient;
    import org.apache.xmlrpc.XmlRpcException;
    import org.apache.xmlrpc.client.XmlRpcClientConfigImpl;
    
    public class Main
    {
        public static final String JIRA_URI  = "http://jira.atlassian.com";
        public static final String RPC_PATH  = "/rpc/xmlrpc";
        public static final String USER_NAME = "****";
        public static final String PASSWORD  = "****";
    
        public static void main(String[] args)
        {
            try
            {
                XmlRpcClient rpcClient;
                XmlRpcClientConfigImpl config;
                
                config = new XmlRpcClientConfigImpl();
                config.setServerURL(new URL(JIRA_URI + RPC_PATH));
                rpcClient = new XmlRpcClient();
                rpcClient.setConfig(config);
    
    
                // Login and retrieve logon token
                Vector loginParams = new Vector(2);
                loginParams.add(USER_NAME);
                loginParams.add(PASSWORD);
                String loginToken = (String) rpcClient.execute("jira1.login", loginParams);
    
                // Retrieve projects
                Vector loginTokenVector = new Vector(1);
                loginTokenVector.add(loginToken);
                Object stuff = rpcClient.execute("jira1.getProjects", loginTokenVector);
                Object [] projects = (Object [])rpcClient.execute("jira1.getProjects", loginTokenVector);
    
                // Print projects
                for (int i=0; i < projects.length; i++)
                {
                    Map project = (Map)projects[i];
                    System.out.println("KEY: " + project.get("key") + "\tNAME: " + project.get("name") + "\tLEAD: " + project.get("lead"));
                }
    
                // Log out
                Boolean bool = (Boolean) rpcClient.execute("jira1.logout", loginTokenVector);
                System.out.println("Logout successful: " + bool);
    
            }
            catch (MalformedURLException e)
            {
                e.printStackTrace();
            }
            catch (IOException e)
            {
                e.printStackTrace();
            }
            catch (XmlRpcException e)
            {
                e.printStackTrace();
            }
    
        }
    
    }
    
    1. Feb 12, 2007

      Yuen-Chi Lian says:

      Hello Pablo, Thanks for the update. I have updated the attachments with both xm...

      Hello Pablo,

      Thanks for the update. I have updated the attachments with both xmlrpc-2.x and xmlrpc-3.x compatible Java source files: xmlrpc-2.x | xmlrpc-3.x

      Cheers,
      Yuen-Chi Lian

  6. May 23, 2007

    Baerrach bonDierne says:

    I struggled with working out how to update versions like, fixVersion etc. The d...

    I struggled with working out how to update versions like, fixVersion etc.

    The documentation at http://www.atlassian.com/software/jira/docs/api/rpc-jira-plugin/latest/ seems to indicate that http://www.atlassian.com/software/jira/docs/api/rpc-jira-plugin/latest/com/atlassian/jira/rpc/xmlrpc/JiraXmlRpcService.html#updateIssue(java.lang.String,%20java.lang.String,%20java.util.Hashtable) expects a hash table matching http://www.atlassian.com/software/jira/docs/api/rpc-jira-plugin/latest/com/atlassian/jira/rpc/soap/beans/RemoteIssue.html.

    But fixVersions are listed as http://www.atlassian.com/software/jira/docs/api/rpc-jira-plugin/latest/com/atlassian/jira/rpc/soap/beans/RemoteVersion.html#RemoteVersion().

    The python example above uses:
    "components": ["10370"]
    where the component id is obtainable via getComponents().

    Likewise for versions.
    "fixVersions" : ["<version id>","<version id2>"]
    where the version id is obtainable via getVersions()

  7. Jun 07, 2007

    jian zhang says:

    Hi,&nbsp; Pablo Costa That code is not working for me.&nbsp; rpcClient.execute("...

    Hi,  Pablo Costa

    That code is not working for me.  rpcClient.execute("jira1.login", loginParams) pulls out the login page and fail when parse it.  Is there someway to turn off the xml validator.

     Thanks a lot

     --Jian

     <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
    <head>
    <TITLE>Log On</TITLE>
    ..

    [Fatal Error] :1:63: White spaces are required between publicId and systemId.
    org.apache.xmlrpc.client.XmlRpcClientException: Failed to parse servers response: White spaces are required between publicId and systemId.
            at org.apache.xmlrpc.client.XmlRpcStreamTransport.readResponse(XmlRpcStreamTransport.java:177)
            at org.apache.xmlrpc.client.XmlRpcStreamTransport.sendRequest(XmlRpcStreamTransport.java:145)
            at org.apache.xmlrpc.client.XmlRpcHttpTransport.sendRequest(XmlRpcHttpTransport.java:94)
            at org.apache.xmlrpc.client.XmlRpcSunHttpTransport.sendRequest(XmlRpcSunHttpTransport.java:39)
            at org.apache.xmlrpc.client.XmlRpcClientWorker.execute(XmlRpcClientWorker.java:53)
            at org.apache.xmlrpc.client.XmlRpcClient.execute(XmlRpcClient.java:166)
            at org.apache.xmlrpc.client.XmlRpcClient.execute(XmlRpcClient.java:157)
            at org.apache.xmlrpc.client.XmlRpcClient.execute(XmlRpcClient.java:146)
            at Main.main(Main.java:39)

  8. Jul 17, 2007

    Mark Derricutt says:

    Will progressWorkflowAction() be available from the XML RPC client any time soon...

    Will progressWorkflowAction() be available from the XML RPC client any time soon at all?  Or is there another way to progress a work flow via rpc?

  9. Feb 05, 2008

    Wiesław says:

    Any one knows if it is possible to connect to jira trught XML RPC when jira is o...

    Any one knows if it is possible to connect to jira trught XML RPC when jira is on https?

    Are there any problems to do it?

    1. Feb 18, 2008

      Igor V Demin says:

      Probably, It can require certificate installation (adding to keystore) or use th...

      Probably, It can require certificate installation (adding to keystore) or use this string:

              System.setProperty("javax.net.ssl.trustStore", "<path to certificate *.jks>");

  10. Feb 29, 2008

    Valentyn Gatsuk says:

    ORIGINAL POST: It would be nice if your examples actually worked. Python script ...

    ORIGINAL POST:

    It would be nice if your examples actually worked.

    Python script as written doesn't update custom field values for me. I've tried everything... Am I the only one who can't update customfields via xmlrpc?

    Using soap is not an option for me

    CORRECTION:

    Python script does work, but only if you associate correct screen type for that issue for that custom field. Otherwise xmlrpc happily ignores the update. Took me forever to chase it down. How come I can change a customfield from inside my java plugin but not via xmlrpc? Sounds like a bug to me.

  11. Feb 29, 2008

    amit mitra says:

    Hi to all, &nbsp;&nbsp;&nbsp; Can anybody help me to create isssue in JIRA throu...

    Hi to all,

        Can anybody help me to create isssue in JIRA through XML-RPC client In JAVA.It was working before assing Custom field  in JIRA.

    But after adding custom field its throwinig the Infrastructure Exception....

    Can any body tell me  the code  *or  *indentify the errors in this code...

    -------------------------------------------------------------------------------------------------------------------------------String proj=new String("MP");
    String typ=new String("1");String summ=new String("Created after reducing JAR file");
    String pri=new String("2");String rep=new String("amitmitra83");
    String desc=new String("test for error");String asign=new String("amitmitra83");
    String cstid0=new String("customfield_10000");String cstid1=new String("customfield_10001");String cstid2=new String("customfield_10002");
    String cstval0=new String("Always");String cstval1=new String("S3");
    String cstval2=new String("234"); Hashtable issue = new Hashtable();
    issue.put("project",proj);issue.put("type", typ);
    issue.put("summary", summ);issue.put("priority", pri);
    issue.put("reporter",rep);issue.put("description",desc);issue.put("assignee", asign); Vector cust_fld=new Vector();
    Hashtable Custom_fields = new Hashtable();Custom_fields.put("customfieldId",cstid0);Custom_fields.put("values",cstval0);
    cust_fld.add(Custom_fields);

    Custom_fields = new Hashtable();
    Custom_fields.put("customfieldId",cstid1);Custom_fields.put("values",cstval1);
    cust_fld.add(Custom_fields);

    Custom_fields = new Hashtable();
    Custom_fields.put("customfieldId",cstid2);Custom_fields.put("values",cstval2);
    cust_fld.add(Custom_fields);

    issue.put("customFieldValues", cust_fld); Vector NewParams=new Vector();
    NewParams.add(loginToken);

    NewParams.add(issue);Object objIssues = rpcClient.execute("jira1.createIssue", NewParams);System.out.println("Returned issue key: " + objIssues);
    ------------------------------------------------------------------------------------------------------------------------------------------------------------------

    Please Help..................................

    Thanks in Advance

    1. Feb 29, 2008

      Valentyn Gatsuk says:

      Amit, Not sure if this will help, but...&nbsp; &nbsp;Try assigning customfields ...

      Amit,

      Not sure if this will help, but... 

       Try assigning customfields the same way you assign summary, so issue.put("customfield_10210", new String("you custom string value"))

      Hope this helps. Also see my comment above - to be able to update customfield via xmlrpc it seems like you need to associate correct screens with it for your issue.

    2. Mar 31

      Steven Rowland says:

      customFieldValues Solution Hey Amit, I had the same problem but was able to fig...

      customFieldValues Solution

      Hey Amit, I had the same problem but was able to figure it out by looking at the source code. Apparently a String[] is needed for the "values" key. If you change your code to the following it should work:

      Custom_fields = new Hashtable();
      
      Custom_fields.put("customfieldId",cstid1);Custom_fields.put("values", new String[]{cstval1});
      
      cust_fld.add(Custom_fields);

      -cheers 

      The following code listed below is what worked for me:

      Hashtable issues = new Hashtable();
      
      Hashtable custom_field_one = new Hashtable();
      custom_field_one.put("customfieldId", "customfield_10000");
      custom_field_one.put("values", new String[]{"super duper company"});
      
      Hashtable custom_field_two = new Hashtable();
      custom_field_two.put("customfieldId", "customfield_10001");
      custom_field_two.put("values", new String[]{"45"});
      
      Vector vect = new Vector(2);
      vect.add(custom_field_one);
      vect.add(custom_field_two);
      
      issues.put("customFieldValues", vect);