Sunday, April 1, 2012

Simplified Communication Between Applications

There exist several processes that can be used to communicate information between Java EE applications: JMS, database storage/retrieval, printing/OCR scanning, etc. (For a distributed version of the last one, see RFC 1149.)

But each of these requires the creation and management of resources, along with complicated APIs. Probably the best "hidden" feature of Java, beginning with JDK 1.4, is that there is already such a capability that can conduct complicated communications connecting Java EE applications: the Logger object.

Loggers can be given arbitrary names, and these logger objects are shared across the JVM. So if more than one application within an app server run the following:

    Logger logger = Logger.getLogger("logger0");

...both applications have a handle to the same object. We have the beginning of our inter-application communications framework so far. What makes this useful is that every Logger can contain a Level, and Levels hold a value that can be any integer. So we have, in essence, a map of strings to integers that can be accessed by any application within the server. The possibilities are wide open.

To test this, I have a simple web application that asks the user for 3 numbers and stores them in loggers like this (simplified slightly):

        Logger.getLogger("april1loggerA").setLevel(Level.parse(a));
        Logger.getLogger("april1loggerB").setLevel(Level.parse(b));
        Logger.getLogger("april1loggerC").setLevel(Level.parse(c));

A separate web application, when reloaded, retrieves the values and displays them:

        fieldA.setValue(getLevelValue(Logger.getLogger("april1loggerA")));
        fieldB.setValue(getLevelValue(Logger.getLogger("april1loggerB")));
        fieldC.setValue(getLevelValue(Logger.getLogger("april1loggerC")));

...where getLevelValue(Logger) simply returns logger.getLevel().intValue() or null if there is no level set. The entire source application is in this file, and the entire destination application is in this one. You can use this pom.xml [edit: fixed broken link] file to build either project -- just change 'artifactId' and 'finalName' to suit the circumstances.

Here is a screen shot of the 'source' application in exhilarating action:


...and the 'destination' application, before and after the data above was submitted:


Both of the applications were deployed to a GlassFish 3.1.2 server. Hopefully this blog sheds some light on a woefully underutilized feature of Java. This kind of communication between applications involves no setup before deployment, can be used with any number of applications, and doesn't directly couple applications to each other. It's left as an exercise to the reader to explore extending Level to include any arbitrary data, not just integers (though there are a lot of integers).


Also, happy April 1st everyone.