Category Archives: Software Development

eBay Java / C# SOAP Examples

At the start of this year I worked with some guys at eBay to further develop their code samples. Some, but not all of the twelve examples I wrote went live in the recently launched Community Codebase. You can download all the Java examples (of which I wrote three) or browse the Subversion repository. I wrote the SOAPAddItem, SOAPGetItem, and SOAPGetUser items in the Java source tree.

The examples I wrote were different from the majority of the (then) existing examples in that I didn’t make any IDE assumptions (most of the Java examples have JBuilder .jpx files and Eclipse .project files, the .NET projects contain the Visual Studio artifacts.. tsk tsk.) and as such, all the examples I wrote contain comprehensive Ant / NAnt build files which means you can get up and running without having to setup your fancy schmancy IDE. But the biggest difference was that all the examples I wrote used either Ant (with WSDL2Java) or NAnt (with NAntContrib) tasks to conditionally download the eBay WSDL, generate the client stub(s), and compile the resulting code, which makes for a prettier source code repository (generated stubs aren’t checked into source) and gives you compile time checking of your code against the API.

If you’re interested in how you can use Ant or NAnt in a build environment where you access SOAP services, you should check it out!

Java Class.forName(String className) and JDBC

A reader asked a question via a comment a couple months ago that I didn’t really have an answer for (and had always kind of wondered the same thing). In the original post (which showed how to use JDBC with ColdFusion), I used the following snippet of code:

Class.forName("jdbc.DriverXYZ");
Connection con = DriverManager.getConnection(url,
  "myLogin", "myPassword");

and the reader wanted to know what the Class.forName(..) method did. The most common answer you’ll hear is that it loads the database driver, which, while technically true, is shallow. Where does it get loaded? How does it happen? And why?

To answer the question I started with the JavaDoc for the Class.forName() method. According to the documentation, the method:

… attempts to locate, load, and link the class or interface

I wasn’t perfectly clear on what “locate, load, and link” meant, so I did a little digging through the Java Language Specification. According to chapter 12 of the JLS:

Loading refers to the process of finding the binary form of a class or interface type with a particular name, perhaps by computing it on the fly, but more typically by retrieving a binary representation previously computed from source code by a compiler, and constructing, from that binary form, a Class object to represent the class or interface.

Next, again according to the JLS, it must be transformed from it’s binary representation to something the Java virtual machine can use, this process is called linking. Finally, the class is initialized, which is the process that executes the static initializer and the initializers for static fields declared in the class.

So then back to the original problem, when Class.forName() is called with an argument like this:

Class.forName("org.gjt.mm.mysql.Driver");

the classloader attempts to load and link the Driver class in the “org.gjt.mm.mysql” package and if successful, the static initializer is run. The MySQL Driver (download the source code) static initializer looks like this:

static {
  try {
    java.sql.DriverManager.registerDriver(new Driver());
  } catch (SQLException E) {
    throw new RuntimeException("Can't register driver!");
  }
}

So it calls a static method in the java.sql.DriverManager class which apparently registers a copy of itself when it loads.

So now I understand the where and the how, what about why? To understand the why you have to look at the next line in the initial code example:

Connection con = DriverManager.getConnection(url,
  "myLogin", "myPassword");

The DriverManager class (view DriverManager source here) returns a database connection given a JDBC URL string, a username and a password. In order to create that connection, the DriverManager class has to know which database driver you want to use. It does that by iterating over the array (internally a Vector) of drivers that have registered with it (ie: the registerDriver(Driver driver) method illustrated above) and calls the acceptsURL(url)) method on each driver in the array, effectively asking the driver to tell it whether or not it can handle the JDBC URL.

So there you have it. Class.forName explained.

Adaptive Path interview with Jared Spool: how to ask questions

Great story from an interview that Adapative Path’s Peter Merholz did with the founder of User Interface Engineering Jared Spool:

PM: Any other mistakes, in terms of how tests are structured?

JS: There are many problems I see in terms of people not
understanding the effects of testing affecting results.
Here’s a simple example that we discovered. We were working with a
client, testing a website that sold furniture. And the client had
already done some testing. They had created some simple tasks, and
one of the tasks was basically asking users to come to the site and buy
a bookcase they might want to buy.

Every user in that study went to the search box, and typed in the word “bookcase,” immediately. So they were off trying to improve the hits on the word “bookcase,” and get the results better. We did a subsequent test, and instead of asking people to look for a bookcase, we gave them a slightly different task.

We said imagine you have 300 different paperback and hardcover books in
cardboard boxes, all strewn through your living room. You need a way to
organize this stuff such that you can find the stuff you like, and
people who come over can be impressed with your collection. What do you
do? People would go to the site, and then click on links. They’d click
on furniture links; they’d type into the search engine storage systems,
and then type in shelves. Not a single user in our phase of the study
typed in the word bookcase. So by changing the description of the task,
we got a completely different result.

Asking the right question really is half the battle.

Fun with Axis / SOAP, Java and Calendar

The fun with dates didn’t stop at the last post. This one took longer to track down but I learned alot more from it. I’m working on both sides of an Apache Axis SOAP implementation where the server side system persists events and client applications can query to find events and CRUD events against this server side application. So the server presents an event:

...
public class EventRemote {
private String name;
private String address;
private Calendar eventdate;
...
// getters & setters omitted
}

and methods that allow client applications to search for events and create / retrieve / update and delete them:

...
public class EventManagerRemote {
public void updateEvent(EventRemote event) {
...
}
public void createEvent(EventRemote event) {
...
}
public EventRemote findEventByID(long eventid) {
...
}
// other methods omitted
}

For the last couple weeks the clients and servers had no problems, create, retrieve, update, delete and search all worked as expected. But recently a user requested a change to the UI of the client system which resulted in a change to the way the client application needed to format the eventdate (a Calendar object). In the past the client would retrieve the event and then format the eventdate property using a SimpleDateFormat:

EventRemote event = manager.findEventByID(12);
Calendar eventdate = event.getEventdate();
SimpleDateFormat formatter = new SimpleDateFormat("M/d/yyyy h:m aa");
String strdate = formatter.format(eventdate.getTime());

So if my event was today (June 30, 2005 at 7:30pm), the above snippet would print:

6/30/2005 7:30 PM

The change to the client I mentioned above meant that I needed to access each element of the Calendar object separately, so instead of having one big datetime string, I need to know that the month was June, the date ’30’, the year ‘2005’ and so on. Since the getMonth()/Day()/Year() methods of the Date class have been deprecated since v1.1, I had to use the Calendar class get(int field) methods. Not a problem, there’s some different things you have to work through in the Calendar class (ie: the month field has values that range from 0 to 11 instead of 1 to 12), but it’s doable:

EventRemote event = manager.findEventByID(12);
Calendar eventdate = event.getEventdate();
int day = eventdate.get(Calendar.DATE);
int year = eventdate.get(Calendar.YEAR);
...
int hour = eventdate.get(Calendar.HOUR);
int minute = eventdate.get(Calendar.MINUTE);
int am_pm = eventdate.get(Calendar.AM_PM);

I printed out the results (again assuming a date of June 30,2005 at 7:30pm) and instead of getting that same date I got this:

6/30/2005 11:30 PM

which was exactly 4 hours ahead of the time I wanted. I dug into Axis source code and saw that the CalendarDeserializer class explicity sets the TimeZone of the returned Calendar object to GMT (to make it UTC right?). Understandably, this causes the HOUR property of the Calendar object to jump four hours ahead (I’m in EST, GMT/UTC is currently 4 hours ahead of EST, it’ll be 5 hours during the winter months, explanation). The workaround (although I’m not sure it’s a good idea), was to set the TimeZone of the returned Calendar object back to EST. This probably doesn’t make alot of sense without seeing some sample code:

Calendar calendar = new GregorianCalendar(2005, 5, 30, 19, 30);
String utcformat = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'";
SimpleDateFormat zulu = new SimpleDateFormat(utcformat);
String serializeddate = zulu.format(calendar.getTime());
// string gets sent along the wire via soap
// CalendarDeserializer parses date string
Calendar deserial = Calendar.getInstance();
Date deserialdate = zulu.parse(serializeddate);
deserial.setTime(deserialdate);
// CalendarDeserializer explicitly sets TZ to GMT
deserial.setTimeZone(TimeZone.getTimeZone("GMT"));
SimpleDateFormat formatter = new SimpleDateFormat(utcformat);
// will print '2005-06-30T19:30:00.000Z'
System.out.println(formatter.format(deserial.getTime()));
// will print '11', should print '7'
System.out.println(deserial.get(Calendar.HOUR));

So I understand that the date gets sent along the wire in UTC format, which strips out timezone information the date was originally encoded with, my question is this: why does the HOUR property of the Calendar object reflect UTC time (ie: 11:30pm) while the formatted time reflects EST time (7:30pm)?

Fun With Java dates

Sorry for not posting anything other than links recently, the kid is wearing me out almost as much as working with Java dates. I haven’t had to work with java.util.Date and java.util.Calendar all that much, most of the time it’s been pretty simple stuff but for whatever reason this past week has been spent waist deep in the Calendar and Date API’s trying to fix a bug in a deployed application. The code I was using looked something like this:

// date entered by user through a combination
// of drop down lists
String strdate = "12/6/1975 5:30 PM"
SimpleDateFormat formatter = new SimpleDateFormat("M/d/yyyy H:m a");
Date eventdate = formatter.parse(strdate);
System.out.println(formatter.format(eventdate));

and out of that I expected to see a date of 12/6/1975 at 5:30pm, it should in fact have printed back the exact same string I entered right? Instead I got:

12/6/1975 5:30 AM

I spent awhile trying different things (am I entering the date wrong? is there something wrong with the timezone? etc..) but eventually noticed that ‘h’ is not the same thing as ‘H’ in the date format string. Using an upper case ‘H’ signifies to the SimpleDateFormat parser that you want it to look for a 24 hour time format (ie: instead of 5:30 I should have used 17:30). In hindsight that’s somewhat obvious, but the tricky thing is that I included the PM designation, so in theory, shouldn’t the SimpleDateFormat have picked up the fact that I wanted a time in PM? I think it should have at least have thrown an exception that says you’ve entered a time in the morning and an AM PM designation of evening. True Date class experts would say at this point that I should have set the SimpleDateFormat to be strict in it’s parsing:

formatter.setLenient(true)

which I did, but it still didn’t throw an exception. Should it have?

Delicious + Movable Type + Java

I’ve been keeping a list of interesting links in a text file for the last couple years and only recently thought better of it and started using del.icio.us to store links. And I wanted to show the links as part of this blog, but I wasn’t satisfied with just including their RSS feed of my links in blog (what happens when / if del.icio.us disappears?) so I whipped up a some code using the delicious-java library and the Apache XML-RPC library that extracts my delicious links from the previous day and then posts them directly my Movable Type blog using the XML-RPC API that comes standard with Movable Type. After putting it up on my server, I wrote a simple shell script that invokes the Java class and then popped that into /etc/cron.daily/ so that it will get called a nightly basis, voila!

#!/bin/bash
cd /usr/apps/delicious/
java -cp commons-codec-1.3.jar:commons-httpclient-3.0-rc2.jar:
commons-logging-1.0.4.jar:delicious-1.6.jar:xmlrpc-1.2-b1.jar:bin net.cephas.blog.DeliciousPoster config.properties

If you’d like to run it your own server, feel free to download the binaries (which include the source code), edit config.properties to match your Movable Type and de.licio.us profiles and scheduled it to run on a nightly basis.

Strategy Design Pattern applied to hashCode() and equals()

The latest issue of the JavaSpecialists newsletter (by Dr. Heinz Kabutz) features a lengthy look at possibility of applying the Strategy design pattern to the equals() and hashCode() methods commonly used in Java. In it he concludes that the equals and hashCode methods autogenerated by IntelliJ Idea are better from a performance standpoint.

If your IDE of choice doesn’t include the ability to autogenerate the bodies of the above mentioned methods, you might also check out the EqualsBuilder, HashCodeBuilder and ToStringBuilder classes in the Jakarta Commons Lang library.

Paper Review: Two Case Studies of Open Source Software

The term paper for the class I’m taking (Paradigmatic Software Development) required that we write a review of a article that has appeared in a software engineering journal. I spent about 45 minutes trying to poke around the journal locator that UMass Dartmouth outsourced before giving up (they don’t let you search by topic, how lame is that?) and then remembering that Google has an academic focused search. Scholar.google.com found a bunch of articles about ‘open source’ and ‘software engineering’, I chose one entitled “Two Case Studies of Open Source Software
Development: Apache and Mozilla
“. My review of the paper is over 7 pages long, you can download the entire thing in MS Word format or read the extended entry below.
Continue reading Paper Review: Two Case Studies of Open Source Software

Top 15 Ant Best Practices

Good stuff over at OnJava.com, the article “Top 15 Ant Best Practices” gives 15 recommendations on how you should be using Ant to structure and complete your builds. We’re using most of these already at work; I’d be curious to know the author’s take on the deployment system we’ve developed using Ant. I’ve got Subversion handling source control, so on the production machines, I have a build file called build-production.xml that I invoke from the command line using a batch file:

ant -buildfile build-production.xml

which a) checks out the latest build from Subversion / source control, b) executes the default build file (which is in source control) which compiles the project and then wraps up the result in a war file, c) stops the Tomcat Windows service, d) deletes the existing application from the $tomcat/webapps directory, e) unpacks the application from the .war creates in step b, and then finally f) starts the Tomcat Windows service.

It’s worked out pretty well so far in that it decouples the build file for the project from having to know anything about the environment in which it’s executing so developers can write their own build-development.xml which maybe does something similar to the build-production.xml, but deploys to a different location, or even a different application server.

The wrapper build file (be it build-production.xml, build-local.xml, etc..) can also override properties set in the project build.xml. In our projects, I’ve got the build.xml file conditionally setting properties in log4j.properties using the <propertyfile> tag. There are two such targets: one for production that sets the appender to SMTPAPPENDER and the logging level to ERROR and one for development that sets the appender to STDOUT and the logging level to INFO. Said targets use the if and unless attributes of the <target> tag like so:

<target name="build.resources.debug" if="project.debug">
...

and

<target name="build.resources.production" unless="project.debug">
...

This way, unless I set the project.debug property, the system will always be in ERROR / SMTPAPPENDER mode but developers can override that property at compile time using the wrapper build-local.xml to set the project.debug property, ie:

<ant antfile="build.xml">
  <property name="project.debug" value="true"/>
</ant>

Do you do it better? Can you one up me? I’ve love to hear about it.

ASP, Java, Cookies and URLEncode

One of the bugs I tracked down a couple months ago dealt with the different ways in which ASP and Java handle URL encoding in a cookies. ASP automatically encodes and decodes cookie values (without you telling it too even though it the Server object has a method ‘URLEncode’ which does the same job) while Java requires that you explicity use the URLDecoder and URLEncoder, otherwise it sends the cookie values without encoding them first, which in my case lead to an interoperability problem (one assumes URL encoding of cookie values, one doesn’t).

But then it gets weirder. The encoding that ASP automatically applies is different than the encoding that Java applies. For example, in ASP you’d write something like this to set a cookie with my email address:

Response.cookies("encoded") = "ajohnson@cephas.net"

which would then result in this:

ajohnson%40cephas%2Enet

where in Java you’d have something like this:

String email = "ajohnson@cephas.net";
String encoded = URLEncoder.encode(email, "UTF-8");
res.addCookie(new Cookie("encoded", encoded););

which results in this:

ajohnson%40cephas.net

So why does ASP encode the period as %2E and Java leave it alone? The Microsoft documentation for the ASP Server object contains very little documentation about the URLEncode method other than to say that the URLEncode method

… applies URL encoding rules, including escape characters, to a specified string.

(which could be a teensy bit more helpful, must have been a programmer writing that documentation). On the other hand, the Java URLEncoder class documenation says that the special characters “.”, “-“, “*”, and “_” are not to be encoded according to the HTML specification, which itself cites RFC 1738 which says:

…the special characters “$-_.+!*'(),”, and reserved characters used for their reserved purposes may be used unencoded within a URL.

which seems to me to imply that the ASP Cookie object is wrong (ie: it should leave the period alone in the email address). And beyond that, it’s pretty aggressive in assuming that I want to encode the data in my cookies. Am I missing something? How do other languages (PHP, Python, Perl, etc..) implement the same functionality? Aren’t web applications fun?