Java XML-RPC 3.1.x based web service example


Most of the examples of Java XML-RPC based Web Services are of older versions (apache xml-rpc 1.x or 2.x), most of the methods are deprecated and the programs don't work. So I am creating a simple backbone for XML-RPC based web service based on latest available i.e. Apache 3.1.3 version (last binaries dated 2013-01-31) to get started.

My System Configuration:
Eclipse Mars IDE
Java 7 version
JBoss 7.1 Application Server
Mac OS X 10.10.3 Operating system
1. Firstly you will need all the jars, somehow all the links that I got were throwing 404, until I found the correct link : https://archive.apache.org/dist/ws/xmlrpc/binaries/, just download apache-xmlrpc-3.1.3-bin.tar.bz2 or apache-xmlrpc-3.1.3-bin.zip . 2. Now extract the files we will need all jars from apache-xmlrpc-3.1.3 -> lib
commons-logging-1.1.jar
ws-commons-util-1.0.2.jar
xmlrpc-client-3.1.3.jar
xmlrpc-common-3.1.3.jar
xmlrpc-server-3.1.3.jar
3. Create a new Dynamic Web Project: XmlRPC3Example in Eclipse. 4. Add all the jar mentioned above to project by: Right Click on Project -> Properties -> Java Build Path -> Libraries -> Add External Jars. 5. Now create a package : org.code2care.rpc and create Class file : HelloWorld.java,
package org.code2care.rpc;

import java.net.URL;

import org.apache.xmlrpc.client.XmlRpcClient;
import org.apache.xmlrpc.client.XmlRpcClientConfigImpl;


public class JavaWsClient {
   public static void main (String [] args) {
   
   
	   try {
			System.out.println("XML-RPC Client call to : http://localhost:1080/xmlrpc/xmlrpc");
			XmlRpcClientConfigImpl config = new XmlRpcClientConfigImpl();
			config.setServerURL(new URL(
					"http://localhost:1080/xml-rpc-example/xmlrpc"));
			XmlRpcClient client = new XmlRpcClient();
			client.setConfig(config);
			Object[] params = new Object[] { "Chris Martin" };
			String response = (String) client.execute("HelloWorld.message", params);
			System.out.println("Message : " + response);
			
		} catch (Exception e) {
			e.printStackTrace();
		}
    	    
    	   

    
   }
}
6. Now let's create our Server: JavaWsServer.java
package org.code2care.rpc;

import org.apache.xmlrpc.server.PropertyHandlerMapping;
import org.apache.xmlrpc.server.XmlRpcServer;
import org.apache.xmlrpc.server.XmlRpcServerConfigImpl;
import org.apache.xmlrpc.webserver.WebServer;

public class JavaWsServer {
	
	private static final int PORT = 1080;
	
	public static void main(String[] args) {
		
		

		try {

			System.out.println("Starting XML-RPC 3.1.1 Server on port : "+PORT+" ... ");

			WebServer webServer = new WebServer(PORT);
			XmlRpcServer xmlRpcServer = webServer.getXmlRpcServer();

			PropertyHandlerMapping propHandlerMapping = new PropertyHandlerMapping();
			propHandlerMapping.load(Thread.currentThread().getContextClassLoader(), "handler.properties");
			xmlRpcServer.setHandlerMapping(propHandlerMapping);

			XmlRpcServerConfigImpl serverConfig = (XmlRpcServerConfigImpl) xmlRpcServer.getConfig();
		

			webServer.start();

			System.out.println("Server started successfully...");
		} catch (Exception exception) {
			System.out.println("Something went wrong while starting the server : ");
			exception.printStackTrace();
		}
	}
}
7. Create handler.properties file under src folder.
HelloWorld=org.code2care.rpc.HelloWorld
8. Now let's create Client: JavaWsClient.java
package org.code2care.rpc;

import java.net.URL;

import org.apache.xmlrpc.client.XmlRpcClient;
import org.apache.xmlrpc.client.XmlRpcClientConfigImpl;


public class JavaWsClient {
   public static void main (String [] args) {
   
   
	   try {
			System.out.println("XML-RPC Client call to : http://localhost:1080/xmlrpc/xmlrpc");
			XmlRpcClientConfigImpl config = new XmlRpcClientConfigImpl();
			config.setServerURL(new URL(
					"http://localhost:1080/xml-rpc-example/xmlrpc"));
			XmlRpcClient client = new XmlRpcClient();
			client.setConfig(config);
			Object[] params = new Object[] { "Chris Martin" };
			String response = (String) client.execute("HelloWorld.message", params);
			System.out.println("Message : " + response);
			
		} catch (Exception e) {
			e.printStackTrace();
		}

   }
}
9. Create web.xml configuration file under WebContent -> WEB-INF
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns="http://java.sun.com/xml/ns/javaee"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
	id="WebApp_ID" version="3.0">
	<display-name>xml-rpc-example</display-name>
	<welcome-file-list>
		<welcome-file>index.jsp</welcome-file>
	</welcome-file-list>

	<servlet>
		<servlet-name>xmlrpc</servlet-name>
		<servlet-class>org.apache.xmlrpc.webserver.XmlRpcServlet</servlet-class>
		<init-param>
			<param-name>enabledForExtensions</param-name>
			<param-value>true</param-value>

		</init-param>
	</servlet>
	<servlet-mapping>
		<servlet-name>xmlrpc</servlet-name>
		<url-pattern>/xmlrpc</url-pattern>
	</servlet-mapping>

</web-app>
Executing the Web Service :

1. Start the Application Server: Apache/JBoss

2. Now first start Server component : JavaWsServer by right click -> Run As -> Java Application

3. Once the server is started successfully run Client: JavaWsClient by right click -> Run As -> Java Application

Output :

XML-RPC Client call to: http://localhost:1080/xmlrpc/xmlrpc
Message: Hello from the remote place! Chris Martin
Some of the issues you may face and how to solve them :
Nothing works right for the first time, here are some of the exceptions, error that you may face and how to resolve them.
1. java.net.BindException: Permission denied
Something went wrong while starting the server : 
java.net.BindException: Permission denied

	at java.net.PlainSocketImpl.socketBind(Native Method)
	at java.net.AbstractPlainSocketImpl.bind(AbstractPlainSocketImpl.java:382)
	at java.net.ServerSocket.bind(ServerSocket.java:375)
	at java.net.ServerSocket.(ServerSocket.java:237)
	at org.apache.xmlrpc.webserver.WebServer.createServerSocket(WebServer.java:164)
	at org.apache.xmlrpc.webserver.WebServer.setupServerSocket(WebServer.java:183)
	at org.apache.xmlrpc.webserver.WebServer.start(WebServer.java:218)
	at org.code2care.rpc.JavaWsServer.main(JavaWsServer.java:31)

You may get BindException if you use a port that is less than or equal to 1024, all Unix-based systems do not allow these ports unless you have privileges to root. This issue can be resolved by using some port that is greater than 1024. I have used 1080 port, also make sure that you do not use ports used by other services like Apache Tomcat: 8080 e.t.c if running.

2. java.net.BindException: Address already in use
java.net.BindException: Address already in use
	at java.net.PlainSocketImpl.socketBind(Native Method)
	at java.net.AbstractPlainSocketImpl.bind(AbstractPlainSocketImpl.java:382)
	at java.net.ServerSocket.bind(ServerSocket.java:375)
	at java.net.ServerSocket.(ServerSocket.java:237)
	at org.apache.xmlrpc.webserver.WebServer.createServerSocket(WebServer.java:164)
	at org.apache.xmlrpc.webserver.WebServer.setupServerSocket(WebServer.java:183)
	at org.apache.xmlrpc.webserver.WebServer.start(WebServer.java:218)
	at org.code2care.rpc.JavaWsServer.main(JavaWsServer.java:30)

Again this is an issue related to ports, either some other service is running on the port, or your server component is already running. resolution BindException

3. java.io.IOException: Unable to locate resource handler.properties
java.io.IOException: Unable to locate resource handler.properties
	at org.apache.xmlrpc.server.PropertyHandlerMapping.load(PropertyHandlerMapping.java:53)
	at org.code2care.rpc.JavaWsServer.main(JavaWsServer.java:24)
IOException because you either placed the properties file in wrong location or name mismatch : how to resolve IOException
4. org.apache.xmlrpc.XmlRpcException: No such handler: HelloWorld.message
org.apache.xmlrpc.XmlRpcException: No such handler: HelloWorld.message
	at org.apache.xmlrpc.client.XmlRpcStreamTransport.readResponse(XmlRpcStreamTransport.java:197)
	at org.apache.xmlrpc.client.XmlRpcStreamTransport.sendRequest(XmlRpcStreamTransport.java:156)
	at org.apache.xmlrpc.client.XmlRpcHttpTransport.sendRequest(XmlRpcHttpTransport.java:143)
	at org.apache.xmlrpc.client.XmlRpcSunHttpTransport.sendRequest(XmlRpcSunHttpTransport.java:69)
	at org.apache.xmlrpc.client.XmlRpcClientWorker.execute(XmlRpcClientWorker.java:56)
	at org.apache.xmlrpc.client.XmlRpcClient.execute(XmlRpcClient.java:167)
	at org.apache.xmlrpc.client.XmlRpcClient.execute(XmlRpcClient.java:137)
	at org.apache.xmlrpc.client.XmlRpcClient.execute(XmlRpcClient.java:126)
	at org.code2care.rpc.JavaWsClient.main(JavaWsClient.java:21)

This gets a bit tricky, it may occur when you try to run the client, the reasons that may cause this issue,

You may have misspelled the method call name
You may have specified the wrong URL, check the URL specified and web.xml configuration.
Make sure that the web.xml file is configured correctly
5. org.apache.xmlrpc.XmlRpcException: Failed to read the server's response: Connection refused
org.apache.xmlrpc.XmlRpcException: Failed to read server's response: Connection refused
	at org.apache.xmlrpc.client.XmlRpcStreamTransport.sendRequest(XmlRpcStreamTransport.java:161)
	at org.apache.xmlrpc.client.XmlRpcHttpTransport.sendRequest(XmlRpcHttpTransport.java:143)
	at org.apache.xmlrpc.client.XmlRpcSunHttpTransport.sendRequest(XmlRpcSunHttpTransport.java:69)
	at org.apache.xmlrpc.client.XmlRpcClientWorker.execute(XmlRpcClientWorker.java:56)
	at org.apache.xmlrpc.client.XmlRpcClient.execute(XmlRpcClient.java:167)
	at org.apache.xmlrpc.client.XmlRpcClient.execute(XmlRpcClient.java:137)
	at org.apache.xmlrpc.client.XmlRpcClient.execute(XmlRpcClient.java:126)
	at org.code2care.rpc.JavaWsClient.main(JavaWsClient.java:21)

Make sure the port specified for the client and server are the same.