Skip navigation
ANNOUNCEMENT: community.oracle.com is currently Read only due to planned upgrade until 29-Sep-2020 9:30 AM Pacific Time. Any changes made during Read only mode will be lost and will need to be re-entered when the application is back read/write.

http://weblogs.java.net/blog/cayhorstmann/archive/baby-steps.pngThere are several blogs that tell you how to do fancy things with the upcoming JSF 2 (such as these by Ryan Lubke and Jim Driscoll). In this blog, I look at the other side of the coin—how the simplest things are working out. After all, if Ruby on Rails has taught us anything, it is that a technology that makes the simple things simple has a great shot at getting developer mindshare.

In Ruby on Rails, it is trivial to make a canned CRUD application, but I don't care about that. The kind of applications that I am interested in don't naturally evolve from a bunch of CRUD screens. Instead, I looked at the shopworn login example from Chapter 1 of Core JavaServer Faces. That example has a couple of screens, a managed bean, and a navigation case.

Good News #1. No more <managed-bean> in faces-config.xml

Nobody likes the busywork of maintaining an XML file in addition to the Java code. Just as you can use annotations in JPA to avoid XML drudgery, JSF 2 lets you annotate your managed beans, like this:

@ManagedBean(name = "user")
@SessionScoped
public class UserBean {
   ...
}

Good News #2. Facelets is a standard page description language

I never liked JSP, and I didn't like that JSF was built on top of it. JSP gives you the stack trace from hell. Now, you can author your pages in XHTML goodness, like this:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" 
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://java.sun.com/jsf/html">
  <h:head>
    <title>Welcome</title>
  </h:head>
  <h:body>
    <h:form>
      <h1>Please enter your name and password.</h1>
      ...
      <p>
        <h:commandButton value="Login" action="login"/>
      </p>
    </h:form>
  </h:body>
</html>

A validating XML editor will flag silly typos, and more importantly, when something goes wrong at runtime, you get a comprehensible error message with a file name and line number:

http://weblogs.java.net/blog/cayhorstmann/archive/error-report.png

As an aside, some people like facelets because presumably it gives you a way of sharing your JSF files with a visual designer. You could write that button as

<input type="submit" jsfc="h:commandButton" .../>

and the document would look ok in a web page or a visual designer. But that doesn't scale to higher level components such as a h:dataTable. Those components are the raison d'

schedule-screen.pngAfter many weeks of labor, my software engineering class is ready to deliver our BlackBerry project to Cinequest, the organizers of the San Jose Film Festival. Moviegoers will be able to check the schedule on their Blackberry devices, see when their favorite films are playing, and find out about the latest special events.

Running a real project in an undergraduate course turned out to be a huge challenge. Here are some of the key practices that made the project successful. Professional programmers will say “duh”, but maybe this blog will be of interest for other instructors.

What Worked

Eclipse

Blackberry has its own development environment. I had one look at it, decided that it was a useless toy, and insisted that we use Eclipse instead. When you are in rapid development mode, you need to be able to refactor on a dime. Without “Refactor→Rename” and “References→Project”, we would have been dead in the water.

Ant

Eclipse is great for writing code. But it is not great for reproducible builds. With a lot of effort, it may be possible to get everyone to have exactly the same settings, JDK version and library set, but that is way too hard. More likely, one ends up with a lot of finger-pointing and “But it builds on my machine.”

Ant worked like a charm, thanks to the BB Ant tools

Subversion

Our students weren't used to using version control. They use sneakernet or email attachments—a recipe for disaster when each of them plugs along in their own private world. Subversion works nicely in Eclipse...most of the time. I ran a crash course that covered both the command line client and the Eclipse client.

Trac

For issue tracking, we used Trac. It nicely bundles an issue tracker, a Subversion interface, and a Wiki. We were lucky that our outside customer was tech-savvy and used the issue tracker and Wiki for communication with the team. One day, I discussed some pesky detail with one of my students and pulled out a couple of relevant tickets. He said: “I just realize, we could not do this without Trac.”

JUnit

I am a bit embarrassed to admit that, but I had never used JUnit much. I always thought that the kind of errors that I make can't be caught by the toy tests that you see in the JUnit tutorials. But if you work together with a bunch of junior developers, JUnit is incredibly effective. The students made a bunch of errors that the JUnit test cases easily handled. Just as importantly, the test cases had teaching value—they showed how the APIs were supposed to be used. And it was often easier to write a test case instead of a Trac ticket.

Testing Outside the Device

http://weblogs.java.net/blog/cayhorstmann/archive/testing-outside.jpgProgramming for a device is a miserable thing. Something goes wrong, and you get a stack trace. Then you need to attach a debugger to the simulator or just stare at your code real hard. Either way, turnaround time is just too long.

I insisted at the outset that we test as much of the functionality as possible outside the device: query parsing, caching, and so on. The problem is, of course, that the BlackBerry has its own library for parsing, image conversion, local file access, etc. etc. that is different from Java SE.

Interfaces to the rescue. Every time that we needed something BlackBerry specific, we designed a shallow interface with two implementations, one for the device and one for Java SE. APlatform class delivered the appropriate instances to the code. The unit tests ran in Java SE, so that they could be executed automatically. It would be nicer if the device vendor could have provided some way of accessing their library outside the device, but apparently they live in the land of point and click.

Automate, Automate, Automate

http://weblogs.java.net/blog/cayhorstmann/archive/automation.jpegTo deploy an app on the BlackBerry, you need to sign it. With a GUI tool. And then upload the signed files to the server. And then, because of some idiocy in the file format, unzip them, except when you don't. No big deal, really. But I insisted that one of the students automates the process, and boy was I glad he did when the final crunch came. Note to RIM: It is not cool to have a GUI pop up in a tool that people want to run on a headless server. (We used xvfb to overcome that.)

XML

Our application consumes data from the movie database: schedules, film descriptions, and so on. At first, I thought that XML was overkill, but I was glad I stuck with it. We had tedious issues with character encodings, confusion with markup and content, and so on. By using XML, we didn't waste time with debating workarounds. Instead, we told the customer (who implemented the queries): Point Firefox to the query URL, and if it complains about XML errors, then keep coding

What Does It All Mean?

Do It Right From the Beginning

Once a project is in motion, it is incredibly hard to make changes to the process. In the later stages, panic sets in when everyone realizes that one can't possibly make the schedule, and nobody wants to step back and do the right thing if it even means one “lost” day.

Make sure that everyone starts using Eclipse and Antant Subversion and JUnit and testing outside the device, and keep yelling until everyone does it all the time. The first two weeks are the best time to shake out the usual issues with platform and library differences, but it can take considerably longer to get the last straggler on board.

That's a Lot of Tools

http://weblogs.java.net/blog/cayhorstmann/archive/a-lot-of-tools.jpgThe students were definitely struggling with the basics. Few of them had much tool experience, and they had to climb a steep learning curve in an extremely short amount of time. That's certainly memorable—I recently got a LinkedIn invitation from a former student who remembered her horrible first two weeks in my software engineering class. But it is not very efficient.

I really wish that students would learn more tools of the trade before they are seniors. Granted, things are better than when I first joined the department 20 years ago. At that time, I complained to one colleague that the students didn't know how to use a debugger, and he lectured me on how students should be taught to think harder about their programs, not how to use a debugger. Now, there is no longer any doubt that every student needs to learn that.

I keep begging my colleagues to use a version control system in their classes so that students can learn it gradually, but so far my pleadings have fallen on deaf ears. We teach a junior level course on object-oriented design. Why not have an Ant lab in that course? JUnit may be a bit hardcore for CS1, but it doesn't have to wait until the senior year.

If you hire college graduates and want them to get a better education, the best thing you can do is to join the industrial advisory board in the CS department of your local college. Tell the department chair about your needs. It works best if you can formulate it in terms of good pedagogy. Wouldn't it be great if students were encouraged to submit an early draft of an assignment and then an improved version? SVN can make this painless. Wouldn't it be great if students learned to read code, not just write it? Suggest that junior level courses should require students to extend a larger code base. Then the instructors will soon discover the benefits of build automation, and there will no longer be any doubt that every student needs to learn that.

This semester, my software engineering class is working on a project to bring the San Jose Cinequest film festival catalog to the Blackberry. RIM has generously donated us some devices.

Being a keyboard person and not very touchy-feely, I like the devices much better than the iPhone. Developing for them is another story. I am not the only one who has gripes about that.

  • The development environment is a quaint, homegrown Windows program.
  • RIM lives in the world of points and clicks. There is no provision for automatic builds and tests. I am thankful for the third-party bb-ant-tools and Dave Mitchell who figured out how to get the signing tool to work outside Windows. (The tool looks for signature files with the relative path..\bin\sigtool.csk, with backslashes in the path name—how lame is that?)
  • The API documentation is less than stellar. Check out the documentation of RichTextField. If you stare hard enough at it, you can probably figure out how to set up the offsets, attributes, and fonts. But what are those cookies? And how do you set colors?
  • Many methods have this ominous comment: “Framework: This element may be called by the underlying framework. Members that are invoked by the framework may not behave exactly as documented.” Huh?
  • Some things seem just impossibly hard. For example, I cannot figure out how to set patterns for “active regions” (those items that you can quickly select with the nifty trackball) in a single ActiveRichTextField. RIM only provides an example that sets them application-wide (using an unilluminating mess of factories and cookies).
  • Networking is bizarre. There are four (!) different networks to which you may want to connect, and it is up to you, dear developer, to code your way through the selection process.
  • There are two (!) separate developer forum sites (here andhere), which are both sad.

Ok, why am I surprised? It's not that the Windows API is a walk in the park, and you can't expect RIM to have the same developer resources as Microsoft. But I haven't programmed with Windows for many years. With everything that I have done recently, I hadaccess to source code, and there was apublic bug list.

Publicly available source need not mean open source. Long before Sun saw the wisdom of open-sourcing Java, most of the library source was included with the JDK (and it was easy to get the rest through a free “research license”). And the bug parade has been there since JDK 1.0. There have been many times where I scratched my head about some weird behavior, and I could either read the source or find a bug report. Or, if I wasn't able to do that, someone else was, and that someone would post intelligent answers on a forum.

With access to the source, third-party programmers can produce better tools. There have been some people (here and here) who put together a unit test library for Blackberry programming, but one could a lot better with source code for the device and simulator.

use-the-source.jpeg It is just crazy how unproductive it is not to have the source. Come on, RIM, and everyone else out there who still locks their source away from public view. If you had super-great APIs and dev tools, maybe there would be a competitive advantage to that secrecy. But otherwise, what's the point? You'll have happier, smarter, and more productive developers if you let them use the source.