Review: WebObjects web application construction kit
Update/Disclaimer: I feel it should be noted that I read this book and wrote this review before I was contacted by WROX to contribute to their WebObjects book. I considered not posting this here after I agreed to work on their book because of potential perceived conflicts of interest, but, people asked me for my opinion, and information wants to be free, so, here it is.
Here are the notes I wrote while I read the book WebObjects web application construction kit, by George Ruzek, from SAMS publishing. I started reading the book on June 3rd and finished around June 25th. I wasn't sure if I should share this with everyone because I found a number of errors and I didn't want to sound like I thought this was a bad book, because it definitely is NOT a bad book. It's a great book, but I'm noticing people in the webobjects-newbies group making some of the same mistakes made in this book, and I'd like to help people avoid those mistakes.
This book impressed me from the start when it made it quite clear what the prerequisite knowledge and experience was for getting the most out of the book. (page 3)
The companion web site is http://www.wowack.com/, which contains the code samples and sample databases, but it doesn't offer much more than that. It doesn't have errata (yet), which was surprising because there are a number of errors which I'll get to soon.
Page 54 suggests that any table structure changes require the table(s) to be dropped and recreated. However, EOModeler supports schema synchronization, so if your database's EOAdaptor supports schema synchronization, you won't have to do this. Alternatively you can just use your database's schema tools to make the changes to the tables, if your database supports modifying tables without dropping them (most do).
Page 84 uses a contrived example for demonstrating the data binding of WOImage, before showing how to use the much more common filename binding! This was the first real WO component / code example in the book and it was really confusing. A WO newbie I talked to who was reading the book thought that this was how WO handled images, because he didn't know what the filename binding was for, and thought WO had really bad image handling. He was asking me questions about WOResourceManager, asking me how to use it to find images, not knowing the filename binding does this for you.
One thing that was apparent in the book was he wanted to stick to pure-Java idioms and datatypes rather than introduce Foundation idioms and datatypes. On page 85, java.io and System.getProperties are used to find things about files which could have been done simply with NSPathUtilities in Foundation.
It's a fair thing to stick to Java concepts because it keeps the learning curve low, but I don't think it would have hurt to mention the Foundation alternatives, because synergy with WO requires synergy with Foundation.
Listing 4.11 on page 115 uses a rather odd pattern for sharing WOComponent instances in the session object. This might be worthwhile if the component was to be visited a lot of times and needed to store complex state. A better way to do this might be to make the FortunePage component stateless and have it access the list of fortunes in the application as was mentioned as a good use for the Application instance on page 111. I think George just wanted to keep the examples as simple as possible at this point because he was covering the request response entry points and didn't want to muddy the waters.
On page 116 he rewrites the action method to use the session's action method. A good segue into showing the reader how to get the session from a component, but he could have also mentioned that the binding for the WOHyperlink in the component could have been changed to session.fortunePage instead.
Foundation is finally covered in Chapter 5, the first chapter about EOF. I think it was a good idea to keep things as simple as possible by holding off on Foundation until this time, but some of the code examples previous to this chapter made WO look kinda weak because they didn't exploit much. Classic Catch 22!
I thought he could have described of the advantages of the Foundation frameworks over the java.util.* datatypes, but zealotry doesn't appear to be George's style at all. A better ambassador than a lot of the flame-throwing folk on the webobjects lists... ;-)
I found Figure 5.9 on page 135 really confusing. It's not an easy diagram to draw, but I had to look at it for quite a while before I understood what it meant. It was confusing enough for me to make note of it.
At this point in my notes I wrote:
"So far Chapter 5 has been wonderful, a very well thought out introduction (results oriented) to using EOF".
On Page 137, George says:
"This is easier than it sounds; the value associated with the WORepetition's item binding will contain the appropriate object when the action method is called."
I think this is understated, and can't be overstated enough! Web Developers are used to adding state (URL parameters) to action links which must decoded by the receiving page, and like magic, WO manages ALL OF THIS for developers automatically!
Page 139 goes into NSDictionary and NSMutableDictionary. I thought a diagram would have been very useful here -- I've found some people have trouble conceptualizing dictionaries/hashtables. There are many real world examples to draw from: dictionaries (surprise!), phone books, the periodic table...
Minor error: At the bottom of page 141, step #2 is incorrect. It should have referred to Table 5.5, not 5.3.
Page 168 says standard fetch specifications do not allow for distinct queries, but EOFetchSpecification has an instance method called setFetchesDistinct(boolean). Then on the next page he says there's a "Fetch Distinct Rows" check box in Figure 6.12. A weird contradiction.
This is the point where things start getting really scary. On page 179, he says "The bottom line is this: Don't mess with the accessor methods that EOModeler generates." This is baloney! get and set accessor methods are absolutely great entry poins for custom business logic. As long as you don't call valueForKey("foobar") in the foobar() get accessor method on an EOGenericRecord (which would cause infinite recursion and a stack overflow crash) you're totally fine.
Then on page 182: "It would be useful to have a constructor that creates a Rental given a Customer, Unit and date out."
But this is totally wrong! You should never set attributes or relationships of EO instances in the constructor, because the object is not yet being watched by an editing context! You'll run into all sorts of errors if you do this.
The correct way to have a convenience "constructor" for an EO, if desired, is to have a static method on the EO's class that also takes an editing context as a parameter and inserts the new instance before setting any attributes or relationships. However, since Java's static methods aren't true class methods, they can't be overridden by subclasses, so this is a limiting design pattern. I don't recommend it if you expect to use EO modelling inheritance. The same mistake (setting attributes before inserting in an editing context) is in Listing 7.6.
Page 188 mentions using FileMerge to merge in changes to EOs into previously generated .java source files. I thought, since he worked for BLaCKSMITH, he would have mentioned EOGenerator, a great tool that eliminates the problem, but he didn't. Check out EOGenerator if you have problems with FileMerge.
Listing 7.12 on page 197 saves the session's defaultEditingContext() to save the movie the MovieEditPage lets the user edit, but he really should have saved the movie's editingContext() because the movie did not HAVE to be in the session's defaultEditingContext(). It might have been in this example but that's beside the point. No need to keep things overly-simple this deep into the book, IMHO. The same action method was shown in Listing 7.15.
I really liked the code example on page 207, Listing 7.16. It showed how to properly delete objects which are displayed by a WODisplayGroup.
Chapter 8 is Using Inheritance with EOF. I was totally delighted that inheritance is brought up so early. In Apple's WO classes, it was the last topic and I thought it could have been covered earlier. Inheritance with EOF is so powerful and cool.
Page 216, Listing 8.1, shows a constructor for an EO class. This one doesn't have parameters, but it still makes the mistake of setting attribute values before the value is inserted in the editing context. The correct place to set default values for an EO is in the method awakeFromInsertion, which is called on your EO instance by EOF when the instance is inserted into an editing context.
Page 217 shows the really really hard way to make a Many-to-Many relationship between two entities. Seeing as how he was trying so hard to keep things simple I don't understand why he didn't just demonstrate the use of the very handy "Join in many to many" menu item in the Property menu of EOModeler.
The same "setting attributes in the constructor" error is made again in Listing 8.2 (page 218).
Page 219 shows a method that you can put on your component class to test whether an object is an instance of a particular class. This works great but it isn't very reusable. ERExtensions, available from http://www.netstruxr.com/developer/, contains a very handy reusable component called InstanceOfConditional that lets you do the same thing without having to write extra Java code.
Other than the errors in the Java listings, I think Chapter 8 was a very good synopsis of the options and the issues related to inheritance with EOF. The screenshots and steps shown were just frequent enough.
I felt Chapter 9 showed poor design in the examples and left me wanting more. Because of the numerous screenshots and overly verbose code listings, I surmise there was not enough room left for adequate detail and I was annoyed when I saw "This is left as an exercise for the reader" at the end of the chapter. Check out the validation article on Stepwise for another take on validation. Also, consider using DirectToWeb (and ERDirectToWeb) if you need to do a lot of validation because D2W really makes it easy to leverage EOF's validation schemes with WO.
Chapter 10: Advanced UI. Checkboxes and RadioButtons are Advanced UI??? This shows there wasn't enough coverage of the dynamic elements in previous chapters. This probably suffices for a book aimed at the beginner but it left negative connotations... describing checkboxes and radiobuttons are advanced suggests doing really truly advanced stuff would be EXTREMELY difficult. (It's not) In this respect this is not a substitue for the thorough attention given to dynamic elements in Apple's WO classes. The 3rd paragraph of page 255, about using checkboxes in a repetition, really needed a code example but it was left out, another exercise for the reader. Similarly, the WORadioButton example was really contrived.
Page 314 says you should click Yes when asked if you want to add a framework to the search order. You should instead choose No and then add $(NEXT_ROOT)/Local/Library/Frameworks to the Framework Search Order in the Build Attributes pane of the Project Inspector.
Chapter 13, Optimizing Database Access, page 355: "If left untouched, the performance of EOF-based applications can be fairly poor."
While the rest of the chapter addressed this issue, reading a blanket statement like that on the first page of the chapter was bothersome. The performance can be poor compared to what? How much time/money does it cost to use the alternative (JDBC/SQL or ADO/SQL)? I believe EOF improves performance in many more ways than it degrades it.
Overall, this is a great book. I think it moves at a very thoughtful pace, and does well to introduce traditional Java programmers to the WO way. I was disappointed by the numerous errors in the handling of EO classes. With the information above in hand to correct the errors I mentioned in my review, I recommend this book to anyone as an effective way to learn WebObjects on one's own. However, I still strongly recommend Apple's WO training classes to anyone wanting to learn WO quickly and effectively. Having all those other students around you asking questions and getting answers, doing the exercises and having an experienced trainer by your side for a long, in depth week is a great experience.
I hope this information is helpful to you and your peers. If I've made any mistakes in my review or you have comments, please leave me a message at jim@roepcke.com or on my web site at http://jim.roepcke.com/webobjects/articles/wowackreview
Jim Roepcke




