Archive for the ‘Java’ Category

Java Tuple update

Friday, August 20th, 2010

Download:

Four years ago I created a Java Tuple class. I needed a way to quickly create type-safe multi-valued keys in Java. Here’s what I came up with:

Map<Pair<String, String>, Integer> population = new HashMap<Pair<String, String>, Integer>();
population.put(
    Tuple.from("TX", "Dallas"),
    1213825);
population.put(
    Tuple.from("TX", "Fort Worth"),
    624067);
population.put(
    Tuple.from("IL", "Springfield"),
    203564);
population.put(
    Tuple.from("NM", "Albuquerque"),
    494236);

int p = population.get(
    Tuple.from("TX", "Fort Worth"));
// p = 624067
assertEquals(624067, p);
assertNull(population.get(
    Tuple.from("NM", "Roswell")));
assertNull(population.get(
    Tuple.from("NJ", "Springfield")));

Tuple.from() creates a type-safe object containing the listed values. It implements equals(), getHashCode(), compareTo(), and toString() in meaningful ways. And it provides for multi-valued returns.

Variable<Boolean> found = new Variable<Boolean>();
Variable<Integer> index = new Variable<Integer>();

findCharacter("Hello, world", 'w').extract(found).extract(index);
assertTrue(found.get());
if (found.get()) {
    int i = index.get();
    assertEquals(7, i);
}
else {
    fail();
}

Where findCharacter returns Pair<Boolean, Integer>. I published the source and got a few comments.

The most persistent complaint was that Tuple only worked with types that implemented IComparable<Themselves>. This constraint was only used in compareTo(). If you wanted tuples for one of the other methods, you ran into a meaningless compiler issue.

I have since removed that generic constraint. Now you can create tuples of non-comparable types. If you try to compare them, you will get a run time issue.

If you have used this library in the past, or if you need tuples in Java, please download the latest using the links at the top of this article.

Java/WCF Interop

Monday, February 8th, 2010

As of today (February 2010), the story of Java/WCF interoperability is fair. That wasn’t always the case. In the past, I’ve struggled to get Java and .NET to play nice. Today, I was able to make a .NET WCF client talk to a Java CXF web service with just a little coaxing. Here’s how I did it.

Contract first
The first step to successful interoperability is to define the contract. Somehow you need to generate the WSDL, and you need to tightly control what it looks like. Use tools to help you, but keep a close eye on what those tools do.

I started with a WCF service contract. This is a .NET interface that uses the [ServiceContract] and [OperationContract] attributes. Put this interface and all of the data types it uses into a class library project. Here’s an example:

[ServiceContract(Namespace = "http://correspondence.updatecontrols.com")]
public interface ISynchronizationService
{
    [OperationContract]
    FactTree Get(FactTree pivotTree, long pivotId, long timestamp);

    [OperationContract]
    void Post(FactTree messageBody);
}

The FactTree data type used by this interface is decorated with the [DataContract] and [DataMember] attributes.

[DataContract(Namespace = "http://correspondence.updatecontrols.com")]
public class FactTree
{
    [DataMember]
    public long DatabaseId { get; set; }

    [DataMember]
    public List<Fact> Facts { get; set; }

    [DataMember]
    public List<FactRole> Roles { get; set; }

    [DataMember]
    public List<FactType> Types { get; set; }
}

Create a WCF service

Even though we want to end up with a Java web service, an intermediate step is to implement this service in WCF.

  1. Create a new project in Visual Studio using the template Visual C#: Web: WCF Service Application.
  2. Add a reference to the class library that defines the interface.
  3. Change the name of the generated service from Service1 to something meaningful.
  4. Delete the generated IService1 interface.
  5. Use your own interface instead.
  6. Add a [ServiceBehavior] attribute to set the Namespace.

At this point, the service looks something like this:

// NOTE: If you change the class name "Service1" here, you must also update the reference to "Service1" in Web.config and in the associated .svc file.
[ServiceBehavior(Namespace = "http://correspondence.updatecontrols.com")]
public class SynchronizationService : ISynchronizationService
{
    public FactTree Get(FactTree pivotTree, long pivotId, long timestamp)
    {
        throw new NotImplementedException();
    }

    public void Post(FactTree messageBody)
    {
        throw new NotImplementedException();
    }
}

Like the comment says, we need to edit the svc file and the web.config. Right-click the svc file in the project tree and select “View Markup”. Change the Service attribute to the fully qualified name of the service class.

<%@ ServiceHost Language="C#" Debug="true"
  Service="UpdateControls.Correspondence.WebService.SynchronizationService"
  CodeBehind="SynchronizationService.svc.cs" %>

The web.config change is slightly more complicated. There’s a lot of junk in web.config that you don’t need to worry about. The section you want is all the way at the bottom. Look for the <service> tag. It has two attributes: name and behaviorConfiguration. Also look for the <endpoint> tag right below it. It has three attributes: address, binding, and contract.

  1. Change the service name to the fully qualified name of your service class.
  2. Change the endpoint binding from wsHttpBinding to basicHttpBinding.
  3. Change the endpoint contract from IService1 to the fully qualified name of your interface.

Here’s a trick to getting the fully qualified names. Delete the text between the quotes of the attributes. Open the Class View by hitting Ctrl+Shift+C in Visual Studio. Expand the tree to find your service class and interface. Drag them onto the web.config file between the quotes.

You can also change the name of the service behavior, but that’s not necessary for this intermediate step.

Examine the WSDL

These steps ensure that we have nice clean WSDL to work from. Take a look at it by running your WCF service application. A directory listing will open in the browser. Click on the svc file. If you get a yellow screen, please double-check your steps.

Click on the link to see the WSDL you’ve created. Different browsers react differently to raw XML. IE and Firefox will show it to you, but Chrome will give you a blank screen. You’ll have to view source to see the WSDL in Chrome.

On this first page, you’ll see all of the input and output messages, and the operations, and the service itself. Double-check that the service uses binding="i0:BasicHttpBinding_...".

Hack the url to look at more detailed information. Change the query string to “?wsdl=wsdl0” to see the declaration for the binding. It uses “http://schemas.xmlsoap.org/soap/http” with the “document” style.

Hack the url again with “?xsd=xsd0” to see the data types. You should recognize these data types as the ones you wrote in C#. Notice that it turns all of your List<T>s into ArrayOfTs. When we import these into Java, they will become classes containing List<T>.

Create the Java contract project

Create a Java project in your favorite IDE (mine is Eclipse). Open a command prompt and go to the source directory of that project (probably ends in “src”). Download Apache CXF and unzip it to your hard drive (mine is in “c:\apache-cxf-2.2.6”).

Go back to the first WSDL page, the one with the “?wsdl” query string. This is the URL that we are going to generate Java files from. Copy this URL and use it at the command line:

\apache-cxf-2.2.6\bin\wsdl2java.bat http://localhost:3642/SynchronizationService.svc?wsdl

CXF will generate a bunch of class files. Most will be in a package derived from your namespace. One will be in “com.microsoft.schemas._2003._10.serialization”. If you find one in org.tempuri package, you forgot a Namespace setting in one of your attributes. These class files are decorated with enough annotations to make them compatible with the WCF service.

Create the Java service project

Although you could put your service implementation and contract in the same project, I prefer to keep them separate. You can use the contract project to write a different service implementation, or even to write a client.

Create a new Dynamic Web Project. Add to the new project a reference to the contact project. You will also need to add this reference to the Java EE Module Dependencies in the project properties. Otherwise it won’t copy the contract jar file to the service lib directory, resulting in a NoClassDefFoundError at runtime. Then add a class that implements the service contract. Copy the @WebService annotation from the interface to the class. The service looks something like this:

@WebService(targetNamespace = "http://correspondence.updatecontrols.com", name = "ISynchronizationService")
public class SynchronizationService implements ISynchronizationService {

    @Override
    public FactTree get(FactTree pivotTree, Long pivotId, Long timestamp) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public void post(FactTree messageBody) {
        // TODO Auto-generated method stub

    }

}

The service project needs the CXF jar files. Copy them from the CXF install folder (C:\apache-cxf-2.2.6\lib) into the project’s library folder (WebContent\WEB-INF\lib). This is the minimal set that you will need:

  • jaxb-api-2.1.jar
  • jaxb-impl-2.1.12.jar
  • wsdl4j-1.6.2.jar
  • XmlSchema-1.4.5.jar
  • cxf-2.2.6.jar

Now we need to publish this web service as a servlet. The quickest way to do that is to derive a class from CXFNonSpringServlet. Right-click the project and select "New: Servlet”. Change the servlet base class to “org.apache.cxf.transport.servlet.CXFNonSpringServlet”. Uncheck the boxes to implement doGet and doPost. The base class handles those for you. Once the class is created, override the loadBus method.

package com.updatecontrols.correspondence.service;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.xml.ws.Endpoint;

import org.apache.cxf.transport.servlet.CXFNonSpringServlet;

public class SynchronizationServlet extends CXFNonSpringServlet {
    @Override
    public void loadBus(ServletConfig servletConfig) throws ServletException {
        super.loadBus(servletConfig);        

        Endpoint.publish("/SynchronizationService", new SynchronizationService());
    }
}

Open the web.xml file. You will notice that a servlet mapping was created for you. This mapping is set up to handle URLs that directly address the servlet, but the CXF servlet adds the service name to the URL. Add a “/*” to the end of the URL pattern to direct all such addresses to the servlet.

<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
    <display-name>correspondence_sync_service</display-name>
    <servlet>
        <description>
        </description>
        <display-name>SynchronizationServlet</display-name>
        <servlet-name>SynchronizationServlet</servlet-name>
        <servlet-class>
        com.updatecontrols.correspondence.service.SynchronizationServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>SynchronizationServlet</servlet-name>
        <url-pattern>/SynchronizationServlet/*</url-pattern>
    </servlet-mapping>
</web-app>

Run the project in Tomcat to make sure the servlet is published correctly. Point a browser at the servlet (in my case http://localhost:8080/correspondence_sync_service/SynchronizationServlet) and you should see a listing of available SOAP services. Append the service name to the URL (http://localhost:8080/correspondence_sync_service/SynchronizationServlet/SynchronizationService) and you will get a 500 error. If you get a 404, you haven’t modified the web.xml file correctly.

Create a WCF client

The last step is the easiest. Since we started by creating a WCF service contract, we can ask WCF to create a client proxy. I documented this technique in .NET to .NET web services without WSDL. It turns out that this trick works equally well for .NET to Java web services.

Add an endpoint to the app.config of your client. The URL should be the servlet name followed by the service name. For example:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.serviceModel>
    <bindings>
      <basicHttpBinding>
        <binding name="SynchronizationServiceSoapBinding" closeTimeout="00:01:00"
            openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
            allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
            maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
            messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
            useDefaultWebProxy="true">
          <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
              maxBytesPerRead="4096" maxNameTableCharCount="16384" />
          <security mode="None">
            <transport clientCredentialType="None" proxyCredentialType="None" realm=""/>
            <message clientCredentialType="UserName" algorithmSuite="Default" />
          </security>
        </binding>
      </basicHttpBinding>
    </bindings>
    <client>
      <endpoint address="http://localhost:8080/correspondence_sync_service/SynchronizationServlet/SynchronizationService"
          binding="basicHttpBinding" bindingConfiguration="SynchronizationServiceSoapBinding"
          contract="UpdateControls.Correspondence.WebService.Contract.ISynchronizationService" name="SynchronizationService" />
    </client>
  </system.serviceModel>
</configuration>

And with that you have a .NET WCF client communicating with a Java CXF server. I expect that similar strategies could be used to go the other direction, although I haven’t tried yet.

NullReferenceException while using bean:write

Wednesday, July 2nd, 2008

Here's an obscure error that I fought for several hours today:

Jul 2, 2008 5:42:42 PM org.apache.catalina.core.ApplicationDispatcher invoke
SEVERE: Servlet.service() for servlet jsp threw exception
java.lang.NullPointerException
at org.apache.struts.taglib.TagUtils.retrieveMessageResources(TagUtils.java:1175)
at org.apache.struts.taglib.TagUtils.message(TagUtils.java:1038)
at org.apache.struts.taglib.TagUtils.message(TagUtils.java:1013)
at org.apache.struts.taglib.bean.WriteTag.retrieveFormatString(WriteTag.java:254)
at org.apache.struts.taglib.bean.WriteTag.formatValue(WriteTag.java:360)
at org.apache.struts.taglib.bean.WriteTag.doStartTag(WriteTag.java:232)
.... (the rest is unimportant)

This was thrown by the following line in a JSP:

<bean:write name="report" property="exceptionReportId" />

The problem is that my method getExceptionReportId() returns an int. The struts bean tag library expects all properties to be Strings. So by changing my method to return a String and using Integer.toString, I made it happy.

This presents a real separation-of-concerns problem. A bean should be a dumb data container. It should give you back exactly what you put in, and it should preserve your data types. The restriction that all properties are strings puts formatting into the bean, and therefore makes it specific to the JSP page.

Is there a tag library that separates formatting concerns from beans?

[UPDATE: You can format non-String property values using the bean:write format attribute. For a date, for example, <bean:write name="report" property="reportDate" format="MM/dd/yyyy"/>. Furthermore, to fix the NullPointerException above, I just added an empty format attribute, as in <bean:write name="report" property="exceptionReportId" format="" />.]

Inversion of Thought

Monday, June 30th, 2008

I've started a new project using Spring MVC. In doing so, I've had to invert my thinking.

Spring is an inversion of control container, which means that you don't code dependencies of one class directly upon another. Instead you put all of your dependencies into one configuration file and keep your code as loosely coupled as possible. This one configuration file creates a graph of objects, each with references to the others. Since the configuration file specifies the classes and references, the code for one class doesn't need to know the names of other classes.

Why is this important?
The dependency inversion principle tells us that it is better to depend upon something abstract than something concrete. This helps us to change how something is done without breaking the things that need it to be done. If your code depends upon an interface, you can change the thing that implements that interface without changing your code.

There are other reasons which have come to light since Robert Martin published his paper back in 1996. Dependency inversion makes unit testing easier, because you can replace the components that a unit calls with mock objects. Dependency inversion makes distributed computing easier, because you can replace business objects with proxies that call business logic on remote servers. In general, dependency inversion is a good goal.

How does Spring do it?
So if your class depends upon an interface rather than a concrete class, how does it get a reference to an object that implements that interface? It can't use "new" to create an instance, because "new" needs a concrete class name. To invert dependency, you have to move all of your "new"s into one place. That place is an inversion of control (IoC) container.

Spring reads an XML file that contains a bunch of object descriptions. You can think of each of these as a call to "new". Each one specifies a class name, an instance name, and a set of properties. These are write-once properties (what I like to call definitive), and should be initialized and never changed. These properties can include references to other object instances, thus forming a graph.

MVC
Spring MVC combines the dependency inversion principle with the model-view-controller pattern to create a pretty compelling web framework. The controllers and URL mappings are all configured through the IoC container. The URL mapper has a reference to each of the controllers, so it knows how to delegate the handling of a request. Because dependency has been inverted, the URL mapper doesn't know about the concrete classes that are the controllers, it only knows about an interface. So you can use the out-of-the-box URL mapper with your own custom controllers.

But it just so happens that Spring has a quaint mechanism for database access. In your XML file, you can configure a data source by providing a driver class name and a connection string to an instance of "org.apache.commons.dbcp.BasicDataSource".  Then you can use this data source to execute queries using "org.springframework.jdbc.core.simple.SimpleJdbcTemplate". I wanted to use this technique from my data access layer. However, the XML file that defines the object graph is way up in my web layer. How can I push that object graph, or at least the data source, down through the business logic layer and into the data access layer?

The epiphany
That's when the full realization of dependency inversion hit me. I was thinking about the web layer depending upon the business logic layer, which then depended upon the data access layer. This is not the Spring way. Instead, the web, business logic, and data access layers are all independent. The IoC container depends upon them all. The individual components within these layers only depend upon interfaces.

So the one XML file declares a data source. It then declares a data access component and gives it a reference to the data source. Next comes a business logic component and with a reference to the data access component. Then, the controller with a reference to the business logic component. And finally, the URL mapper comes last with a reference to the controller. As more URLs, controllers, and components are added, this chain widens into a graph.

You can't pick and choose which pieces of your application use dependency inversion. Please don't try. Once you start down the Spring path, all dependencies are inverted. The graph that's defined at the highest layer of your application delves deep into the lowest, and touches all layers in between. Consider dependency inversion for your next project, and think carefully about the consequences.

Java Query

Monday, May 12th, 2008

This is not linq for Java, but it does bear a small resemblance. Download the source code and unit test. [Update: One unit test requires the Java tuple library.]

If you've ever needed to return an Iterable<T> from a Java method, you know that it can be challenging. If you already have exactly the collection that you want to iterate, then all is well. If not, you have two choices.

Option 1, you could construct a new ArrayList<T>, populate it, and return it. This option is less memory efficient than it could be. But it is by far the easiest way to go. You get to write your iteration code using "for".

Or option 2, you could implement Iterable<T> with an anonymous inner class. Instead of using "for", you'll have to manage the state of your iterator yourself. Basically, you have to turn the looping code inside out and put the initialization, testing, and stepping code in separate methods. However, this saves on memory, as you don't have to store the results in an intermediate collection.

On a number of occasions, I've taken option 2. Having rewritten the same ugly code several times, I decided to generalize it.

Inspiration from C#
Having spent some time in the .NET world, I'm familiar with two ways of solving this problem.

First, C# provides the "yield" keyword for turning a loop inside out. You write the code as per option 1, but instead of adding an object to a collection, you "yield return" it. The compiler turns the code inside out and makes it work like option 2. Yael has an implementation of yield return in java, if you like this approach.

Second, C# now has built-in syntax for querying any data source, including collections of objects. This syntax is called linq, or language integrated query. I didn't want to implement all of the linq functionality in java, but I did use it as a source of inspiration.

From
Linq is like upside-down SQL. The first thing that you write is the "from" clause. This is important for type safety and intellisense. Borrowing from this convention, you start a java query with:

Query
    .from(collection)

This returns a Query<T>, which gives you the rest of the methods.

Where
A where clause filters the collection on-the-fly. The iterator that is produced only lands on the items that satisfy the where condition. You specify the condition by anonymously implementing the Predicate interface, as in:

Query
    .from(collection)
    .where(new Predicate<T>() {
        public boolean where(T row) {
            return /* Condition based on row */;
        }
    })

Join
A join traverses a nested collection. For each object of the first collection, you obtain an iterator over the second. The result is the same as two nested for loops. You return the inner collection using the Relation interface, as in:

Query
    .from(collection)
    .join(new Relation<PARENT, CHILD> () {
        public Iterable<CHILD> join(PARENT parent) {
            return parent.getChildren();
        }
    })

This produces an iterator of Join<PARENT, CHILD>.

Select
The last clause in a query is the select. Now that you've built up and narrowed down your collection of objects, the select clause gives you a chance to transform them into the data type that you want. You provide an anonymous implementation of the Selector interface:

Query
    .from(collection)
    .select(new Selector<T, RESULT>() {
        public RESULT select(T row) {
            return row.getProperty();
        }
    })

If you want to get the objects themselves, you can simply use ".selectRow()" instead.

Put it all together
You can combine these clauses to create the query you need. It has to start with a "from" and end with a "select", but you can have any combination of "join" and "where" clauses in between. Here's an example from the unit test:

// Iterate through the order items. Pull out order numbers where a widget is ordered.
Iterator<Integer> orderNumbers = Query
    .from(customers)
    .join(new Relation<Customer, Order>() {
        public Iterable<Order> join(Customer parent) {
            return parent.getOrders();
        }
    })
    .join(new Relation<Join<Customer,Order>, Item>() {
        public Iterable<Item> join(Join<Customer, Order> parent) {
            return parent.getSecond().getItems();
        }
    })
    .where(new Predicate<Join<Join<Customer,Order>,Item>>() {
        public boolean where(Join<Join<Customer, Order>, Item> row) {
            return row.getSecond().getPart().getName().equals("widget");
        }
    })
    .select(new Selector<Join<Join<Customer,Order>,Item>, Integer>() {
        public Integer select(Join<Join<Customer, Order>, Item> row) {
            return row.getFirst().getSecond().getNumber();
        }
    })
    .iterator();

Now you can generate iterators on-the-fly without wasting memory or writing really ugly code. Under the covers, it's just doing what a for loop would do. But with a query, you can return the resulting collection to a caller without turning your code inside-out.

Constrained dot-chaining

Thursday, April 26th, 2007

For my recent XML parsing library -- DeclarativeXMLParser -- I used a coding technique that I call constrained dot-chaining. This technique is useful for creating structures in code that more concisely express their intent.

Simple dot-chaining is accomplished by declaring methods that end in "return this". For example, StringBuffer in Java and StringBuilder in C# both facilitate dot-chaining by returning "this" from the "append" (or "Append" in C#) method. Thus you can chain a series of method calls as in:

String greeting = new StringBuffer()
  .append("Hello, ")
  .append(name)
  .append("!")
  .toString();

Notice the use of the dot at the beginning of the line. As compared to the more typical dot at the end of the line, this lends more symmetry to dot-chained code and works better with intellisense.

Dot-chaining is especially powerful when you pass the resulting object as a parameter. The object can be created and initialized in-line with no semicolon. No variable needs to be declared.

throw new MyException(new StringBuffer()
  .append("Failed to open  file ")
  .append(fileName)
  .append(": ")
  .append(e.getMessage())
  .toString(), e);

Constrained dot-chaining is useful when the order of operations should be restricted. For example, in the DeclarativeXMLParser, each element will be initialized before the attributes are matched. The attributes will be matched before the Begin delegate is called. Begin will precede the sub elements, and End will follow all. So you want the code to look like this:

new Element()
  .Init(delegate() {...})
  .RequiredAttribute("id", idAttribute)
  .IgnoreOtherAttributes()
  .Begin(delegate() {...})
  .One("subElement", new Element()
    .RequiredAttribute("name", nameAttribute)
  )
  .End(delegate() {...});

Unconstrained dot-chaining would allow these operations to be declared in any order. While that wouldn't confuse the parser engine, this would most certainly confuse anyone reading the code. Constraints are required to force this code to be more readable.

Here's my solution
The Element class is only the leaf of a long line of inherited classes. It directly supplies the Init method, which returns Element. It's base class is ElementWithAttributes, which supplies all of the attribute related methods. ElementWithAttributes in turn inherits ElementWithFilter, which supplies the Filter method, and so on up the hierarchy until you reach ElementWithEnd.

The idea is simple. Once you go up the inheritance hierarchy, you can't go back down. This forces you to call the methods in the prescribed order. Inheritance allows you to skip levels if you want to, but you can't backtrack.

Each level of the hierarchy returns its own type for methods that can be called more than once, and its base class type for methods that can be called only once. So, for example, once you call Begin, you are now at the ElementWithContent level. You cannot call Begin again because you are too high up in the tree.

Download the code for more details. I hope you find this technique as useful as I have.

Dirt Simple XML Parser

Friday, March 30th, 2007

I know there are already far too many ways to parse XML. Softartisans has an entire page devoted to choosing which XML parser is best for different situations. But still I find myself facing the same trade-off each time I need to consume an XML document: do I do something simple, or do I do something efficient? DOM is easy, but very costly. SAX is the most efficient, but very difficult to use. Other technologies fall between those two on the spectrum.

I've finally solved that problem once and for all. I created an XML library that makes SAX dirt simple to use. You express an XML document declaratively, putting in hooks to handle elements that interest you. This declaration turns into a DefaultHandler for SAX to invoke. The source code is available in two parts: mallardsoft.xml depends upon mallardsoft.util.

To build a parser, create a new NestedHandler and initialize it with a new Document. Using in-line dot-chaining, set up sub elements of the Document with new Element objects. Here's a quick example:

final StringBuffer firstName = new StringBuffer();
final StringBuffer lastName = new StringBuffer();

DefaultHandler handler = new NestedHandler(new Document()
  .one("people", new Element()
    .zeroToMany("person", new Element()
      .init(firstName)
      .init(lastName)
      .optionalAttribute("firstName", firstName)
      .requiredAttribute("lastName", lastName)
      .end(new InvokeHandler() {
        public void handle() throws SAXException {
          newPerson(firstName.toString(), lastName.toString());
        }
      })
    )
  )
);

Pass this to a SAX parser and it will extract all of the person elements, grab their first and last names, and call the newPerson() method for each one. You can nest elements as deeply as you need to. And if you need a recursive declaration, use an ElementSpec object. Give it a try with a more complex XML file and see how well it scales up.

Update
I've changed the names to better reflect true XML nomenclature. The proper names are not "root" and "node", but "document" and "element".

Unhelpful Error Message in Eclipse

Monday, December 18th, 2006

I'm a big fan of the Eclipse Java IDE. I think it is at least on generation ahead of Microsoft's Visual Studio IDE. However, even Eclipse has some poorly designed features.

Take, for example, the error message infrastructure. Instead of handling errors in useful ways, or better yet just doing the right thing in the first place, they wrap all exceptions and present the same useless UI for everything. Here's an example:

The message box tells me that an exception was caught (not helpful), and that the reason was that it encountered a problem (not helpful). It gives me the options of either undoing or aborting the refactoring, which sound a lot like the same thing. Then when I ask for more details, it tells me again that it encountered a problem.

To reproduce this error, you must install the Subclipse plugin to manage a project in Subversion. Delete a package. The package will not actually be deleted, since the change has not been committed to SVN. Then try to move a class into the deleted package. You can see how the separate concerns of Java packages, file systems, source control, and refactoring have all combined to produce a mess of a situation.

Lazy Logging

Friday, December 15th, 2006

I sometimes see coders trying to optimize their logging. Since it takes time to format log messages, they will first test whether logging is enabled:

Logger log = Logger.getLogger(MyClass.class);
if (log.isInfoEnabled())
    log.info( "Processing customer " + customer.getName() +"." );

The info() method already checks whether logging is enabled, but this additional check avoids the string concatenation. String formatting and manipulation is surprisingly expensive, so it is undesirable to take this hit only to have no effect.

However, this type of checking is just a distraction. Fortunately, Log4J gives you an option. The parameter to info() is not a String, as you might think by looking at this example code. It is actually an Object. Log4J will call toString() on the object you pass in. Furthermore, it will only call toString() if it really does log the message. We can take advantage of this to clean up our code.

Here's my solution
I've created a class that performs string concatenation and formatting inside of the toString() method. It caches the result so that multiple calls to toString() don't repeat the work. However, if toString() is never called, the expensive operations are never performed. Using this class, the logging code looks like this:

Logger log = Logger.getLogger(MyClass.class);
log.info( StringFormatter.format("Processing customer {name}.").
    set("name", customer.getName()) );

Downlaod the source code here: stringformatter.zip.

Java Tuple

Friday, October 20th, 2006

Final UpdateThe latest code is at http://adventuresinsoftware.com/blog/?p=546. The javatuple.com site is going off-line.

Update I've created a new version of this Java Tuple library. It can be found at http://javatuple.com. The new version uses generics for type safety. It also has extractor methods. If you use Java 1.4 or earlier, or you just prefer the previous version, please read on. Otherwise, visit javatuple.com.

Thanks.

I don't know how many times I've needed a hash map with a compound key, but it seems to come up often. Every time, I am faced with the same question: do I really want to define a class for this key?It's seems like such a simple thing at first. Just a class with a few members. But then you have to initialize those members in the constructor. And then you need to write equals(). And don't forget hashCode(). Sometimes I'm tempted to create a concatenated string to get around the extra baggage. But that would be a hack.To solve this problem, I finally decided to create a Tuple class. A tuple is a an ordered collection of heterogeneous elements. Compare this to a vector, which is homogeneous. The type of a tuple is defined by the number and type of its elements.Examples of tuples that naturally occur in software are parameter lists and database rows. Both of these things have a fixed, finite number of elements that must occur in a certain order. All rows in a table have the same number and types of columns, but one column can have a different type from another. Some languages treat tuples as native data types, but not Java.My Tuple class comes in two pieces. The base class implements all of the comparison behavior. The concrete class lets you build a generic tuple.

package com.adventuresinsoftware.tuple;import java.util.ArrayList;import java.util.Iterator;public abstract class BaseTuple implements Comparable {    // Ordered collection of elements.    ArrayList elements = new ArrayList();    // Strings used to display the tuple.    String open;    String separator;    String close;    // Initialize the strings for this tuple type.    protected BaseTuple(String open, String separator, String close) {        this.open = open;        this.separator = separator;        this.close = close;    }    // Add elements to the tuple. Supports dot-chaining.    protected BaseTuple addElement(Object o) {        elements.add(o);        return this;    }    protected BaseTuple addElement(int i) {        return addElement(new Integer(i));    }    // Compare two tuples. All elements must be equal.    public boolean equals(Object obj) {        if (obj == null)            return false;        if (!(obj instanceof BaseTuple))            return false;        BaseTuple that = (BaseTuple) obj;        if (that.elements.size() != this.elements.size())            return false;        for (int i = 0; i < elements.size(); ++i) {            if (!that.elements.get(i).equals(this.elements.get(i)))                return false;        }        return true;    }    // Calculate a hash code based on the hash of each element.    public int hashCode() {        int result = 0;        Iterator it = elements.iterator();        while (it.hasNext()) {            result = result * 37 + it.next().hashCode();        }        return result;    }    // Display the tuple using the open, separator, and close    // specified in the constructor.    public String toString() {        StringBuffer result = new StringBuffer(open);        Iterator it = elements.iterator();        while (it.hasNext()) {            result.append(it.next());            if (it.hasNext())                result.append(separator);        }        return result.append(close).toString();    }    // Order by the most significant element first.    // The tuples must agree in size and type.    public int compareTo(Object o) {        BaseTuple that = (BaseTuple) o;        for (int i = 0; i < elements.size(); ++i) {            int compare = ((Comparable) this.elements.get(i))                .compareTo((Comparable) that.elements.get(i));            if (compare != 0)                return compare;        }        return 0;    }}
package com.adventuresinsoftware.tuple;public class Tuple extends BaseTuple {    // Display a coma-separated list of elements.    public Tuple() {        super("(", ", ", ")");    }    // Add generic elements to the tuple.    // Supports dot-chaining.    public Tuple add(Object o) {        super.addElement(o);        return this;    }    public Tuple add(int i) {        super.addElement(i);        return this;    }}

To use a Tuple as a compound HashMap key, just construct one in place using dot-chaining.

    public void testTupleHashMap() {        Map population = new HashMap();        population.put(            new Tuple().add("TX").add("Dallas"),            new Integer(1213825));        population.put(            new Tuple().add("TX").add("Fort Worth"),            new Integer(624067));        population.put(            new Tuple().add("IL").add("Springfield"),            new Integer(203564));        population.put(            new Tuple().add("NM").add("Albuquerque"),            new Integer(494236));        assertEquals(new Integer(624067), population.get(            new Tuple().add("TX").add("Fort Worth")));        assertNull(population.get(            new Tuple().add("NM").add("Roswell")));        assertNull(population.get(            new Tuple().add("NJ").add("Springfield")));    }

The Tuple class has a useful toString method.

    public void testTupleToString() {        Tuple tuple = new Tuple().add("MLB").add(1);        assertEquals( "(MLB, 1)", tuple.toString() );    }

And if you want to create your own strictly typed tuples, you can declare your own derived class.

package com.adventuresinsoftware.tuple;public class Version extends BaseTuple {    // A version is a tuple of 4 integers separated by periods.    public Version(int major, int minor, int release, int qfe) {        super("", ".", "");        addElement(major).addElement(minor).addElement(release).addElement(qfe);    }}
    public void testVersion() {        Version v1 = new Version(2,0,2,3425);        Version v2 = new Version(2,1,0,241);        assertEquals("2.0.2.3425", v1.toString());        assertEquals("2.1.0.241", v2.toString());        assertTrue("Version 2.1.0.241 > 2.0.2.3425", v2.compareTo(v1) > 0);    }

Enjoy!