Category Archives: Uncategorized

my foray into xmlrpc – calling perl from java

XMLRPC is supposedly the new RPC mechanism to handle remote method calls independent of programming language, platform type, or location. Basically, it is how CORBA was supposed to be. Of course, it formats data into xml packaged into an HTTP message. This is not SOAP though, and I still don’t really know the difference, other than SOAP is a the packaging for WebServices and has its own strict way of defining method and method arguments(?). Anyways, XML-RPC sounds perfect to get some crappy Perl to Java method calls working!

The problem as I see it, is that the XMLRPC mechanism is usually “extended” to handle language specific needs. This makes things a lot easier when you are using it to call remote methods in a uniform environment. The problem is that thats not what I want, as extensions in Java will make the Perl methods die. A horrible death.

In Perl there are two cpan modules that facilitate the XMLRPC mechanism that I tried: RPC::XML and XMLRPC::Transport in the SOAP::Lite package. I tried the XMLRPC::Transport package with no results (meaning I couldn’t get it to work), but after installing the RPC::XML package and using the examples provided at this page (beware the text ads!). It seemed to get things working via his provided Client (on Page 3) and Server (Page 2) examples. His provided sample client and server perl uses only the non-extended XMLRPC mechanisms. Nice. [Note: I did not include links to Mr. Yang’s perl because he might care about licenses and stuff (he copyrights his examples! x-( ]

So anyways, what I did was write up some Java code to interface with Mr. Yang’s Perl. Here is the example class, using the apache xmlrpc jars. The jar files** can be found at the Apache Web Service Page and are licensed under the Apache License.

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

import java.net.URL;
import java.util.HashMap;

/**
 * 03/2007 hello from tmarthal :: tmarthal.blogspot.com
 *
 * sample xmlrpc client using Apache's common xmlrpc-client classes to interface with a sample perl xmlrpc
 * server provided on the interwebs at http://www.herongyang.com/perl_b/rpc_xml_3.html
 *
 * The methods are (from the webpage):
 *  It offers 3 methods: com.herong.hello, com.herong.getCelsius, and com.herong.getInfo.
    - com.herong.hello has one signature: return type of string, and no input argument. Its handler function is defined inside the add_method call.
    - com.herong.getCelsius has two signatures. The first one requires no input argument, and the second one requires one "double" argument.
    - com.herong.getInfo has one signature of returning an 'array'. The corresponding handler function returns a reference to a list. The server knows how to convert the content of the reference to an 'array'.
 *
 * There are also two XML:RPC system calls that get the list of available methods and method arguments:
    - system.listMethods returns an array of strings which are the names of the methods
    - system.methodSignature returns the HashMap of method name to string arguments
 *
 */
public class XmlRpcClientExample {

    public XmlRpcClientExample() { }

    private static final String SERVER_URL = "http://localhost:8001";


    public double getCelcius(double temp) {
     double value = 0.0;
        try {
            XmlRpcClientConfigImpl config = new XmlRpcClientConfigImpl();
            config.setServerURL(new URL(SERVER_URL));
            config.setEnabledForExtensions(true);
            config.setConnectionTimeout(60 * 1000);
            config.setReplyTimeout(60 * 1000);

            XmlRpcClient client = new XmlRpcClient();


            // use Commons HttpClient as transport
            client.setTransportFactory(new XmlRpcCommonsTransportFactory(client));
            // set configuration
            client.setConfig(config);

            // make the a regular call
            Object[] params = new Object[] { new Double(temp) };

            //TM Calculator is the name of the handler on the server side
            // and add is the method call
            Object result = (Object) client.execute("com.herong.getCelsius", params);

            // autobox / Java 5.0
            value = (Double) result;
            System.out.println("result = " + value);
        }
        catch (Exception e) {
            e.printStackTrace();
        }
        return value;
    }

    public String[] listMethods() {
     String[] methods = null;
     try {
      XmlRpcClientConfigImpl config = new XmlRpcClientConfigImpl();
      config.setServerURL(new URL(SERVER_URL));
      config.setEnabledForExtensions(true);
      config.setConnectionTimeout(60 * 1000);
      config.setReplyTimeout(60 * 1000);

      XmlRpcClient client = new XmlRpcClient();


      // use Commons HttpClient as transport
      client.setTransportFactory(new XmlRpcCommonsTransportFactory(client));
      // set configuration
      client.setConfig(config);

      // Null input
      Object[] params = null;

      // RPC
      Object result = client.execute("system.listMethods", params);

      // Cast the result as a list of objects
      try {
       Object[] methodsObjects = (Object[]) result;
       methods = new String[methodsObjects.length];

       for (int i=0; i < methodsObjects.length; i++) {
        methods[i] = (String) methodsObjects[i];
        System.out.println(i + " " + methods[i]);
       }
      }
      catch (ClassCastException e) {
       e.printStackTrace();
      }

     } catch (Exception e) {
      e.printStackTrace();
     }
     return methods;
    }


    public HashMap methodSignature(String method) {
     HashMap signature = new HashMap();
     try {
      XmlRpcClientConfigImpl config = new XmlRpcClientConfigImpl();
      config.setServerURL(new URL(SERVER_URL));
      config.setEnabledForExtensions(true);
      config.setConnectionTimeout(60 * 1000);
      config.setReplyTimeout(60 * 1000);

      XmlRpcClient client = new XmlRpcClient();


      // use Commons HttpClient as transport
      client.setTransportFactory(new XmlRpcCommonsTransportFactory(client));
      // set configuration
      client.setConfig(config);

      // method
      Object[] params = new Object[] { method };

      // RPC
      Object result = client.execute("system.methodSignature", params);

      // Cast the result as a list of objects
      try {
       Object[] returns = (Object[]) result;

       for (int k=0;k<returns.length;k++) {

        Object[] methodsObjects = (Object[]) returns[k];
        String[] methods = new String[methodsObjects.length];

        for (int i=0; i< methodsObjects.length; i++) {
         methods[i] = (String) methodsObjects[i];
         //System.out.println(i + " " + methods[i]);
        }
        signature.put(k,methods);
       }
      }
      catch (ClassCastException e) {
       e.printStackTrace();
      }

     } catch (Exception e) {
      e.printStackTrace();
     }
     return signature;
    }


    public String hello() {
     String returnString = "";
        try {
            XmlRpcClientConfigImpl config = new XmlRpcClientConfigImpl();
            config.setServerURL(new URL(SERVER_URL));
            config.setEnabledForExtensions(true);
            config.setConnectionTimeout(60 * 1000);
            config.setReplyTimeout(60 * 1000);

            XmlRpcClient client = new XmlRpcClient();


            // use Commons HttpClient as transport
            client.setTransportFactory(new XmlRpcCommonsTransportFactory(client));
            // set configuration
            client.setConfig(config);

            // make the a regular call
            Object[] params = null;

            //TM Calculator is the name of the handler on the server side
            // and add is the method call
            Object result = (Object) client.execute("com.herong.hello", params);

            returnString = (String) result;
        }
        catch (Exception e) {
            e.printStackTrace();
        }
        return returnString;
    }

    public String[] getInfo() {
     String[] info = null;
     try {
      XmlRpcClientConfigImpl config = new XmlRpcClientConfigImpl();
      config.setServerURL(new URL(SERVER_URL));
      config.setEnabledForExtensions(true);
      config.setConnectionTimeout(60 * 1000);
      config.setReplyTimeout(60 * 1000);

      XmlRpcClient client = new XmlRpcClient();


      // use Commons HttpClient as transport
      client.setTransportFactory(new XmlRpcCommonsTransportFactory(client));
      // set configuration
      client.setConfig(config);

      // Null input
      Object[] params = null;

      // RPC
      Object result = client.execute("com.herong.getInfo", params);

      // Cast the result as a list of objects
      try {
       Object[] infoObjects = (Object[]) result;
       info = new String[infoObjects.length];

       for (int i=0; i< infoObjects.length; i++) {
        if (infoObjects[i].getClass().equals(String.class)) {
         info[i] = (String) infoObjects[i];
        }
        else if (infoObjects[i].getClass().equals(Integer.class)){
         Integer castedInteger = (Integer) infoObjects[i];
         info[i] = (String) castedInteger.toString();
        }
        else {
         continue;
        }
        System.out.println(i + " " + infoObjects[i]);
       }
      }
      catch (ClassCastException e) {
       e.printStackTrace();
      }

     } catch (Exception e) {
      e.printStackTrace();
     }
     return info;
    }


    public static void main(String[] args) {
        XmlRpcClientExample  x = new XmlRpcClientExample();
        x.listMethods();
        x.getCelcius(100.0);
        x.methodSignature("system.listMethods");
        //System.out.println(x.hello());
        x.getInfo();
    }
}

I hope the tag CSS works! (Just in case, I used the outdated pre tag as well). The for loop iterators and Java Generic markup had to be replaced. 😦

The reason that I published this, instead of just keeping it is that XML-RPC resources from the web are lacking. Example code to interface between the Apache xmlrpc and Perl's XML::RPC package are non-existent. At least, with my limited google-fu, nothing turned up that would help me, so maybe Blogger will spyder this into a google search and be helpful to the one developer that finds this blog when looking for an example. Note that an IBM Web Development link "Utilize XML-RPC in Perl" was also helpful as a reference. If you read that and still can't figure out how to implement the methods in the linked code, comment here or find me and I can help.

** The jar files used are xmlrpc-client-3.0.jar, xmlrpc-common-3.0.jar, commons-codec-1.3.jar, common-logging-1.1.jar, ws-commons-util.1.0.1.jar, commons-httpclient-3.0.1.jar

xkcd

The webcomic xkcd was recently featured on a popular tech website which I frequent. The author spoke at mit about his life and writing (and was interuppted by students), so I started reading the comic. Man, is it good.

I just started reading them, and got lots of the way through. Then I realized that there is a second level of awesome, in the img alt text tags. And then I read most of them again.

Some of my favs, in no particular order:


how many links is he going to inline?!

ipod shuffle

So i broke down and got my 2nd ipod, a 1gb ipod shuffle. Since my 4gb 1st generation ipod nano is stuck in my truck’s dashboard (most likely still playing the same thing \=)) with my ‘USA Spec IPOD Interface’ Toyota connector. Hopefully this will be my more ‘used’ ipod (aka updated regularly and listened to at the office, during outdoor activities, and in the bathroom).

It was set to shuffle and the first track was my favorite Kanye West track Gone.
Wear your music! yay! \o/

i need to do some css editing with those dang labels. p.s. i still rule

CSS Templates and Blog Spam

So, I was perusing my other blog today and deleted a drug spam comment for the third or fourth time in as many days from one of the more recent posts. In this case, it was my friend Jake dancing in leotards… but the spam comments are always there, always posted on the top message.

Prior to this, the blog spammers, people that post either poker referrals, drug purchase links, ‘hot’ stocks, online diplomas [almost as bad as the USC DEN program!], or money making schemes all seem to never have posted on this ‘…’ blog. I used to think that it was because it had custom CSS that I use to display the pages, and that comment bots couldn’t figure out which link to click when they came to my page.

That can’t be the case now though; I think that more and more pennies/day workers are being paid to drive views to sites rather than bots. I have to say that is the case, I had 15 comments my museum post which is pretty crazy considering I get like 1 unique visitor a month here and almost no real traffic [maybe I should talk about the iphone too!?].

To fight this I’ve turned on the blogger captchas, but still allow anonymous posts. I’ve also upgraded to the new blogger, but I can’t tell any difference (other than the label/tag support [for which I didn’t add to my CSS? hrrm]). *shrug*

Smithsonian Museum Day

This September 30th, 2006 is Museum Day!. The Smithsonian Institution started a free admission day a while back and most museums around the country (even if they already offer free admission) are getting into the spirit of the free Museum day! It’s a Saturday ferchrissakes, nothing better to do that day (USC has an away game).

So go to the What is Museum Day? website already and print out the admission card located there. Wherever you are located, there is a museum nearby participating!

There are so many sweet places to go: maybe get my bro to head to the defense museum in San Diego, check out the only museum with only electronic art, maybe see some quilts (I’m big into quilting!), or just see one of the many art museums located around LA.

WIHSTGW =(

hoodies

So, some of you might not know this, but I am very particular (peculiar?) about my hooded sweat shirts. I usually buy 2-3 new hoodies per year, and end up not liking most of them due to shoulder-area fit, color change, sleeve cuff, softness, waist area cinch type, or depth-of-hood. (Yeah, like I said peculiar).

There are two general types of hooded sweat shirts, flat-fronts and zip-ups.

  1. Flat-Front Hoodies: These are normal sweat shirt shirts, but with an added pocket in the front and a hood (which makes it the hoodie).
  2. Zip-Ups: These have the same hood, but zip up in the front. They sometimes have no pocket but most have have a split front pocket.

Well, this isn’t about the criminal nature of hooded sweatshirts, or the fashion, but a zit pick about zip-up hoodies: Zippers!!

Most of the cheaper zip up hoodies come with plastic zippers. They are fine for the first couple months, but if worn in extreme cold (like while snowboarding), plastic zippers have a tendency to break teeth. Plastic zippers also have a tendency to not lye straight: they warp in the direction out of the zipper, causing ungainly bulges in the stomache region. That is the reason I prefer metal zippers.

Generally, higher quality hoodies come with metal zippers. This is because IMO most higher quality ‘softgoods’ are produced by companies that tend to make heavier outerwear as well, which generally come with metal zippers for the cold-breakage described above.

So I bought a very nice black zip-up Four Square hoodie last year while in New Mexico which has a nice flanel-pattern waterproof mesh lining. It had everything I look for in a hoodie: color, fit, hood shape, warmth, quality metal zipper; everything. The problem was, when I went to bust it out last spring I could not get the zipper to work!

The metal zipper was stuck; it would not connect and link up the teeth as if there was a string jammed in there or something. If anyone knows, most aficionados wear thier zip-up hoodies 3/4 zipped up, and this would just not do. I tried everything all summer long, it seemed like the zipper was bent or something and all my efforts with wrenches, knives, pliers, and assorted tools would not get it to work.

So I tried WD-40. The zipper zipped right up. It had rusted over. I did not know such a thing was possible. The same elements that the metal zipper is to protect against, are prone to cause rust as well. Good thing a little grease made it good, else I would’ve had to buy another hoodie this fall… as it stands I think I have at least one as we head into the winter months.

Do you people think about hoodies as much as I do? This blog is sweet.