Once again, an attempt to get two stable, mature, well-documented open source Java tools to talk to each other has resulted in several hours of frustration, as well as all the bad karma associated with using Those Words (as my Grade 3 teacher called them) out loud. I finally figured out how to avoid the problem, but I still don’t understand why it happens in the first place. If any Ant and/or Hibernate gurus would care to enlighten me, I would be grateful.
Here’s what happened:
- Background
-
I wanted to create a near-trivial example application to introduce future generations of students to Hibernate (an object/relational mapping framework for Java). Hibernate gives developers two options: write a JavaBean class, then write a mapping file to describe how that class’s members map to database tables, or write the mapping file, and then have Hibernate generate the JavaBean class. Half of this fall’s students did it one way, half did it the other; based on their experiences, I decided to go the code generation route.
- Setup
-
I created four files:
hibernate.cfg.xml: the Hibernate configuration file.
build.xml: the Ant build file. (If you haven’t seen Ant, it’s a pure-Java replacement for Make, which has become the standard build tool for Java programming).
src/User.hbm.xml: the Hibernate mapping file for my User class.
src/Test.java: a simple test program. I initially used JUnit, but when things started to go pear-shaped [1], I yanked it out in an attempt to isolate the problem.
Note that my source files are in a src directory. build.xml creates two output directories at the start of the build process: one called gen, for generated code, and another called class, for compiled .class files.
build.xml has four targets:
clean: deletes the gen and class directories, and also the data directory (described below).
codegen: invokes Hibernate’s Hbm2JavaTask to generate gen/User.java from src/User.hbm.xml.
compile: compiles gen/User.java and src/Test.java to create class/User.class and class/Test.class.
schema: creates a data directory, and invokes Hibernate’s SchemaExportTask to generate database schema files in that directory. SchemaExportTask reads src/User.hbm.xml, checks that it’s consistent with class/User.class (compile-time checking—excellent), and creates data/hippo.log and data/hippo.properties, which between them tell HSQLDB (the database I’m using) what table(s) to create, and how.
- The first hour and a half
-
The examples in Hibernate in Action (the book I’m using) show several examples of hibernate.properties files, which use the older Java properties file syntax, but when it comes to XML configuration files, the book says, “Go see your install documentation.” I didn’t find that documentation helpful; in particular, it wasn’t clear when the XML configuration file’s properties had to have the same names as were used in the plain text configuration file, and when they had to be different. Hibernate’s error messages didn’t help at all: all I could do to debug was make more-or-less random changes to the configuration file, and see what effect they had.
- The next hour and a half
-
I finally annealed [2] my configuration file into a working state. A fresh cup of tea, and I was ready to start making some progress—except now Ant was unhappy. The four targets in build.xml are linearly dependent: schema depends on compile, while compile depends on codegen. ant schema should therefore erase the working directories, generate gen/User.java, compile it and src/Test.java, and generate a database schema.
When I tried it, the first three steps worked perfectly, but schema generation failed with an error message saying, “Unable to read User.class”. My first thought was that this was yet another classpath problem, but then I discovered that if I ran ant schema again, without running ant clean in between, Ant and Hibernate would generate my schema for me.
After ninety minutes and a lot of bad language, I convinced myself that this was some sort of timing problem. If I ran ant compile, then ran the schema-generation target on its own, everything worked. If I left the dependency between the schema and compile targets in build.xml, and tried to do everything in a single Ant run, it failed. I went so far as to revive a little Python inventory tool I wrote a while back, which walked through the directory tree, recording timestamps, file sizes, and MD5 checksums. As far as I could tell, there was no difference in the files generated by running Ant in two steps, versus running it in one.
And no, it isn’t Windows-specific: I get exactly the same behavior on Debian Linux…
At this point, I know how to work around the problem (run Ant twice), and could go back to working on my Hibernate example. But how am I going to explain this to students? “Hi, everyone, this term we’re going to be using Ant. It’s a replacement for Make, and sometimes, well, sometimes you just have to run it a couple of times to get it to work.” I don’t think it’s acceptable for software to act like a spoiled six-year-old (“I won’t! I won’t! I won’t I won’t I won’t and you can’t make me!”); I certainly don’t feel comfortable telling my students that when it does, they should just put up with it.
If you know something about Ant and Hibernate, and would like to figure out what’s going on, I’ve put the project’s four files on the web, and I’m easy to reach. I look forward to hearing from you.
[1] “Pear-shaped” is a British expression meaning “gone bad”. No idea how it originated; if anyone knows, I’d like to hear.
[2] “Annealing” is the process of banging on metal to get the kinks out. “Simulated annealing” is an optimization technique in which you make random changes to your proposed solution, keeping those that make things better, and throwing aways those that don’t. Simulated annealing is a lousy way to debug programs.
Uncategorized
I’ve written more than fifty book review columns for Doctor Dobb’s Journal since 1997, covering more than two hundred books. Here are ten I think every serious software developer should read:
- Andrew Hunt and David Thomas: The Pragmatic Programmer.
- Everyone I give this book to comes back and says, “I wish I’d had a course about this stuff at college.” The Pragmatic Programmer is about those things that make up the difference between typing in code that compiles, and writing software that reliably does what it’s supposed to. Topics range from gathering requirements through design, to the mechanics of coding, testing, and delivering a finished product. The second section, for example, covers “The Evils of Duplication”, “Orthogonality”, “Reversibility”, “Tracer Bullets”, “Prototypes and Post-It Notes”, and “Domain Languages”, and illuminates each with plenty of examples and short exercises. I don’t agree with everything they say, but it’s all thought-provoking. If you only read one book from this list, do your customers a favor, and make it this one. Note: their “Starter Kit” books on CVS, JUnit, and build automation are also worth far more than the $30 they’ll set you back. (Fair notice: I’m currently writing a book for them as well.)
- Mike Gunderloy: Coder to Developer.
- This book’s is subtitled, “Tools and Strategies for Delivering Your Software”, and that’s exactly what it’s about. As with The Pragmatic Programmer, project planning, source code control, unit testing, logging, and build management are all there. Importantly, so are newer topics, like building plugins for your IDE, code generation, and things you can do to protect your intellectual property. Everything is clearly explained, and illustrated with well-chosen examples. While the focus is definitely on .NET, Gunderloy covers a wide range of other technologies, both proprietary and open source. I’m already using two new tools based on references from this book, and plan to make the chapter on “Working with Small Teams” required reading for my students.
- Joel Spolsky: Joel on Software.
- If you’re a developer, Spolsky’s weblog is a
must-read: his observations on hiring programmers, measuring how well a dev team is doing its job, the API wars, and other topics are always entertaining and informative. In this book, he ranges from the specific to the general and back again, tossing out pithy observations on the commoditization of the operating system, why you need to hire more testers, and why NIH (the not-invented-here syndrome) isn’t necessarily a bad thing. Most of this material is still available on-line, but having it in one place, edited, with an index, is probably the best twenty-five dollars you’ll spend this year.
- Martin Fowler et al: Refactoring: Improving the Design of Existing Code.
- Like architects, most programmers spend most of their time renovating, rather than creating something completely new on a blank sheet of paper. This book presents and analyzes patterns that come up again and again when programs are being reorganized. Some of these are well-known, such as placing common code in a utility method. Others, such as replacing temporary objects with queries, or replacing constructors with factory methods, are subtler, but no less important. Each entry includes a section on motivation, the mechanics of actually carrying out the transformation, and an example in Java.
- Jeff Johnson: GUI Bloopers.
- Most books on GUI design are long on well-meaning aesthetic principles, but short on examples of what it means to put those principles into practice. In contrast, GUI Bloopers presents case study after case study: what’s wrong with this dialog? What should its creators have done instead. And, most importantly, why? The net effect is to teach all of the same principles that other books try to, but in a way you can immediately apply.
- Robert L. Glass: Facts and Fallacies of Software Engineering.
- Glass presents fifty-five facts (some a little fuzzier than anything I’d call a “fact”, but never mind), and ten fallacies under headings such as “Management”, “Reuse”, and “Testing”. What’s more, he also cites some of the evidence we have to back up these statements. Some of what he says is well-known: good programmers are up to N times better than bad ones (his value for N is 28), reusable components are three times harder to build than non-reusable ones, and so on. Other facts aren’t part of the zeitgeist, though they should be. For example, most of us know that maintenance consumes 40-80% of software costs, but did you know that roughly 60% of that is enhancements, rather than bug fixes? Or that if more than 20-25% of a component has to be modified, it is more efficient to re-write it from scratch? If nothing else, this book is a better way to start thinking about our profession than the “everybody knows” factoids you’re likely to soak up at coffee time.
- Joe Walnes, Ara Abrahamian, Mike Cannon-Brookes, and Pat Lightbody: Java Open Source Programming.
- For my generation, the Standard Model of programming was C, Emacs, Make, Unix command-line tools like cat and grep, CVS, and character streams. Now, twenty-five years later, a replacement has taken shape. Its main elements are:
- Java;
- Eclipse and its many plugins;
- Ant (for building), JUnit (for testing), and Subversion (for version control);
- reflection for making systems extensible; and
- XML as a universal storage format.
JOSP covers these topics, and many more; it also shows how they all fit together. Want to know how an experienced developer figures out how to manage object lifecycles and dependencies? That’s Chapter 14. Look and feel? See Chapter 17, and so on. Best of all, the authors put as much emphasis on testing as developers know in their hearts they ought to.
If JOSP isn’t to your liking, you may prefer one of these:
- Mark Grand: Patterns in Java (2nd ed).
- I flip-flop back and forth between this book, and Cooper’s Java Design Patterns. Both cover the core patterns from the Gang of Four’s classic Design Patterns, but with examples in Java, and at a level that mere mortals can understand. There’s also Metsker’s Design Patterns Java Workbook, and (more recently) Kerievsky’s Refactoring to Patterns, and several others, each with its own slant. In the final analysis, it doesn’t really matter which one you pick up, as long as you make Visitor, Facade, Singleton, Factory, and their friends all become part of how you think about solving complex programming problems.
- Jane Margolis and Allan Fisher: Unlocking the Clubhouse: Women in Computing.
- As a rule, women do not choose to go into computer science, and many of those who do later choose to pursue something else instead. This book looks at why this is, and at what we can do about it. Its first six chapters describe the many ways we are conditioned to believe that computers are “boy’s things”. Later on, the “who needs a social life?” atmosphere of undergraduate computer labs drives many women away (and many men, too). As the authors point out, almost three quarters of students of both genders believe that they do not fit the stereotype of a computer science students. The last two chapters describe what the authors have done to remedy the situation at Carnegie-Mellon. By being conscious of the many things that turn women off computing, and by viewing computer science from different angles, we can attract a broader cross-section of society, which can only make our discipline a better place to be. The results are impressive: female undegraduate enrolment at CMU rose by more than a factor of four during their work, while the proportion of women dropping out decreased significantly.
- Stewart Brand: How Buildings Learn
- This beautiful, thought-provoking book starts with the observation that most architects spend their time re-working or extending existing buildings, rather than creating new ones from scratch. Of course, if Brand had written “program” instead of “building”, and “programmer” where he’d written “architect”, everything he said would have been true of computing as well. A lot of software engineering books try to convey the same message about allowing for change, but few do it so successfully. By presenting examples ranging from the MIT Media Lab to a one-room extension to a house, Brand encourages us to see patterns in the way buildings change (or, to adopt Brand’s metaphor, the way buildings learn from their environment and from use). Concurrently, he uses those insights to argue that since buildings are always going to be modified, they should be designed to accommodate unanticipated change.
Finally, one honorable mention:
- Carlton Egremont III: Mr. Bunny’s Guide to ActiveX.
- What can you say about a book that includes lines like:
“The familiar dot ‘.’ symbol from Internet addresses is used in this
book to terminate sentences.”
along with a side view of a dialog, and (my favorite) the Visual Basic 5.0 splash screen on page 40, which looks suspiciously like a memory access violation message box. Yes, the book eventually runs out of steam, but it’s still very funny, and let’s face it, where else are you going to read something like:
“…you form windows using forms. A form is a window that you form. At first forms are unformed. You must form your forms using the form designer (formerly the former). In the form former, an unformed form forms a uniform formation of dots…”
Books
Recent Comments