Running on Java 22-ea+27-2262 (Preview)
Home of The JavaSpecialists' Newsletter

084Ego Tripping with Webservices

Author: Dr. Heinz M. KabutzDate: 2004-02-05Java Version: 1.4Category: Language
 

Abstract: We have a look at how to build a simple webservice with Java.

 

Welcome to the 84th edition of The Java(tm) Specialists' Newsletter, and welcome to the year 2004 A.D. Many years ago, Cape Town attempted to host the Olympics, and that was supposed to happen this year. Unfortunately, or perhaps fortunately, Athens won the bid. We are this year celebrating 10 years of democracy, and today, 10 years ago, my brother tied the knot, two weeks before me. Congrats, Rudolf and Karin :-)

January 2004 is a significant month. It is the first month since November 2001 that I did not publish a newsletter. I appreciate all the emails that I have been getting from you, urging me to continue, for example:

long time no newsletter :(

I just wanted to let you know that I enjoyed reading your
newsletter 82 in German.

and this one:

Hi,

What happened u look very busy?
I m waiting 4 ur next issue.
;-)

Thank you so much for these little notes, they are appreciated :-) I was quite busy with an important project that had to be finished by the 31st of January (or no payment), so whilst the rest of the world was celebrating, I had my nose against the grindstone, typing Java code at neck breaking speed.

Before we get to today's newsletter, I would like to feedback on newsletter 83 and the follow-up. I omitted to mention that Clark Updike sent me a similar code snippet to what I used in Puzzle 3. Thanks, Clark :-) Thanks to all my readers for your eager participation in the puzzle. Here are the results:

  • Puzzle 1: 254 out of 412 responses were correct, i.e. 62%
  • Puzzle 2: 195 out of 259 responses were correct, i.e. 75%
  • Puzzle 3: 217 out of 319 responses were correct, i.e. 68%

I interpret the figures as demonstrating that the readers of The Java(tm) Specialists' Newsletter are the smartest of any Java newsletter :-)

javaspecialists.teachable.com: Please visit our new self-study course catalog to see how you can upskill your Java knowledge.

Ego Tripping with Webservices

These last two weeks seemed like the longest since I was battling to understand the Visitor pattern. One of my customers asked me to investigate how we could plug into Webservices and supply our own transport for the XML messages, since HTTP was not appropriate for their application.

I must admit that I viewed Webservices with skepticism, shared by many others. How many useful Webservices are we going to see in the next few years, or is it all just Silicon Snake Oil [ISBN 0385419945] (great book, btw)? My frustrations were compounded by battling to get any communication with REAL Webservices going. Believe it or not, but I struggle with new technologies. I remember when EJBs first appeared on the scene and how long it took me to deploy my first CMP bean!

The first implementation we looked at was Sun's Java Web Services Developer's Kit. The jax-rpc implementation worked most of the time, but I lost much hair (and time) when it didn't.

I am by no means an expert on Webservices. My total real experience is about two weeks. However, after starting to use the Apache Axis implementation, I become excited at the possibilities of integrating with world-famous websites from within my Java programs.

A Mathematical Webservice

First off, I will show you a Java Webservice that you can integrate with:

public class Fibonacci {
  public int calculate(int n) {
    if (n < 0)
      throw new IllegalArgumentException("number must be >= 0");
    switch (n) {
      case 0:
        return 0;
      case 1:
        return 1;
      default:
        return calculate(n - 2) + calculate(n - 1);
    }
  }
}

The Fibonacci calculator is a favourite exercise that I use to break the spirit of overconfident Java students. The reason this code causes problems is because of its recursive nature and exponential time complexity. Even working out fibonacci(100) would take a long long time using this algorithm.

How do we convert this Java class to a Webservice? Do we compile it? Do we add an interface, and write a WSDL (Web Services Description Language) description for it?

No, it is much easier. Start by downloading Apache Axis v 1.1. Install Axis and Tomcat 4.1.x. Next take the directory axis in webapps (under the axis install) and copy it into the webapps directory under Tomcat. Start up Tomcat. Axis should now be working. Go to http://localhost:8080/axis and validate your setup. If it did not work, please follow the documentation that comes with Axis.

Now comes the cool part. Take Fibonacci.java (not the class file), copy it to the webapps/axis directory and rename it to Fibonacci.jws. Congratulations! You have written your first Webservice. That is really how easy it is. You can verify that it worked by going to http://localhost:8080/axis/Fibonacci.jws. The standard webpage gives you a link to the WSDL file describing the interface for that class in a language that everybody can understand (except humans).

Accessing the Webservice

The client to the Webservice is a bit more difficult (an easier version comes later):

import org.apache.axis.client.*;

public class FibClient {
  public static void main(String[] args) throws Exception {
    String endpoint = "http://localhost:8080/axis/Fibonacci.jws";
    Service service = new Service();
    Call call = (Call) service.createCall();
    call.setTargetEndpointAddress(endpoint);
    call.setOperationName("calculate");
    Integer ret = (Integer) call.invoke(new Object[]{new Integer(args[0])});
    System.out.println("Got result : " + ret);
  }
}

You need to have your classpath set up correctly. I assume that regular readers of The Java(tm) Specialists' Newsletter would also be aware of the system property java.ext.dirs that you can point at a directory of jar files, instead of listing them all separately in your classpath. For example, Axis is installed on c:\java\axis-1_1 on my disk, and the compiled classes are in a subdirectory called classes. So once I have compile my FibClient, I can run it like this:

java -Djava.ext.dirs=c:\java\axis-1_1\lib -classpath classes FibClient 0
Got result : 0
java -Djava.ext.dirs=c:\java\axis-1_1\lib -classpath classes FibClient 1
Got result : 1
java -Djava.ext.dirs=c:\java\axis-1_1\lib -classpath classes FibClient 2
Got result : 1
java -Djava.ext.dirs=c:\java\axis-1_1\lib -classpath classes FibClient 3
Got result : 2
java -Djava.ext.dirs=c:\java\axis-1_1\lib -classpath classes FibClient 4
Got result : 3
java -Djava.ext.dirs=c:\java\axis-1_1\lib -classpath classes FibClient 5
Got result : 5
java -Djava.ext.dirs=c:\java\axis-1_1\lib -classpath classes FibClient 6
Got result : 8
java -Djava.ext.dirs=c:\java\axis-1_1\lib -classpath classes FibClient 30
Got result : 832040

Making the Client Code Simpler

IBM is a great company. They write excellent open source, free software, that we can use to produce good software. One of the wonderful tools that they wrote is WSDL2Java. You can invoke it on the Webservice that we have just written:

java -Djava.ext.dirs=c:\java\axis-1_1\lib org.apache.axis.wsdl.WSDL2Java
  http://localhost:8080/axis/Fibonacci.jws?wsdl -o src -p eu.javaspecialists.fib.client

This generates some files that we can use to make our client easier to write. The package that the files are in is eu.javaspecialists.fib.client, so that is where I will add my new FibClient class:

package eu.javaspecialists.fib.client;

public class FibClient2 {
  public static void main(String[] args) throws Exception {
    FibonacciService service = new FibonacciServiceLocator();
    Fibonacci fib = service.getFibonacci();
    for (int i=0; i<10; i++) {
      System.out.println("fib(" + i + ")=" + fib.calculate(i));
    }
  }
}

And that is all you have to do. Run the code like this:

java -Djava.ext.dirs=lib -classpath classes eu.javaspecialists.fib.client.FibClient2
fib(0)=0
fib(1)=1
fib(2)=1
fib(3)=2
fib(4)=3
fib(5)=5
fib(6)=8
fib(7)=13
fib(8)=21
fib(9)=34

And Now, the Ego Trip

Fame is when you walk into a room and there are more people that know you than that you know. My father-in-law was the best soccer player in South Africa in his days of glory. For 20 years afterwards, people would greet him in the street and say: Remember in 1968 when we celebrated your victory together? Of course he did not, but he did not want to disappoint his fans either.

The question is: How famous are you? Depending on your name, that may be hard to determine. My name is easy. I am the only "Heinz Kabutz" alive on this planet. My friend John Green probably has another John Green living in the same street. So, the results of a Google search must not be taken too seriously.

Google has published a Webservice interface that we can use to do searches. The WSDL is available at https://developers.google.com/custom-search. Google makes this available to the general public, so there are restrictions. For example, you have to register at their website to obtain a license key, that you send along with every request. You can only do 1000 requests per day, and there are other restrictions. Please do read the documentation on Google's website. I would like to continue doing EgoSurfing on Google through my program, so please do not abuse their goodwill ;-)

In addition to the WSDL, Google makes available a Java API Facade. However, since I was trying to learn how to interact with a Webservice, I used Axis to speak to Google. It was a lot easier than I thought it would be. First off, it is a good idea to generate Java classes from the WSDL:

java -Djava.ext.dirs=c:\java\axis-1_1\lib org.apache.axis.wsdl.WSDL2Java
  https://api.google.com/GoogleSearch.wsdl -o src

This creates the following files in the package GoogleSearch:

DirectoryCategory.java
GoogleSearchBindingStub.java
GoogleSearchPort.java
GoogleSearchResult.java
GoogleSearchService.java
GoogleSearchServiceLocator.java
ResultElement.java

The stage is now set for our EgoTrip client. I am using the generated Google classes to do a search for famous names:

package eu.javaspecialists.webservices;

import GoogleSearch.*;

import javax.xml.rpc.ServiceException;
import java.rmi.RemoteException;
import java.util.*;

public class EgoTrip {
  private final GoogleSearchPort port;
  private final String googleKey;

  public EgoTrip(String googleKey) throws ServiceException {
    this.googleKey = googleKey;
    GoogleSearchService service = new GoogleSearchServiceLocator();
    port = service.getGoogleSearchPort();
  }

  private int measureFame(String name) throws RemoteException {
    GoogleSearchResult result = port.doGoogleSearch(
        googleKey, name, 0, 10, false, "", false, "", "UTF-8", "UTF-8");
    return result.getEstimatedTotalResultsCount();
  }

  public static void main(String[] args) throws Exception {
    String[] famousPeople = {
      "Bruce Eckel", // famous Java author
      "John Vlissides", // famous Design Pattern author
      "Cay Horstmann", // famous Java author
      "Erich Gamma", // famous Design Pattern author
      "Martin Fowler", // famous author
      "Jörn Schmidt-Dumont", // my sales manager
      "Heinz Kabutz", // me
      "Pieter Kritzinger", // my prof at university
      "Helene Kabutz", // my wife
      "Marten Kabutz", // my older brother
      "Rudolf Kabutz", // my oldest brother
      "Bettina Kabutz", // my sister
      "Bjarne Stroustrup", // famous C++ inventor
      "Mark Shuttleworth", // famous Thawte founder
      "Bill Gates", // apparently wrote some software
      "Costa Kytides", // #14 in the world street-luger
      "Anesti Kytides", // stand-up skate-boarder
      "John Green", // friend from university
    };
    Set people = new TreeSet();

    EgoTrip et = new EgoTrip(args[0]);
    for (int i = 0; i < famousPeople.length; i++) {
      System.out.println("Egotripping " + famousPeople[i]);
      int fame = et.measureFame(famousPeople[i]);
      people.add(new Person(fame, famousPeople[i]));
    }

    System.out.println();
    System.out.println("Hall of Snake Oil Fame");
    for (Iterator it = people.iterator(); it.hasNext();) {
      System.out.println(it.next());
    }
  }

  private static class Person implements Comparable {
    private final int fame;
    private final String name;

    public Person(int fame, String name) {
      this.fame = fame;
      this.name = name;
    }

    public int compareTo(Object o) {
      Person other = (Person) o;
      int result = other.fame - fame;
      if (result == 0) {
        return name.compareTo(other.name);
      }
      return result;
    }

    public String toString() {
      return name + " (" + fame + ")";
    }
  }
}

When you run this program, you have to give it your Google key that you get when you register. You can register on Google Web APIs website. You can then run this program yourself:

java -Djava.ext.dirs=lib -classpath classes eu.javaspecialists.webservices.EgoTrip YOUR_GOOGLE_LICENSE_KEY

By the time you run this program, the newsletter should be on the website, so perhaps Google would've done its work indexing it? If so, the numbers could be different. Infact, they will probably be different because they are just an estimate. Sorry Bill Gates, you are not at the top, my friend John Green is more famous:

Egotripping Bruce Eckel
Egotripping John Vlissides
Egotripping Cay Horstmann
Egotripping Erich Gamma
Egotripping Martin Fowler
Egotripping Jörn Schmidt-Dumont
Egotripping Heinz Kabutz
Egotripping Pieter Kritzinger
Egotripping Helene Kabutz
Egotripping Marten Kabutz
Egotripping Rudolf Kabutz
Egotripping Bettina Kabutz
Egotripping Bjarne Stroustrup
Egotripping Mark Shuttleworth
Egotripping Bill Gates
Egotripping Costa Kytides
Egotripping Anesti Kytides
Egotripping John Green

Hall of Snake Oil Fame
John Green (3360000)
Bill Gates (1630000)
Martin Fowler (207000)
Bruce Eckel (29300)
Bjarne Stroustrup (22900)
Erich Gamma (21600)
Mark Shuttleworth (16000)
John Vlissides (14000)
Cay Horstmann (7880)
Heinz Kabutz (874)
Pieter Kritzinger (846)
Rudolf Kabutz (36)
Jörn Schmidt-Dumont (35)
Anesti Kytides (18)
Costa Kytides (16)
Helene Kabutz (11)
Bettina Kabutz (9)
Marten Kabutz (6)

At least I appear more often than my professor from the University of Cape Town ;-)

Thanks for reading this newsletter :-)

Kind regards

Heinz

 

Comments

We are always happy to receive comments from our readers. Feel free to send me a comment via email or discuss the newsletter in our JavaSpecialists Slack Channel (Get an invite here)

When you load these comments, you'll be connected to Disqus. Privacy Statement.

Related Articles

Browse the Newsletter Archive

About the Author

Heinz Kabutz Java Conference Speaker

Java Champion, author of the Javaspecialists Newsletter, conference speaking regular... About Heinz

Superpack '23

Superpack '23 Our entire Java Specialists Training in one huge bundle more...

Free Java Book

Dynamic Proxies in Java Book
Java Training

We deliver relevant courses, by top Java developers to produce more resourceful and efficient programmers within their organisations.

Java Consulting

We can help make your Java application run faster and trouble-shoot concurrency and performance bugs...