rentzsch.com: tales from the red shed

Introduction to WebObjects 5
“If You’re Writing Code, You’re Doing Something Wrong”
Copyright © 2002 Red Shed Software. All rights reserved.
Written by Jonathan ‘Wolf’ Rentzsch (jon at redshed dot net).

They took the credit for your second symphony,
Rewritten by machine on new technology,
And now I understand the problems you can see...

I’ve met your children, what did you tell them?

Video killed the radio star

Abstract

WebObjects gives you the power to quickly develop robust applications that can be distributed over the Internet. This paper will introduce you to WebObjects, explain what it can do, how it’s put together and what tools it provides. Finally, you’ll see how WebObjects stacks up to “competitors” such as PHP, JSP, ASP and WebLogic.

What can I do with WebObjects?

WebObjects Serves Many Types of Requests

Here is just a sampling of the types of software you can build with WebObjects:

  • Database-backed Web Applications. The “Web” in “WebObjects”. WebObjects’ most popular use, for good reason. Web applications usually require no additional software to be installed on the user’s system, and Web Browsers are available on all platforms, allowing widespread use of your application.

    WebObjects has an entire database management layer (discussed below) which is amazing in its own right.

    While WebObjects provides a rich environment to assist you in creating HTML based applications, by no means is WebObjects limited to vending HTML. It can also serve:

    • Images. Both static and dynamic. Generally, you’ll only want WebObjects to serve up dynamic images since Web Servers do a better job.

      WebObjects comes with JavaPlot, a poorly documented framework for web image creation. However there are a number of well-documented, pure Java, open-source image generation libraries that integrate nicely with WebObjects.

    • PDF. Adobe’s Portable Document Format can be generated dynamically as well.

      This has been used to great effect for generating printable materials from your Web Application. For example, Toyota Canada’s website will generate a customized printable brochure based on the model, color and options of the car you choose.

    • SVG. Scalable Vector Graphics is essentially PDF in Extensible Markup Language (XML) format. While that’s a massive simplication, it’s hoped that SVG will become the standard vector graphics format on the web.

      An open source extension to WebObjects, SVGObjects, assists in dynamically generating SVG content from your application.

    • WAP. Wireless Access Protocol, a lightweight version of HTML geared for cell phones, palm computers and other small web access devices.

      A commercial extension to WebObjects, named WAPObjects, aids in creating WAP-based content.

    • SMIL. Synchronized Multimedia Integration Language: think presentations (animated slide shows) for the Web.

      WebObjects comes with well-documented SMIL extensions.

    • Java Applets. When you need a more dynamic interface than what HTML can provide, you can turn to running Java programs inside the user’s Web Browser.

      WebObjects features an ability to partition Java objects between local and remote versions, and manage their state and synchronization automatically.

  • Java Applications. Java Applications are much like Java Applets. They both come as Java Virtual Machine (JVM) bytecode classes often distributed in Java Archive (JAR) files.

    However, there are notable differences between Applications and Applets:

    • Applications are downloaded once. Applets are implicitly downloaded each time they are used. That stands in contrast to Applications, which are explicitly downloaded before use and are stored locally by the user.

      The upside of downloading Applets on demand is that the user isn’t bothered with managing another program and the developer can ensure that the user is always using the latest version of your software. The downside is that applets can be large and painful to download on slow network connections.

    • Applications can have more abilities. Depending on the user’s Web Browser security settings, Applets may not be able to read and/or write to the user’s file system, communicate with arbitrary servers or local programs.

      Applications, on the other hand, can do all these things and more, such as calling native APIs on the operating system and spawning external processes.

  • SOAP & XML-RPC Access. WebObjects provides XML-to-object encoding and decoding services, facilitating Simple Object Access Protocol (SOAP) and Extensible Markup Language-Remote Procedure Call (XML-RPC) interfaces.

    Apple provides sample code on its developer website on integrating web services with WebObjects.

An important fact here is that a single WebObjects application can serve all these types simultaneously with little to no consistency issues. For example, a SVG bar graph inside an HTML report could be updated with a Java Applet in another window.

What Makes WebObjects Different?

There are a lot of other software packages that fall under WebObjects’ category of application server. Here’s how WebObjects stands out:

  • Data-Driven & Introspective. This is from where this paper’s subtitle — “If you’re writing code, then you’re doing something wrong” — stems.

    The quote is facetious: it’s perfectly fine to write Java to achieve the functionality you need. Instead, it’s meant to encourage use of WebObjects’ built-in capabilities instead of writing custom code.

    WebObjects makes extensive use of the data and metadata provided by the developer. That information, coupled with the software’s ability to examine itself at runtime (introspection, a.k.a. reflection) eliminates a fantastic number of problems that would require code.

    Each line of code is an expensive responsibility. It has to be written, debugged, documented and maintained. Since WebObjects strives to minimize coding, it saves you much time and money.

  • Cost. WebObjects used to be priced on a sliding scale, based on the number of processors in the server and the desired number of transactions per second. The price could range between a little over $1,000 to $50,000. At these prices, WebObjects was cost competitive with other players in the application server market.

    In May 2000, Apple switched to a flat price of $699 per server, which includes one developer seat. In addition, a deployment license is bundled with Mac OS X Server and members of Apple’s Select and Premier developer programs can purchase it at a significant discount.

    At this price, WebObjects is effectively free. For example, the best competitor to WebObjects’ database layer (TopLink) alone costs thousands of dollars.

  • Design. This topic is too large to fit into a single bullet point, read on.

WebObjects’ Design

WebObjects represents the pinnacle of application server design. This stems from a combination of its age (it was the first object-oriented application server, and has been steadily evolving over the years) and its authors (what NeXT lacked in UI knowledge they made up in Object Design know-how).

You can contrast WebObjects to its competitors based on the three aspects fundamental to all application servers:

  • Interface. What the user sees. Commonly HTML, but Java is one other possibility. Also referred to as “presentation” or “view”.
  • Logic. The functionality of the application.
  • Data Access. How the application retrieves the information it needs for itself and the user.

By examining how different application servers separate the above aspects, you can tease out an evolution of design:

Design Evolution
  • Stone Age: Data Access and Interface embedded in Logic.
    Stone Age design

    Typified by a focus on the logic of dynamic page generation. The HTML is embedded within the code, as is the mechanism to access data, be it a flat-file scan or Structured Query Language (SQL) command.

    The “Stone Age” moniker isn’t meant to disparage the “logic first” design. Instead, it’s merely an indication of the design’s age (it was the first design) and simplicity. That said, embedding interface and data access into code leads to problems such as:

    • If your data source changes, you must update your code. SQL refers to specific table and column names, and the onus is on you to keep the embedded queries synchronized with your database.
    • One page equals one chunk of code. If you need to share logic among multiple pages, it’s up to you to work out a code sharing strategy and keep the code up to date.
    • Nonprogrammers can’t change a page’s look. Programmers are too valuable a resource to tie up every time a corporation’s web site appearance is updated.

    Examples of Stone Age-design tools include AppleScript, C/C++, Java, Perl, Python, and Visual Basic. You can tell that these tools focus on logic because they’re all programming languages. They’re great at representing logical decisions and operations, but suffer when forced to deal with data access and interface generation.

  • Bronze Age: Data Access embedded in Logic embedded in Interface.
    Bronze Age design

    After a brief period of time, programmers discovered most dynamic pages were comprised predominately of Interface, with only snippets of Logic throughout. Thus the Stone Age design’s structure was shuffled and begat a new age: the Bronze Age.

    While Bronze Age design still tightly couples everything, it changes the order of embedding. Instead of putting HTML into code, it puts code into HTML. This is usually accomplished with custom (non HTML-standard) tags.

    This allows many nonprogrammers to edit HTML pages — they just avoid the globs of Logic dropped here and there. Nowadays graphical HTML editors can do a great job of hiding such globs, making dynamic page editing possible for the non-technical.

    While Bronze Age addresses the need for a programmer to change a page’s look, it doesn’t address the Stone Age’s other two issues: Logic sharing and data source fragility.

    Examples of Bronze Age tools include Active Server Pages (ASP), Java Server Pages (JSP), Lasso, and PHP. These tools all embed programming logic inside HTML. ASP typically uses Visual Basic, JSP uses Java, Lasso has its own proprietary tag-based language, and PHP uses its own language as well.

  • Industrial Age: Data Access embedded in Logic separated from Interface.
    Industrial Age design

    Stone Age and Bronze Age design encourages code duplication. When a bug is discovered or a feature is added, one of two things can happen:

    1. The programmer reads through every file and applies the fixes.

      This is tedious and time-consuming work, and feels more like clerical drudgery than programming. Not surprisingly, many programmers won’t do it at all, or at least not consistently. (Especially when a deadline is looming.)

    2. The programmer updates the code in the one place where it’s broken or the feature was added.

      This leads to code divergence. After a few rounds of this, the software becomes an entangled patchwork of repetitive slightly-different code.

    Neither action is ideal, which leads us to the Industrial Age design solution: move Logic out of Interface. By keeping them separate, and joining them though a well-defined channel, Logic and Interface maintenance becomes much easier. Each side benefits from the independence: Logic becomes clearer, while both increase their reusability.

    It should be noted that with careful up-front design and consistent discipline, many Bronze Age tools can be bent to fit the Industrial Age design. However, like anything, Industrial tools will be easier to use with Industrial designs than non-Industrial tools.

    Examples of Industrial Age design include Cold Fusion, Lasso, WebLogic and WebSphere. Yes, Lasso gets a double mention here because it supports external JavaScript Logic in addition to its tag-based language.

  • Information Age: Data Access separated from Logic separated from Interface.
    Stone Age design

    You probably see where this is going. Bronze Age design solved Stone Age design’s need for a programmer to modify the Interface. By separating Interface from Logic, the Industrial Age solved the code duplication issue. Data source fragility is the only Stone Age issue left on the table.

    Computer Science has a tenet: that adding a layer of indirection can solve any problem. And sure enough, separating Data Access from Logic can solve the data source fragility issue.

    This leads to a natural and efficient separation of talent. An outside Web design firm can lay out a site without the company handing over their business logic code. The programmers can work on the company’s code without worrying about color coordination of the pages, or which brand of database the company is currently using. The database folks can move and rename databases, tables and columns without fear of breaking the Web application.

    There are only three examples of Information Age tools: Lasso, Tango and WebObjects. Yes, Lasso comes up again. To the author’s knowledge, it’s the only tool that natively spans three ages of design out-of-the-box. However, of the three tools, WebObjects has the most maturity and interoperability.

WebObjects’ Ingredients

WebObjects’ Three Elements

WebObjects can be broken down into three elements:

  • A set of frameworks. NeXT, and now Apple, were big believers in the advantages of frameworks.

    The concept of the framework has been described as “libraries turned upside down”, or the “Hollywood design” (as in “don’t call us — we’ll call you”). Instead of your code being “in charge” and calling upon libraries to do work for you, the framework itself is in charge. The idea is that you start with something generic working right away. Your job then becomes to override and extend the framework to achieve your specific desired functionality.

    These frameworks are written in pure Java, and can run anywhere there is a modern JVM. Supported operating systems include Mac OS X (naturally), Windows NT/2000/XP, Solaris and HP-UX (HP’s Unix). While the author and others have successfully used Linux and FreeBSD, these are not officially supported.

  • A set of development tools. WebObjects comes with multiple development tools. These tools range from the simplistic (Rule Editor is just a graphical frontend to a .plist file) to the ambitious (WebObjects Builder integrates a graphical HTML editor with your custom Java code and a data model). We’ll cover these tools below.

    These development tools are written in Objective C, and only run on Mac OS X and Windows NT/2000/XP. While it’s nice the development tools run on Windows at all, the Windows version of the tools are falling behind the Mac OS X versions. It’s clear Mac OS X is the preferred development environment.

  • A set of deployment tools. Once your application is built, you’ll want to make it public. Much of WebObjects’ fantastic scaling abilities relies on these tools.

    The deployment tools are written in pure Java, and can be used anywhere there’s a modern JVM.

The Frameworks

Layers of WebObjects’ Frameworks

At the heart of WebObjects lie its frameworks. There are four major frameworks, from the bottom-up:

  • JavaFoundation. This framework contains the fundamental data structure implementations and utilities used throughout the rest of WebObjects. Examples include arrays, dictionaries (objects that contain key-value pairs) and formatting classes.

    If you’re a Cocoa programmer, then the classes contained by this framework will be immediately familiar. NSArray, NSMutableDictionary and NSFormatter are but three of the classes you’ll also find in Cocoa. There is an interesting difference between JavaFoundation and Cocoa’s Foundation, however. The difference is belied by the name: JavaFoundation is written in Pure Java for portability. Cocoa’s Java support is merely a runtime wrapper around the Objective C implementation on Mac OS X.

  • Enterprise Objects Framework. The crown jewel of WebObjects. In the author’s opinion, Enterprise Objects Framework (EOF) alone is worth thousands of dollars.

    EOF handles storing and restoring objects to a data store. Usually the data store is a relational database, but this is not the only possibility. Previous versions of WebObjects shipped with a flat file adapter, while WebObjects 5 currently ships with a Lightweight Directory Access Protocol (LDAP) adapter.

  • WebObjects Framework. WOF bears the responsibility of providing your application’s user interface and state management.

    WOF provides an environment where you can use and create reusable components. Components are chunks of presentation (HTML) and functionality (Java code) often with a parameter list to enhance reusability.

  • DirectToWeb Framework. Give DirectToWeb a database, and it will generate — at runtime — a web application that can query the tables and modify data and relationships.

    Wow.

    Impressive feat, but chances are you (and perhaps your clients) won’t be happy with the default generic interface. This is the powerful part of DirectToWeb: you can customize the interface not just with Java but with rules. More on this impressive technology below.

Enterprise Objects Framework & EOModeler

Structure of EOF

“Where do your objects sleep at night?” That is, when your application exits, how is its data stored?

Enterprise Objects Framework (EOF) answers this question in an extremely elegant fashion. EOF is designed to easily store and restore your objects on demand. There are numerous technologies out there for accomplishing this task, here’s what makes EOF better:

  • The objects themselves don’t know how they’re stored.

    Whether pulled from a flat file, LDAP data source, or relational database: your object’s code stays the same. This leads to greater reusability and maintainability.

    While it’s nice to know EOF supports many types of data sources, the vast majority of WebObjects applications use relational databases as their data source. To make the following text less abstract, a SQL-based relational database is assumed as a data source.

  • Model file-based data source interaction.

    A pattern is repeated throughout WebObjects: prefer data to code. EOF follows this pattern by specifying the data source connection and interaction via a model file.

    EOModeler creates and edits the model file. The model file contains:

    • How to connect to the data source.

      Typically a Java Database Connectivity (JDBC) URL is used to specify a database.

      WebObjects uses JDBC drivers to talk to databases. Every major database offers a JDBC driver, allowing wide database use with WebObjects. A notable feature is that WebObjects can connect to multiple databases simultaneously (even from different vendors) and seamlessly create and maintain relationships between objects spanning databases.

    • The types of objects the data source stores.

      Everything you’d want to know about the data source’s objects, down to the individual table column’s SQL datatype.

      An interesting feature of EOModeler is how it can reverse engineer a database. No, this isn’t a tool for flagrant violations of the DMCA. Instead, given an existing database, EOModeler will walk its tables and columns and create a model for you, based on the information gleaned from the database and some advanced heuristics.

    • Mapping tables between the data source and in-memory objects.

      These tables describe how columns in your database map to instance variables in your Java objects.

    • Data source independent queries.

      EOF defines a simple query language. There are two basic reasons:

      1. Non-SQL Data Sources.

        Remember that while most WebObjects applications use SQL-based relational databases as their data source, EOF supports non-SQL data sources as well. Flat files don’t have query languages of their own, so EOF supplies one.

        “Memory” can also be considered a non-SQL data source. If you already have the necessary objects in memory, EOF allows you to query them without hitting the database again.

      2. Nonstandardized SQL.

        While SQL is standardized, alas most databases don’t follow the standard. Almost every database implements a Slightly Different Version of SQL. Having a consistent query language that is dynamically turned into vendor-specific SQL grants you database freedom and greater productivity.

  • Automatic Key Management.

    EOF handles primary and foreign key creation and management automatically, relieving the programmer of the tedious and error-prone task. This has much the same advantages that garbage collection memory management system has over a manual system (without the runtime performance overhead).

    EOF can work with your database to create primary keys, invoke your own custom stored procedures and/or Java code or just generate UUIDs by itself.

  • A “Sandbox” for Object Editing.

    EOF provides what’s called an editing context. As an object is edited, its changes are tracked by the editing context. When the time comes to save your changes, EOF bundles up your changes, compares it to a snapshot, and dynamically generates the differential SQL necessary to update the database. That’s right — EOF writes customized SQL for you.

    The object updates are bundled into one database transaction that either succeeds or fails, ensuring your database stays consistent. The editing context also supports undo. That is, you can revert an object to the way it existed prior to a series of modifications. This allows you to manually roll back a series of modifications if you encounter a failed update transaction.

  • Performance.

    EOF is a mature framework that features many optimizations. We’ve already seen how EOF will bundle multiple object modifications into a single updating transaction, but EOF has more tricks up its sleeve:

    • Faulting.

      Here EOF steals a page from the Virtual Memory playbook. It’s no surprise that when you pull an object from relational database, it will often have relations to other objects. Those objects, will, in turn, have relationships to even more objects. This can lead to a situation where you read an entire database into memory for one object!

      EOF deals with the issue using faults. A fault is a stand-in object that doesn’t actually hold data, but knows how to get it. When accessed, the fault “fires”, hitting the database and replacing itself with the retrieved data (be it a single object or list). The idea is directly analogous to how virtual memory systems will have unpopulated pages that are dynamically filled as programs read from them.

    • Uniquing.

      Once an object is fetched into memory, EOF jumps through hoops to ensure another copy doesn’t exist. To that end, as rows are retrieved from the database, EOF checks to make sure the object isn’t already in memory before creating an object based on the row.

    • Caching.

      Because EOF stores objects in memory, it saves expensive round-trips to the database.

A quick sidebar: This framework should rightly be named “Persistent Objects Framework”. The author’s pet theory is this was the initial name, but was abandoned when it was discovered the acronym could conceivably be pronounced “poof!”. Not something you want to bring up when discussing code that’s responsible for saving your business records...

WebObjects Framework & WebObjects Builder

WebObjects gives you three big wins:

  1. Automatic State Management.

    HTTP is a stateless protocol. While that’s elegant and easy to implement, it is a big challenge for writing web applications (which rely on state).

    WebObjects manages state for you, even if the user has cookies disabled. It performs this trick by generating a unique URL for each user. This URL contains a unique, randomly generated key that allows WebObjects to look up a Session object from each request. This Session object, which is completely extensible, is handed to the page during the processing.

    An example WebObject Unique URL

    If that URL is too ugly for you, then WebObjects offers alternatives. You can place the session’s ID into a cookie with a flip of a runtime setting. Another option is to take some responsibility for managing state yourself by using direct actions, which are, unfortunately, out of the scope of this paper.

  2. Automatic Web Form Management.

    You never have to decode another URL again! Using WebObjects Builder, you bind your Java class’s variables directly to HTML FORM input elements. When your page is invoked, the user’s input has been magically populated into your page’s instance variables.

  3. Component-based Development.

    WebObjects Builder is a miniature development system in itself. You build web pages by placing reusable components onto a page. Examples of component include WOString (a simple string), WORepetition (an element that iterates over a list, producing HTML as it goes along) and WOHyperlink (creates a hyperlink given a page name or URL). A component can be small as one character, or as large as a page.

    Each component comes with an API. WOString has a value that you bind an object to, while WORepetition requires a list and an item binding.

    WebObjects ships with many powerful components, but the true power lies in that you can create your own reusable components. For example, you can create an “Order Display” component that you can drop into your Shopping Cart Contents page, Order Confirmation Email and Past Order Information Page.

DirectToWeb Framework & Rule Editor, WebAssistant

There is a common set of tasks for records in a database. These include:

  • Creating a query
  • Listing matching results
  • Display a record
  • Create/Edit/Delete a record

When you put a web interface on a database, the burden is placed on you to code web pages that give the user the ability to perform these tasks. There’s a big problem, however. Each record requires another set of four pages:

  • A database with one table requires at least four pages.
  • A database with two tables requires at least eight pages.
  • A database with four tables requires at least sixteen pages.
  • A database with eight tables requires at least thirty-two pages.

The next figure illustrates this unpleasant relationship:

Relationship of Pages per Table
WebObjects Framework and DirectToWeb

There’s an obvious pattern here. Each record requires a set of pages. The tasks are constant — it’s only the records that change. DirectToWeb leverages this behavior pattern and its rich runtime knowledge of the database to build pages dynamically. It takes the model and — at runtime — generates pages on demand.

The idea is: you give DirectToWeb a model (generated using EOModeler) and it will, at runtime, generate all the pages necessary on demand.

It doesn’t matter if your database has one table or one hundred — DirectToWeb will generate a completely functional web application at runtime.

A key point here is that DirectToWeb is not a “wizard”. No code is generated. If your model changes, you need only restart the application to get new behavior.

Another key point is that DirectToWeb is fully customizable. You can define your own templates, and use the rule engine to insert your custom components and functionality where you like. DirectToWeb isn’t an all-or-nothing technology — it's merely a framework that extends WebObjects Framework.

You use Rule Editor to edit the application's rule files. Apple also provides the WebAssistant Java applet when your application is running, which is more specialized than Rule Editor. While Rule Editor is a generic rule editor, WebAssistant is focused on defining the customized functionality of the current page.

The Deployment Tools

Deployment Architecture

WebObjects comes with three main deployment tools:

  • woservices.

    This is a small daemon that starts wotaskd at system startup time and then continuously polls wotaskd, checking its responsiveness. If wotaskd becomes nonresponsive, woservices restarts it.

  • wotaskd.

    This daemon is responsible for keeping a list of running WebObjects processes. wotaskd starts and stops application processes, controls their environment, restarts crashed instances and provides a list of running processes for the web server adapter to pick from (for load balancing purposes).

  • JavaMonitor.

    This is an administration application that acts as a user interface to wotaskd. You add new applications and instances to JavaMonitor, and it rewrites the configuration files for you. It also provides at-a-glance information about which applications are running, along with their statistical information.

Further Reading

WebObjects documentation has markedly improved over the last two years, and is only getting better. Here’s some materials you may find handy, in reverse chronological order:

Building WebObjects 5 Applications
by Jesse Feiler
Copyright 2002
WebObjects Web Application Construction Kit
by George Ruzek
Copyright 2001
Professional WebObjects 5.0 with Java
by DeMan, Flowers, Frederico, et al.
Copyright 2001
Beginning WebObjects 5/Advanced WebObjects 5
by Emmanuel Proulx
MacTech Magazine: September, October, November 2001
WebObjects: WO Is Me
by Jonathan ‘Wolf’ Rentzsch
TidBITS Electronic Newsletter: June 18th, June 25th 2001
WebObjects Development Lifecycle
by David K. Every
MacTech Magazine: October 2000
The Not-So-Infinite Loop: Request Response in WebObjects
by Sam Krishna and Patrick Taylor
MacTech Magazine: August 2000
Introduction to EOF and WebObjects: The State of WebObjects
by Sam Krishna and Patrick Taylor
MacTech Magazine: July 2000
WebObjects and EOF for Everyone!
by Sam Krishna and Patrick Taylor
MacTech Magazine: May 2000
Introduction to WebObjects
by David K. Every
MacTech Magazine: January 2000

Credits

First, I’d like to thank Chris Hanson for introducing me to WebObjects. I am much obliged to the smart and kind folks (far too many to list here) on the WebObjects mailing lists, as well as OmniGroup for hosting the lists.

Thanks to Bob Frank, Larry Mills-Gahl, Steve Loranz and the other folks at CAWUG for providing monthly meetings (and free pizza!).

Wednesday, June 19, 2002
12:00 AM