Archive for the ‘Java’ Category

JavaFX Demo: Damn Pipes

This is what I learned from today’s JavaOne news…

JavaFX Pipes

You can see the QuickTime demos here.

And about those crashes:

Unfortunately, the application, using the new Java Update 10 browser plug-in, kept crashing. “It’s the size of the pipes in Moscone Center,” Green complained. “This is the Moscone terror moment.”

Eagerly Awaiting JavaFX

The JavaFX page is up, but so far it’s all QuickTime videos. I wonder when the site will eat its own dog food?

JavaCrashX

This never makes a good first impression:

Unfortunately, the application, using the new Java Update 10 browser plug-in, kept crashing.

Someone Please Explain This

I don’t understand this claim:

Another problem is that it only supports 64 bit applications. Bye bye applets in Safari.

I found that in this article about Java 6 on Mac.

I always assumed that Java .class files are the same regardless of platform. A .class file compiled on one system should still run on Macs, even though their VM is 64-bit. But that quotation sounds as if the .class file format is different and code must be specifically compiled in some 64-bit mode to run on Macs. What am I missing?

Null Creep

I believe it is really important to clearly specify how your classes react to null values. Suppose some class is buried deep in your application code:

public class Company {
  private final String id;
  private final String name;

  public Company(String id, String name) {
    this.id = id;
    this.name = name;
  }

  public String getId() {
    return id;
  }

  public boolean equals(Object o) {
    // ...hmm...can id be null? Better write some defensive code:
    if (id == null) { ... }
    ...etc
  }
}

Perhaps a class like this represents some fundamental concept and is used throughout an entire family of applications. While reviewing the code, you see the equals(...) method checks for a null id. And you wonder…can the id ever be null?

There Must be a Reason

Surely the original programmer put that null check in for a reason. Or maybe not — maybe he generated the equals() and hashCode() methods using an IDE? There are no comments, and you discover everyone using the Company class also checks for null:

public void connectTo(Company c) {
  String id = c.getId();
  if (id != null) {
    ...
  }

Maybe the programmer who wrote that method just wasn’t sure — since Company has no comments. So in an effort to “be safe”, he checks for null before using the company id.

Creeping Dread…

And what do you do if the id really is null? Oh, crap. Now you have to throw an exception, and someone has to eventually catch it. Everything from the data access layer on up to the GUI has to anticipate the possible error.

Because the first programmer failed to document how Company handles null, EVERYBODY who uses the Company class now has to assume the id might be null. The fact that the original programmer included some null checking in the Company class seems to imply that it might indeed be null.

A Better Solution

If null really is allowed, that’s fine — you just need to document that fact. But if null really is illegal, then fail fast:

public class Company {
  private final String id;
  private final String name;

  public Company(String id, String name) {
    if (id == null) throw new IllegalArgumentException("null id");
    if (name == null) throw new IllegalArgumentException("null name");

    this.id = id;
    this.name = name;
  }
  ...etc

That tiny exception now means everybody using the Company class can eliminate their null checking. Which means instead of potentially checking for null and reacting by throwing NullPointerException from dozens of locations scattered about your app(s), the validation occurs in a single location.

For more fun, check out these @Nullable and @NotNull annotations.

When Does EJB Make Sense?

Ted says:

If you’re like most Java developers, you heard the term “EJB” and immediately got a note of distaste in your mouth.

Yep, that’s right. The first thing that comes to my mind is…complexity. You never really write EJBs by hand because there is so much duplication and so much configuration. The fact that EJBs (for all practical purposes) require code generation tools (XDoclet, wizards, etc) is a bad sign. He continues:

You know that if you suggest EJB on your next Java project, you will be ridiculed and shamed and made to stand in the corner with the Dunce Cap on, even if it makes complete sense from a technical perspective.

I wouldn’t suggest EJB for the next project. In fact, I’m trying to imagine how it would ever make complete sense from a technical perspective. I cannot think of any reason to advocate EJB.

The paragraph then suggests:

Companies are choosing instead to build their own transactional-oriented client/server middleware infrastructure, just to avoid the “shame” of using EJB. Because, as we all know, you just can’t test EJB.

I don’t think shame has much (if anything) to do with it, nor do I even think testing is that big a deal. Hardly anybody builds transactional infrastructure, although I guess that depends on what you mean by “transactional infrastructure”.

It is damn easy to grab Spring, Tomcat, and a handful of other open source projects to completely replace EJB. Not even a day’s effort. Hell, I recently put together a server-side app using Tomcat and Guice, and the whole “transactional infrastructure” consisted of little more than some ThreadLocal helper classes, a bit of AOP, and a servlet filter. Shame on me for spending a day to build my own infrastructure and be free from EJB for the next several years of maintenance on this project!

I submit to you that my Guice + Servlet project is far easier for humans to comprehend and maintain than any EJB app.

No Shame Here

We do not avoid EJB for “shame”. We avoid EJB because we know how much of a pain EJB is, and we know that thanks to products like Terracotta, for instance, we can duplicate EJB’s feats with far less pain.

EJB is painful because it suffers from accidental complexity. The programming model encourages duplication, and generally forces us to complicate our build procedures by incorporating code generation steps and/or “wizards”. At runtime, it is painful because it promotes a monolithic, gigantic EAR file that makes scaling out to clusters all that much harder. EJB is painful because it locks you in to a particular app server for all but the most trivial apps. It is painful because error messages are so cryptic. It is painful because of classpath woes. It is painful due to slow deployment, and OutOfMemoryErrors when you hot-deploy one to many times.

I feel no shame by advising my friends and customers: avoid EJB. There are better, simpler solutions, free solutions.

On Second Thought…

Maybe I would feel shame if I advised you to use EJB. I guess Ted’s right. I avoid EJB to avoid the shame.

Back When It Was The JDK

This graphic illustrates the JDK naming history.

JDK Version History

I like “JDK 6u5″ the best. The first number indicates API changes, the second number indicates implementation changes. The “JDK” lets you know this is the development kit, not the runtime environment. This is simple, concise, and easy to understand.

I think the 1.x.0_0y scheme is redundant and confusing because the “1″ and “0″ never change any more.

The whole “Java SE 6″ name just adds to the confusion. Nobody I know says that name out loud. It reminds me of the asinine commercials where the 5 year old kid is singing “I am stuck on Band Aid Brand”, as if a 5-year old would ever say “Band Aid Brand”.

Simplified Array Syntax

Sometimes, when working with Java 5/6, you still have to call methods from pre-Java 5 libraries. For instance, many of our DAOs are littered with code similar to this:

jdbcTemplate.query(sql,
    new Object[]{ customerId, customerName },
    new int[]{Types.INTEGER, Types.VARCHAR},
    ... );

I don’t like the new Object[] { … }, So today I wrote a static method:

public static <T> T[] array(T... t) {
    return t;
}

And another for primitive ints:

public static int[] intArray(int... i) {
    return i;
}

Thus, I can now write the original code like this:

jdbcTemplate.query(sql,
    array(customerId, customerName),
    intArray(INTEGER, VARCHAR),
    ... );

I have to say that static imports and varargs are among my favorite Java 5 syntax features. Now if only I didn’t have to have special methods to handle arrays of primitives.

The Right Tool for the Job

Not all projects are skyscrapers.

In fact, hardly any projects are skyscrapers.

Sometimes complex tools are overkill.

JavaOne Registration Bug

A coworker was informed (by a flawed web app) that his JavaOne registration could not be found. And he was unable to login because “his email address is invalid”. Apparently his email must end in something like .com, .edu, or perhaps even .cc to be considered “valid”. (at least according to the JavaOne registration system)

Guess what? .coop is a valid domain name extension. When writing data validators, make sure you don’t reject valid data.