Eclipse gave a surprising left jab while unboxing

I'm working on a project for a client to integrate an existing web-based mortgage application to work with a large mortgage-loan consolidator. The existing application has a large code base originally targeted for Java 1.3. We needed to create an integration API and wanted to take advantage of some of the concurrency classes introduced in Java 1.5. The client gave approval to use 1.5 for the new code.

Upgrading went smoothly. We had to rename an existing package that included the new enum keyword, but the 1.3 code easily upgraded to 1.5. Being able to use 1.5 was nice because I like the generics support, the simplified "for-each" syntax to iterate over collections, and the simplified concurrent package. Many of the new concurrency features also are available for earlier versions of Java in the backport-util-concurrent library. I like Eclipse's support for 1.5, such as typing "foreach[Ctrl-SPACE]" and having Eclipse make a pretty good guess at filling in the simplified for-each loop code, including the collection reference to iterate over, and picking a good name for the temporary iterator variable.

For example, if you start a method:
public CreditReport getTriMergeForBorrower(
Borrower borrower, Set creditReports
) {
and you want to loop over the creditReports to search for the correct one for this borrower, you can type:
foreach[Ctrl-SPACE]
and Eclipse will replace that with:
for (CreditReport report : creditReports) {
}
Eclipse looks "up" in the code to find the nearest iterable, fills in the correct type for the iteration temporary variable, and gives the temporary variable a reasonable name. Pretty nice. But as the title of this entry implies, I got an unexpected jab from Eclipse, or more accurately, my reliance on it.

Eclipse is aware of another "new" feature in 1.5: autoboxing and unboxing. Autoboxing is the term for the Java compiler allowing you to write code that treats primitives as their equivalent object types (an int treated as if it were a java.lang.Integer, for example). Auto-unboxing is the opposite: using an object when the expression calls for a primitive. If you haven't been able to use Java 1.5 on a project, here's a short introduction.

With autoboxing, you can write code like this (from the above-reference Sun website):
public static void main(String[] args) {
Map m = new TreeMap();
for (String word : args) {
Integer freq = m.get(word);
m.put(word, (freq == null ? 1 : freq + 1));
}
System.out.println(m);
}
Notice how it appears you can pass an int as the parameter to be inserted into the TreeMap. Even though you really can't put a primitive into a collection like a map, the compiler (not the Java runtime) corrects this "incorrect" coding by inserting hidden code to create an Integer object to wrap the primitive int value. Autoboxing makes the code look a little cleaner: Let the compiler do the work rather than the programmer.

I've known you could write autoboxing code like the above for a couple of years. In August, 2004, two months before Java 1.5's general release, I attended a talk by Joshua Bloch and Neal Gafter at the Denver Java Users Group, introducing the new features in Java 1.5 (Tiger). But what I hadn't considered was that you sometimes could write auto-unboxing code without realizing it. It happened to me with code like:
if (creditReport != null && creditReport.isTriMerge()) {
// do some processing
}
When testing the code, it threw a NullPointerException. When I saw the stack trace, I said Huh? The creditReport reference obviously isn't null when invoking isTriMerge, so where did the NPE come from? A moment later, it hit me. The isTriMerge method must be returning a Boolean, not a boolean as I had assumed when I looked at the business object's API using Eclipse's Ctrl-SPACE to show options. I let Eclipse fill in the isTriMerge method name when I typed the if statement. Eclipse didn't complain about the syntax, so my natural assumption was a method named "isXXX" would return a boolean.

Instead, the CreditReport business object uses object wrappers for all its primitive-value fields, so when the object is persisted in the database, it can use NULL values to indicate "unspecified." The getters all return objects.

When writing code that takes advantage of unboxing, you can end up creating seemingly odd statements like:
if (creditReport.isTriMerge() != null &&
creditReport.isTriMerge()
) {
// Do something
}
where you check a value for null and whether the value is true. It looks unusual, compared to the pre-Java 1.5 version:
if (creditReport.isTriMerge() != null &&
creditReport.isTriMerge().booleanValue
) {
....
which is what the compiler is actually inserting into the .class file's bytecode.

Unexpected NullPointerExceptions occur when you don't realize that your "primitive" value is really an object being dereferenced inside hidden code. I found this big discussion of automatic unboxing on TheServerSide from three years ago, debating whether unboxing is a good thing.

So, live and learn. I don't see autoboxing/unboxing as bad. Programmers just need to be cognizant of whether a variable holds a reference to a primitive object wrapper rather than a true primitive value, and whether a method returns an object rather than a primitive. And if you want to be cautious, you can ask Eclipse to warn you about possible unboxing problems. Eclipse (I'm using 3.2) has a Java code setting: Window | Preferences | Java | Compiler | Errors/Warnings | Potential programming problems | Boxing and unboxing conversions. You can tell Eclipse to flag boxing/unboxing in the code as a warning or error. That way, you're less likely to receive an unexpected jab from hidden unboxing code. Eclipse's default is to ignore boxing and unboxing in the code as long as it's legal syntax. (I'm sure IDEA and NetBeans can do the same thing. If you're an IDEA or NetBeans user and want to post those IDE equivalents in a comment, please do.)

Celebrating the first American in orbit 45 years ago

Last week, NASA and the United States celebrated 45 years of Americans in orbit. On Feb. 20, 1962, an Atlas missile launched astronaut John H. Glenn Jr. into a cloudless sky on a trajectory that allowed his tiny Friendship 7 spacecraft to orbit the earth three times. The successful mission let the U.S. hold its head a little higher after the Soviets beat the United States into space yet again (i.e. Sputnik) when it launched Yuri Gagarin into orbit aboard Vostok 1 on April 12 the previous year. The flight also helped the world believe the United States might actually achieve what President Kennedy had proposed less than a year earlier: to land a man on the moon and return him safely to earth.

NASA photo of John Glenn leaving crew quarters prior to launch
NASA
John Glenn, in his pressure suit,
leaving crew quarters.
Prior to the Friendship 7 mission, the U.S. had launched two men only into short sub-orbital flights. The U.S.'s space program seemed years behind the Soviet's. During the weeks leading up to Glenn's space flight, the world witnessed the U.S. delaying the launch 10 times because of equipment problems and uncooperative weather.

NASA's web pages celebrating the 45th anniversary includes an interview with the astronaut-turned-senator, John Glenn, interviews with fellow Mercury astronauts Scott Carpenter and Walter Schirra, and a 360-degree tour of the Friendship 7 capsule, allowing you to zoom in on panel switches and indicators to know just what they say. The presentation allows you to see more capsule details than you would straining to peer inside the capsule in person at the National Air and Space Museum in Washington. (But by no means do you want to miss seeing the capsule in the museum's lobby when you visit D.C. You also can see Glenn's Mercury space suit, although make sure you read the label next to the suit to avoid leaving with the impression that John Glenn stood about 4-foot-10.)

Friendship 7 leaves the launch pad atop an Atlas-D rocket
Friendship 7 leaves the
launch pad atop an
Atlas rocket
NASA's Johnson Space Center also archives many press photos of the Friendship 7 mission. Well worth viewing if you're a space buff. A complete recording of the flight also is available from the Kennedy Space Center as a series of Real Audio files.

Listening to the audio of the entire flight is a good way to live through the event, rather than listening to edited versions of the flight. As an example, for a project I worked on 12 years ago commemorating the 25th anniversary of the Apollo 11 moon landing, I listened to some of the unedited NASA recordings. I remember thinking how slow everything occurred, from the descent of the lunar module to the hours that passed between touchdown ("Houston, Tranquility Base here, the Eagle has landed") and Neil Armstrong actually stepping out onto the surface ("That's one small step...") Whenever the moon landing is shown on television today, you'd think the landing took a couple of minutes and that the astronauts popped the hatch shortly after landing. Listening to the full recording of the 4 hour, 55 minute Friendship 7 flight gives a reminder to the many details that actually occur during a space flight.

If you'd like to hear highlights of the Friendship 7 flight, here are some edited audio files from my collection.
Launch (56 seconds)
Hitting zero G: "Zero-G and I feel fine" (55 secs.)
Firing retro rockets (21 secs.)
Main parachute deploy (40 secs.)

These recorded highlights are fun because you can hear Glenn describing the power of the retro rockets being fired while he was passing over California on his way toward his splashdown target in the Atlantic Ocean. Glenn radios, "Retros are firing. Are they ever. It feels like I'm going back toward Hawaii." You also can hear the excitement in Glenn's voice when he sees his main parachute deploy, which was probably the last major thing that could have gone wrong before splashdown. You hear Glenn's relief when he says "beautiful chute."

Photo of earth taken by astronaut John H. Glenn Jr. during his spaceflight
NASA
Photo of earth Glenn took during his space flight
Glenn had reason to be nervous during re-entry. Ground controllers had received telemetry indicating that the heat shield and landing airbag assembly (in case he needed to make a hard landing on the ground) might have prematurely detached from the capsule. If true, the only thing keeping the heat shield in place were straps attaching the retro-rocket assembly to the space craft. As a safety measure, flight controllers asked Glenn to keep the retro-rockets attached to the space capsule during re-entry. Normally, the rockets are jettisoned after firing. During re-entry, Glenn heard thumps and saw pieces of the retro rockets burning away from his craft.

You also hear in the recordings why NASA later suggested sending a poet into space in order to describe the experience (and thus gain more public support, and funding). It seems Glenn has one word for all the wonders he sees. Sunrises and sunsets? Beautiful. The site of the secondary engine falling away from his craft? Beautiful. Parachute? Beautiful. NASA was hoping the astronauts could provide more vivid descriptions to bring the experience to life.

If you start reading through some of the NASA links and want to learn more about Mercury, I recommend We Seven, a book from 1962 by the Mercury astronauts themselves, describing the program. I remember reading that book when I was about 11, getting me hooked on the excitement of science and exploration. The Wikipedia entry also is good.