After
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.
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.
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 http://bb-ant-tools.sourceforge.net/.
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.
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.”
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.
Programming
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. A Platform
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.
To 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.)
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
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 Ant ant 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.
The 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 educational 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.