Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

XML-RPC - Throwing Exceptions from Server to Client in Java

It is my first time posting here and I could not find the answer to my question during a search so lets see if I can explain myself correctly.

I am using XML-RPC as part of a large project but I will present a simplified code in which I obtain the same result.

The connection is working perfectly if I do not throw exceptions. My problem is to throw an exception from Server to Client. I get the XmlRpcException on the Client side but its cause is always null. Looks like the exception is lost on the transfer. Any idea why?

My Server:

public class JavaServer { 

public Integer sum(int x, int y) throws Exception {
throw new MineException("ABABBABA");
}

public static void main (String [] args) {
try {

 System.out.println("Attempting to start XML-RPC Server...");
 WebServer server = new WebServer(80);
 XmlRpcServer xmlRpcServer = server.getXmlRpcServer();
 PropertyHandlerMapping phm = new PropertyHandlerMapping();
 phm.addHandler("test", JavaServer.class);
 xmlRpcServer.setHandlerMapping(phm);
 XmlRpcServerConfigImpl serverConfig = (XmlRpcServerConfigImpl) xmlRpcServer.getConfig();
    serverConfig.setEnabledForExceptions(true);

 server.start();
 System.out.println("Started successfully.");
 System.out.println("Accepting requests. (Halt program to stop.)");
} catch (Exception exception) {
 System.err.println("JavaServer: " + exception);
}}}

My Client:

public static void main(String[] args) {

    XmlRpcClientConfigImpl config = new XmlRpcClientConfigImpl();
    try {
        config.setServerURL(new URL("http://localhost:80"));
        XmlRpcClient client = new XmlRpcClient();
        client.setConfig(config);           
        Object[] params = new Object[] { new Integer(38), new Integer(3), };

        Integer result = (Integer) client.execute("test.sum", params);
        System.out.println("Results " + result);
    } catch (XmlRpcException exception) {
        Throwable cause = exception.getCause();
        if(cause != null) {
            if(cause instanceof MineException) {
                System.out.println(((MineException)cause).getMessage());
            }
            else { System.out.println("Cause not instance of Exception"); }
        }
        else { System.out.println("Cause was null"); }
        } catch (MalformedURLException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}
like image 364
Augusto Avatar asked Feb 25 '23 06:02

Augusto


2 Answers

I found out that by using apache xml-rpc implementation on both client and server it is possible to throw custom exceptions from the server and receive them on the client. Something just needs to be added to the server and client configuration.

Server:

WebServer server = new WebServer(80);
 XmlRpcServer xmlRpcServer = server.getXmlRpcServer();
 PropertyHandlerMapping phm = new PropertyHandlerMapping();
 phm.addHandler("test", JavaServer.class);
 xmlRpcServer.setHandlerMapping(phm);
 XmlRpcServerConfigImpl serverConfig = (XmlRpcServerConfigImpl) xmlRpcServer.getConfig();
    serverConfig.setEnabledForExceptions(true);
    serverConfig.setEnabledForExtensions(true); //Add this line
 server.start();

Client:

XmlRpcClientConfigImpl config = new XmlRpcClientConfigImpl();
    try {
        config.setServerURL(new URL("http://localhost:80"));
        config.setEnabledForExceptions(true);
        config.setEnabledForExtensions(true); //Add this line
        XmlRpcClient client = new XmlRpcClient();
        client.setConfig(config);                           
        Object[] params = new Object[] { new Integer(11), new Integer(3), };
        Integer result = (Integer) client.execute(config,"test.sum", params);
        System.out.println("Results " + result);
    } catch (XmlRpcException exception) {
        System.out.println(exception.getMessage());
        Throwable cause = exception.getCause();
        if(cause != null) {
            if(cause instanceof MyException) {
                System.out.println(((MyException)cause).getMessage());
            }
            else { System.out.println("Cause not instance of Exception."); }
        }
        else { System.out.println("Cause was null."); }
        } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();

Then everything works as expected.

like image 109
Augusto Avatar answered Feb 26 '23 22:02

Augusto


Some other piece of (hopefully helpful) advice.

So, you want to enable the extensions for exceptions, but you are running the service within a Servlet inside (a full-fledged) web server like say, Apache Tomcat. Then you need to enable the extensions and exceptions by configuring them in the web.xml file (WEB-INF\web.xml):

<servlet>
  <servlet-name>My_XMLRPC_Servlet</servlet-name>
    <servlet-class>com.stackoverflow.server.MyXmlRpcServlet</servlet-class>
      <init-param>
        <param-name>enabledForExtensions</param-name>
        <param-value>true</param-value>
      </init-param>
      <init-param>
        <param-name>enabledForExceptions</param-name>
        <param-value>true</param-value>
      </init-param>
        ...
</servlet>
like image 27
adcelis Avatar answered Feb 26 '23 21:02

adcelis