JSP Tag Files

I’ve written my fair share of JSP 1.0 tags, the hell of deciding whether to extend TagSupport or extend BodyTagSupport and implement BodyTag, writing tons of StringBuffer append statements left alot to be desired. Almost all of the tags that I wrote wrapped up some piece of presentation logic with a bunch of HTML, which meant alot of header.append(“html content”) type statements. Luckily, it seems that there were other people who had bad experiences with the JSP 1.2 specification (or at least they understood that it needed improvement) which lead to the JSP 2.0 specification. Among other things, JSP 2.0 includes the ability to create JSP tags *using* JSP syntax, which means that front-end/GUI developers that don’t know Java can now easily create reusaeable tags without having to write and compile a Java class. It’s brain dead simple. Create a file in /WEB-INF/tags/ OR /META-INF/tags/ OR create a jar of all your tag files and place them in /WEB-INF/lib/, save it with a .tag or a .tagx extension, enter some content (ie: “Hello World!”) and then you can invoke the tag in a JSP by importing the taglib:

<%@ taglib prefix="tags" tagdir="/WEB-INF/tags" %>

and then the tag itself:

<tags:helloWorld/>

The prefix is determined by the taglib directive (in this case the prefix is ‘tags’) and the name of the tag is determined by the file name of the tag that you saved.

Using attributes is just as easy. At the beginning of the tag file you can add as many attribute directives as you want:

<%@ attribute name="title" %>

and then write their values to the screen:

<strong>${title}</strong>

I’m just scratching the surface though. There are 2 great articles on java.net to get you started if you want to learn more:

Easy Custom Tags with Tag Files, Part 1
Easy Custom Tags with Tag Files, Part 2

You can also read the JSP 2.0 specification (JSR-152).

As an aside, one of the things I always wanted to be able to do with ColdFusion was to deploy the custom tags I wrote as part of the application, in a non web-accessible directory without having modify the custom tag path through ColdFusion administrator. For instance, if you deploy a ColdFusion application to a shared host and you want to use your own custom tags, you have to either store the custom tags in the same directory as the script that you call them from (which does not help much at all), you an use cfmodule, which is a kludge, or you can ask the ISP/host to either add the directory where your tags live to the custom tag path or to put your custom tags into the existing custom tag path, neither of which is an attractive (or secure!) option. I haven’t used ColdFusion for awhile… can you do that now?

JSTL vs. Struts taglib

The last couple weeks have been spent working on a couple different Struts applications, all of which will be deployed on Tomcat 5 with Hibernate. I’m finding that working with Struts is an enjoyable experience, the framework encourages true separation of HTML presentation and business logic and model.

As someone working on all aspects of the application, one of the things I butt my head against pretty freqently are the limitations of the struts HTML & Logic tags. For example, an application that shows a listing of widgets commonly shows each row representing a widget in alternating colors… grey, white, grey, white, etc. The Struts tags, specifically the logic:iterate tag provides no mechanism for determining what the current row number is. There are a number of solutions out there, almost all of them suggest using scriplets to create a simple counter in the loop:

<%
String LIGHT_COLOR = "LightColor";
String currentColor = DARK_COLOR;
int i = 0;
%>
<logic:iterate id="product" name="products">
<%
if ( i % 2 == 0) {
currentColor = "BLACK";
} else {
currentColor = "WHITE";
}
i++;
%>
<tr ALIGN="center" class="<%=currentColor %>">
<td>
  <bean:write name="product" property="label" />
</td>
</tr>
</logic:iterate>

Of course, the entire reason tags are used is so that you don’t have to use scriptlets, so it seems like a pretty ugly hack to me. Fortunately I’m using Tomcat 5, so I stumbled upon the JSTL forEach tag, which provides effectively the same functionality as the Struts iterate tag, with the benefit of an index and row status so that the above code becomes:

<c:forEach var="product" items="${products}" varStatus="status">
  <c:choose>
   <c:when test="${status.index % 2 == 0}">
   <tr ALIGN="center" class="dark">
   </c:when>
   <c:when test="${status.index % 2 != 0}">
   <tr ALIGN="center" class="light">
   </c:when>
  </c:choose>
</c:forEach>

which is a bit more simple, with the main benefit that you don’t have use any Java code.

Further, it seems that there is alot of overlap between JSTL and the Struts tag library, which isn’t a bad thing. I’m guessing that not everyone has the opportunity to use JSTL since it requires a web container that supports JSP 2.0, but for those who are deploying to JSP 2.0 web containers, how much do you use JSTL versus the Struts tags? Are you phasing out Struts tags for JSTL? Keeping with Struts tags to maintain a sort of purity to your application?

Can a Developing Nation Be Creative?

Nicholas Negroponte asks the above question in one of the articles from the latest issue of ITID [abstract] [full source]. From what I gather, he posits that for developing nations to be successful, they require “.. discipline, team playing, and efficiencies that come from standardized,controlled, preplanned, and highly regulated environments” but that same discipline and highly regulated environment discourages creativity.

“By contrast, a creative society values and expects different social qualities, almost all of them in the service of imagination. Originality, resourcefulness, and inventiveness are central to the personality of creative people. They can be very contrarian. Expression and individualism are also high on the list. A creative culture welcomes and even encourages a healthy questioning of authority, especially when it is authority for authority’s sake. Complexity and contradiction provide the rich soil for growing new ideas. Quality of life comes from design and invention, and the arts play a central role.”

I found this interesting because I think that this formula is exactly the opposite of what you see in the lifecycle of a corporation, a much smaller organism than a country, but a culture nonetheless. A startup is full of creative people with new ideas, inventions, etc. If the startup lives long enough, new management is likely brought in, rules are created, the free soda goes away and you have to report to your desk at 8am or else you get written up (like you’re in 3rd grade all over again). Nicholas postulates that this is the exact situation facing students in their first years of school:

“By contrast, all the behavioral characteristics needed to jump-start and accelerate economic development seem to be the opposite, and those lead to a very uncreative environment. This is often most manifest in primary education, where the typical emphasis on drill and practice makes kids fearful to ask questions, frightened to make mistakes, and afraid to be different.”

The situation described in the quote above is eerily similar to the environment I work in: people are punished for making mistakes, afraid to be different and don’t question authority.

This then begs the question: can an established organization be creative? Jason Kottke recently posted a link to a speech that Paul Depodesta (at the time assistant general manager to the A’s, now the general manager of the Dodgers) gave at a CSFB conference (in a weird turn of events, CSFB removed the speech from the web, Jason has archived it here). In the speech he talks about his experience working in the Cleveland Indians:

“Going back to my time with the Indians, we were enormously successful during this time. The stadium was sold out every night, we were going to the playoffs every year, we were making more money than any other team in the game, but I could see that our process was really starting to slip. Before I had arrived with the Indians they had a phenomenal process. They had done a great job of scouting players, developing players, they were very innovative in the way they signed players to multi-year contracts, but ultimately we got away from that.

All of our success to some degree actually began to stifle our innovative spirit, and we started slipping from the upper left column of the deserved success.

He goes on to mention that because the Indians were successful at the time, there was no impetus for change, no reason to be creative:

Seemingly, at least on the surface, there really was no crisis in Cleveland. We really were just trying to hang on, rather than continue to push forward.

In short, he had to go to a team (the Oakland A’s) that was losing, both games and money, in order to ask his questions. Can established organizations be creative? Maybe failure, not catastrophic failure, but failure nonetheless, is a prerequisite for creativity.

Information Technologies and International Development Journal

At the bottom of the latest MIT Press newsletter was the introduction of a new journal called “Information Technologies and International Development” or ITID for short. It’s focus is:

“… on the intersection of information and communication technologies with international development. Readers from academia, the private sector, NGOs, and government interested in the “other four billion”—the share of the world population whose countries are not yet widely connected to the Internet nor widely considered in the design of new information technologies.”

The entire first issue is available online for free.

C# Public Properties vs. Java getX() and setX()

Martin Fowler blogged about C# properties a couple weeks back saying that he “.. liked the notion of properties right from the start..” because it’s “.. much more natural to write obj.X = other.X.” Further, ” … from a language point of view, properties and fields look the same. So if I have a field x which I can just read and write to, I can just declare it as a field. I don’t worry about this violating encapsulation, because should I wish to do something more fancy I can just replace it with a property later. It all saves a lot of typing of stupid accessor functions.” For those of you who have never used C#, instead of writing this in Java:

// Java getter & setter
private String foo;
public String getFoo() {
  return this.foo;
}
public void setFoo(String foo) {
  this.foo = foo;
}
// access the private variable foo like this:
bar = obj.getFoo();

you can write this:

// C# public property
private String _foo;
public String Foo {
  get {  return _foo; }
  set {  _foo = value; }
}
// access the private variable _foo like this:
bar = obj.Foo;

I initially liked this feature of C# as well, it definitely seems more natural to use properties. Also, like Martin mentions, it saves you from having to make decisions about encapsulation.. do you use a getX()/setX() method or do I just mark it as public? With C#, you can change the implementation without changing your published API.

Martin points out that in this case beauty is only skin deep. If you use reflection to access the public properties or fields of a C# class, you might be surprised to see that the implementation does in fact change. In the example above, the property ‘Foo’ gets turned into 2 methods: get_Foo() and set_Foo(), which you can see using reflection:

Type type = (typeof(YourClassName));
MemberInfo [] members;
members = type.GetMembers(BindingFlags.Public|BindingFlags.Instance);
Console.WriteLine( "\nThe public instance members of class '{0}' are : \n", type);
for (int i =0 ; i
Martin ends by noting "... now I have to write stupid accessor functions for accessible data values." which is something that your IDE can do for you. In Eclipse, declare your private instance variables and then right click --> Source --> Generate Getter & Setter...

Amazon Web Services Newletter cool links

The February Amazon Web Services Newsletter had some pretty cool applications:

Blogfuel: “Use blogfuel to create a link to an individual item at amazon (using ASIN Search) to illustrate your book review. Or place the code in the sidebar of your blog as a “What I am currently reading feature”. You have control over the width, colour, number of columns, image and text size.

PocketBooks – Amazon: “Check prices and availability of books at Amazon.com and Amazon.co.uk from your Java enabled phone

Books of note, from Sybex: Mining Amazon Web Services: Building Applications with the Amazon API and from Dimensions: Google, Amazon, and Beyond: Creating and Consuming Web Services

Ant WAR Task & WEB-INF in lowercase

If you use the Ant war task to create, well, war files, and you notice that the resulting archive has a lowercase WEB-INF folder, it’s a not a bug with Ant, as the documentation states:

We regulary receive bug reports that this task is creating the WEB-INF directory, and thus it is our fault your webapp doesn’t work. The cause of these complaints lies in WinZip, which turns an all upper-case directory into an all lower case one in a fit of helpfulness. Please check that jar xvf yourwebapp.war shows the same behaviour before filing another report.

Easy fix. Open up WinZip and click Options –> Configuration and then check the option for ‘Allow all upper case file names’.
Winzip Options Menu

Asynchronous Method Invocation in Java

I’m working on a web application that needs to kick off a process that could take anywhere from 5 seconds to an hour, so I need to be able to call a method and have it return immediately. A google search for ‘java asynchronous method‘ didn’t return much, except this, which seems to indicate that simply spawning a new thread within a method will do the job. Basically you end up with something like this:

public class LongProcess implements Runnable {
  public void startProcess() {
    Thread t = new Thread(this);
    t.start();
  }
  
  public void run() {
    // perform the long running process
  }
}

and then you can kick the process off like this:

LongProcess p = new LongProcess();
p.startProcess();

The other solution I thought of would be to use an asychronous xml-rpc call, although this obviously has more overhead.

Are there any solutions I’m missing? What would you do?