Tuesday, March 31, 2009

An Annotated AJAX (via JSON) Spring Controller

Because I could not find an example of an annotated Spring AJAX (via JSON) controller in Google, I forged ahead and figured this one out on my own. I thought I would share this code snippet with the blogosphere. Without further ceremony here is the code example:


@Controller
public class AjaxController {
@RequestMapping("/index")
public void handler(@RequestParam("myParam") Object myParam,
HttpServletResponse response) {
JSONObject json = new JSONObject();
json.putAll(getMyData(myParam));
response.setContentType("application/json");
response.setHeader("Cache-Control", "no-cache");
response.getWriter().write(json.toJSONString());
}
}


The URL request mapping is specified with the RequestMapping annotation. Make sure the path is accessible by properly configuring with web.xml with the correct servlet-mapping. Note that the annotated Spring controller offers tremendous flexibility with respect to the method signature. We can leverage this feature for building the AJAX request handler method. Moreover, you can specify the required URL parameters via the RequestParam annotation and bind them to the method arguments. Lastly, you will need the HttpServletResponse object for the JSON response. Notice that the method returns void because the JSON response is returned via the response object.

The JSON library I used can be found here.

Handle the JSON in the browser with your favorite JavaScript library (e.g. YUI).

Sunday, February 15, 2009

Google Threw Me a Bone

This past week I received a package from Google - 1600 Amphitheatre Parkway Mountain View, CA 94043. That's right, Google. I
was unaware that Google knew of the existence of the USPS, considering it a communication mechanism from the time of Neanderthals.

I opened it to reveal:

  • A Rubik's Cube
  • A mouse pad
  • A pen
  • A "My Other Computer is a Data Center" bumper sticker

All were emblazoned with the Google logo.

And a thank you note hand written with excellent penmanship. They sent me some Google schwag as a token of their appreciation for the contributions I have made to the Google Chart API -- both on the group list and the wrapper API I developed, charts4j .

There is no name to reveal who sent it.

At any rate, in the extremely unlikely possibility the person that sent this to me is reading this blog post (I think I am the only one who reads my blog, except for my wife), thanks for the schwag, especially the Rubik's cube.

Wednesday, February 11, 2009

What? Java Can't Sort Numbers?

I was recently working on some charts4j code to sort a list of Numbers (java.lang.Numbers -- to be exact) and discovered that it could not be done simply by calling Collections.sort. I would think, if anything ought to be sortable in Java, it should be a list of Numbers.

As most Java programmers know, sorting lists in Java is easy -- sort of. "Simply" use the static Collections.sort method, which under the hood is implemented with the classic merge sort algorithm. The major caveat, of course, is that the class of objects you are sorting must implement the Comparable interface by having a properly written compareTo method. Fortunately, many classes in the core Java language already implement Comparable: String, Date, Integer. They can immediately be sorted with Collections.sort without any special effort from the programmer, but not for Numbers. I did a little research by posting a question on this topic on Stackoverflow. I received a lot of good albeit -- Sun party line -- answers. The issue is a bit more complex than one would immediately think.

The simplest explanation for why java.lang.Number does not implement Comparable is rooted in mutability concerns. For a bit of review, java.lang.Number is the abstract super-type of AtomicInteger, AtomicLong, BigDecimal, BigInteger, Byte, Double, Float, Integer, Long, Short. On that list, AtomicInteger and AtomicLong to do not implement Comparable. Digging around, I discovered that it is not a good practice to implement Comparable on mutable types because the objects can change during or after comparison rendering the result of the comparison useless. Both AtomicLong and AtomicInteger are mutable. The API designers had the forethought to not have Number implement Comparable because it would have constrained implementation of future subtypes. Indeed, AtomicLong and AtomicInteger were added in Java 1.5 long after java.lang.Number was initially implemented.

Apart from mutability, there are probably other considerations here too. A compareTo implementation in Number would have to promote all numeric values to BigDecimal because it is capable of accommodating all the Number sub-types. The implication of that promotion in terms of mathematics and performance is a bit unclear to me, but my intuition finds that solution kludgy.

A related issue to this discussion is autoboxing. In Java 1.5, Sun introduced this language feature to seamlessly go back and forth between primitive numeric types and reference types. This is useful for adding and getting numbers in and out of Collections, for example, without having to explicitly convert the primitive type to a reference type. The Java numeric primitive types are byte, char, short, int, float, and double. They all have corresponding reference types, Byte, Character, Short, etc. Those reference types all extend Number (except for Character). The rules for converting from primitive types to boxed reference types are difficult to anticipate for purposes of building APIs. (I thought Java 1.5 was supposed to be all about type safety.) For instance, Arrays.asList(1,2,3) yields a List<Integer> and not a List<Long>. Arrays.asList(1.0,2,3) produces a List<? extends Number> instead of a List<Double>. This lack of predictability is burdensome for API designers, because they essentially have to build multiple method signatures to accommodate multiple boxed numeric reference types. Overloading the method signature may not even be an option in the case of Collections since List<Integer> and List<? extends Number> have the same erasure. One possibility is to rely only on the Number type or in the case of Collections List<? extends Number> for polymorphism but the problem is that the Number type is too general, encompassing more than the Java boxed primitive types, and it does not implement Comparable.

A potential solution is to implement an intermediate RealNumber type that would extend Number and encompass all the boxed numeric primitive types (except for char). This approach would allow polymorphism on numeric primitive types via autoboxing. Moreover, it would be reasonable for this RealNumber type to implement Comparable by promoting primitive numeric types to double in the compareTo method.

Unfortunately, this is yet another example of how Java has never been great in the numerical computation arena.

Wednesday, January 28, 2009

The iPhone Changes the Game for Small Independent Software Vendors

Over the years at the Boulder Java User Group, I have discovered many technologies that have eventually played an important role in my daily software development, YUI or YSlow, for example. Matthew McCullough's fascinating talk earlier this month on iPhone development may
eventually turn out to have been another influential moment.

For a bit of background, last year Apple finally opened up the iPhone platform to non-Apple developers. This sea change reveals a vast and relatively unexplored landscape for software developers where there are probably many good ideas ripe for the picking. In addition, iPhone's smart phone market share is large and growing rapidly potentially providing many customers for iPhone developers. The revenue model is also tantalizing; developers may sell their applications at the iTunes store -- an extremely high visibility marketplace. I know of no other high profile online store where small independent developers have relatively easy access to huge audiences. Of course, this scenario makes the rosy assumption that Apple will approve the application for sale at the iTunes store. Nevertheless, this possibility is better than the alternatives. Hopefully, we will be seeing more of these high visibility online software bazaars.

Contrast this situation to the web application arena, where it seems every good idea has been already explored, not to mention the fact that the competition is cut throat, and the revenue model usually depends on mega traffic, which is difficult if not almost impossible to attain. Overall, it remains extremely difficult to break through and get attention in the web application world.

As a consequence, Matt's BJUG talk certainly whet my appetite for iPhone development. The major caveat, of course, is developers such as myself must learn Cocoa and Objective-C, which is not a small feat. Back in 2003, I became interested in Objective-C and Cocoa development when OS X and the iPod were really becoming popular. I spent about a year tooling around during evenings and weekends learning Objective-C and Cocoa. While I was interested in this environment, nothing concrete ever materialized from my efforts and I moved on to other projects. At any rate, I am glad I did not toss those Cocoa and Objective-C books I purchased a few years ago. Indeed, I have been brushing up on my Cocoa as fast as I can.

Monday, January 12, 2009

Stackoverflow and the Future of Collaborative Media


Stackoverflow is the collaborative media site founded by the illustrious duo, Joel Spolsky and Jeff Atwood. It makes a fresh and original attempt to improve the state of the online software development community, and does so mostly successfully. The site combines the best features and concepts from wikis, blogs, forums, and sites like Digg and Reddit (and perhaps a even a touch of Twitter). The result is an impressive collaborative space where developers can post questions, obtain quick answers and spark discussions.

To highlight just a few Stackoverflow features:

  • Use of Open ID. Account creation -- often the biggest barrier for adoption for collaborative sites -- is near frictionless by leveraging this up-and-coming authentication mechanism.

  • Voting. Higher quality answers and topics tend to filter upwards via a voting and point scheme.

  • An outstanding user interface, with plenty of rich interactivity that adds to the user experience instead of detracting from it.

  • High web traffic yields quick responses and usually decent quality answers and discussions.

  • Questions, answers, and comments (assuming you have the credentials) are editable which means mistakes are corrected over time.

  • Unobtrusive ads.

The engineering behind Stackoverflow must be outstanding. I have noticed very few odd quirks (apart from the occasional dirty cache) and it seems to be scaling fine. This is certainly more proof that the ASP.net stack is at least as good as anything offered in the Java arena, not to mention the fact that Jeff Atwood and friends are extraordinary developers. They designed, implemented, and had the site up and running in just a few months. I have been fantasizing about starting a knockoff site with the Java Spring stack which would theoretically be very doable as long as you had the right talent and time. (I know, easier said than done.)

Stackoverflow is not perfect, however. Question and answers can receive up and down votes, and users accumulate reputation points based on the vote count of their questions and answers. Moreover, users obtain badges as they use the system. It can become annoyingly addictive. This merit system is both an asset and a detriment. The right answers theoretically filter to the top, but Stackoverflow also biases quick answers over the best answers because the quick answer simply receives more views and points. This fact in turn incites users to provides rapid-fire answers over more thoughtful, measured responses resulting in a positive feedback loop. They may be able to partially fix these issues through some algorithmic / social engineering tweak. The reputation point system also means that users can become competitive, which leads to pettiness, incivility, and even borderline vigilantism at times. For exhibit A, note the comments on the legendary (fellow University of Colorado alum) Alan Kay's question. Possibly a better solution is to provide a relatively low ceiling on reputation points.

Searching has problems, as well, and I have even posted questions that already had answers despite a preliminary search for my question. Again, they will fix this issue eventually.

The quality of the discussion is not universally great, but generally adequate and certainly better than the alternatives. For example, this discussion on JavaFX technology partially misses the point that JavaFX is very much related and built on top of applet technology -- a fact I try to point out.

At any rate, the development community is responding favorably to Stackoverflow, and the number of users is growing sharply.

Stackoverflow is the brainchild of Joel Spolsky and Jeff Atwood (actually mostly Jeff, I suspect) of software blogging fame. This effort is another example of how successful bloggers have bootstrapped other facets of their careers by using their blogs as self-promotional springboards.

Stackoverflow's meteoric rise proves there is a real hunger for collaborative spaces that don't suck. I predict that they are going to start spinning off other "spaces," some perhaps having nothing to do with software. Why not have cinema.stackoverflow.com, gaming.stackoverflow.com, IT.stackoverflow.com? Better yet, make those spaces integrated. For instance, if someone asks a question on the IT forum that belongs in the gaming forum, there would be a mechanism to re-assign the question to a better space. The evolution of Stackoverflow into other domains will provide an invaluable service to many online communities whose forums currently stink. How many times have you looked for something on the Internet only to arrive at a forum where your question has been asked but with no answer? Or that you do not have the credentials to provide the answer and that obtaining a login is too onerous. And, of course, you are assaulted with ads along the way. I have encountered this scenario countless times, as have my colleagues. Stackoverflow's expansion into other domains will be a quantum leap in the evolution of collaborative media. An evolution that I will wholeheartedly welcome.

Monday, December 15, 2008

Incorporating Google Charts into a Spring MVC application



The last blog post on interactively building charts with Clojure generated quite a bit of interest. As a continuation of the chart theme, I will describe how to incorporate professional quality charts into a Spring MVC web application by leveraging charts4j.

The Google Chart API potentially provides developers a lightweight mechanism to incorporate static and dynamic charts into a web application. Dealing with the Google Chart API directly, however, is tedious and error prone. Fortunately, charts4j, a lightweight wrapper to the Google Chart API, makes incorporating charts into your Spring web application much easier. To see examples of all the charts that can be generated with charts4j, see the chart gallery here.

See here to download the example code that this post describes. What follows below assumes some familiarity with how to build a Spring MVC web application.

To incorporate Google Charts into your Spring application, you will first need the standard Spring MVC infrastructure:

  • 8 Spring framework jars and friends: commons-logging-api-1.1.jar, jstl.jar, spring-beans.jar, spring-context.jar, spring-core.jar, spring-web.jar, spring-webmvc.jar, standard.jar. Put these jars in the WEB-INF/lib directory.
  • 3 Spring and servlet XML configuration files: applicationContext.xml, frontController-servlet.xml, web.xml. Put these XML files in the WEB-INF directory.

Plus, you will need to write one Spring Controller, one JSP. And most importantly, also grab the charts4j jar and put it in WEB-INF/lib.

Here is the controller code:
@Controller
public class ChartController {
    @RequestMapping("/index.html")
    public ModelAndView indexHandler() {
        //Your really great chart.
        final Plot plot = Plots.newPlot(Data.newData(0, 66.6, 33.3, 100));
        final LineChart chart = GCharts.newLineChart(plot);
        chart.setTitle("My Really Great Chart");
        //Passing the chart to the JSP for rendering.
        return new ModelAndView().addObject("url", chart.toURLString());      
    }

}

Note that I am making use of the newer style annotation based Spring MVC controllers. Also, the line

final Plot plot = Plots.newPlot(Data.newData(0, 66.6, 33.3, 100));

has static, hard coded data, but the real power of this mechanism comes into play when the application dynamically generates data. For example, perhaps you would like to display up-to-date stock price or weather data from your database in your web application.

In addition, here is the JSP code:
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Your great chart</title>
</head>
<body>
<img src="${url}" alt="Chart" />
</body>
</html>



The only noteworthy lines of code in the JSP are highlighted. To display the chart in the JSP, use an HTML <img> tag with the URL generated in the controller: <img src="${url}" alt="Chart" />Also note that I am using the JSTL EL to access the URL string.

Deploy your web application and that is it. You are done.

The strength of this solution is its small footprint and low impact on your code base. To generate nice charts in your Spring MVC application, all you need is one 160 kb charts4j jar, an
Internet connection, a bit of charting code and you are done. No need for special graphics libraries, extra servlet infrastructure, etc. There are many more chart examples with code samples here.

Finally, the Google Chart API and charts4j will satisfy many Java application charting requirements, but there are three reasons why you may not wish to choose this technology:

  1. No Internet connection, no Google Charts. Your application must be connected to the Internet because the charts are ultimately rendered by the Google Chart API.
  2. There is no security with these charts. Your data will be sent as clear text over the Internet, and it would be trivial for someone to intercept this information.
  3. If you have lots of data, roughly speaking, more than 2000 data points, you should try to sample your data less frequently, and use the simple encoding scheme. If this is not a possibility, this technology may not be right for you.

This blog post has shown you how to incorporate charts4j in your Spring MVC web application, but there is no reason why you cannot also incorporate charts4j in any Java application environment, as long as the three requirements above are met. Moreover, this design pattern of generating charts in the servlet layer and rendering the chart URL in the JSP will work for any Java web application environment (e.g Struts, etc.)

Tuesday, December 2, 2008

Interactive Charting with Clojure


I stumbled upon the Clojure programming language a few months ago when I was trolling around the Internet for topics relating to Java threading and concurrency. This Lisp and Scheme derived dynamic language runs on the JVM and has the ability to invoke Java APIs via the Clojure special form syntax. One of Clojure's main features is its strong support for concurrent programming, taking advantage of its bias toward immutability, and leveraging its own notion of software transactional memory in addition to invoking the java.util.concurrent API and the forthcoming fork-join framework.

At any rate, Clojure is dynamic and thus has an interactive shell or REPL. Because you can invoke Java APIs from the REPL, I thought it would be a fun exercise to leverage charts4j to build charts interactively. I created the charts above and below fairly easily, certainly much easier than in a Java main program because Clojure's dynamic environment provides instant feedback. You can find the Clojure script that generated these images here.

Simply load it with the following command: (load-file "charting.clj"), setting your path appropriately, of course. You will also need the charts4j jar in your Clojure classpath. Moreover, you must be connected to the Internet for this script to run, as the charts are ultimately rendered by the Google Chart API. It will play a slide show, and can be a starting point for generating your own charts interactively. It should be straightforward to generate all the charts available in charts4j by using that script as an example. One last important note about the charting.clj script; it works with the latest Clojure SVN revision as of the day of this blog post, but this language is still young, and the Clojure authors are still fiddling with the syntax. Therefore, I also provide a "charting-20080916.clj" that works with the official latest release.

If there is enough interest, I may write a Clojure library that would make this interactive charting environment a bit easier to use, for instance by predefining more chart functions. This library could even be combined into a Clojure tutorial as programmers often respond to visual cues and eye candy as they are hacking away at code.

For the Clojure experts out there, I would welcome feedback on my Clojure code.