JavaRanch Journal
Volume 4, Number 1 (August, 2005)

JavaRanch Newsletter Articles in this issue :
Scriptless JSP Pages: The Power of the MapBear Bibeault
Printable Version
The SCJP Tip Line - More About ConversionsCorey McGlone
Printable Version
Programming with Contracts in JavaErnest Friedman-Hill
Printable Version
Movin' them Doggies on the Cattle DriveCarol Murphy
Printable Version
Book Review of the Month - Ship It!Ernest Friedman-Hill
Printable Version
Upcoming Book Promotions Thomas Paul Printable Version

Scriptless JSP Pages: The Power of the Map
by Bear Bibeault

One sometimes unexpected side-effect of moving to JSP 2.0 "scriptless pages" is the amount of thought it forces one to focus on the "controller-to-view interface". To me, this side-effect is another major advantage (in addition to the welcome simplification of the pages themselves) to making this transition.

"How on Earth is forcing me to actually think of something an advantage?" you may ask. My answer to that is that more thought to this interface usually means a better interface. And better interfaces equal better program structure. And unless you haven't written a line of code in your life, you know that better program structure equals happier programmers.

Now it's not that there's never been any thought given to this interface before, it's just that in the pre-scriptless era it was common -- because it was just so easy -- for us to code the controller servlet to throw any old data structure onto the request knowing that we could write all the Java we wanted on the page to deal with those structures.

Some of us, and I'll give myself credit to be among those, always had the notion that the less Java on the pages, the better, and gave some amount of thought to gearing the structures passed as request-scoped variables to the needs of the page. But still, because any arbitrary Java code could be included on-page, it wasn't a paramount consideration.

That has all changed. With scriptless JSP pages, where JSP 2.0 Expression Language (EL) expressions are the primary means to reference the scoped variables, adjusting the nature of the scoped variables to suit the pages becomes something to which more thought must be applied.

Over the course of converting a number of my client's web applications to use JSP 2.0 and scriptless pages, I've learned a lot about structuring the controller-to-view data, and one thing that has become apparent to me is the overlooked power of the Map as applied to this problem space.

By "Map", of course I mean implementations of the java.util.Map interface.

Recall that in the Expression Language, the fetch operators (the dot and the square brackets) tailor their semantics to the type of their left operand. In the EL expression:

  ${xyz.abc}

or the equivalent

  ${xyz['abc']}

how the EL evaluator determines the value of abc depends upon the type of the value for xyz.

If xyz evaluates to a discrete element, the evaluator attempts to treat abc as a JavaBean property, and to determine its value using the accessor method getAbc().

If however, xyz evaluates to a java.util.Map implementation, the evaluator attempts to resolve the value of abc as the value of the entry with key 'abc'. (Interesting things also happen if xyz is an implementation of java.util.List or an array, but that, as they say, is another show).

This is powerful stuff and opens up the usage of the Map in this context in ways for which we might not previously have thought of using a Map construct.

A Case Study: Member Permissions

One of the web applications that I have updated to use scriptless pages is a community-based recipe sharing site. The app is membership-driven, with each member assigned to a "role" that grants them certain permissions for the various actions that can be performed within the application.

Lowest is the guest role where unregistered visitors can browse the site contents. Registered visitors with the member role can submit recipes to be added to the site contents. Paid members with the gold member role can create private recipe collections and have access to some other advanced features. Moderators can approve submitted recipes, remove member accounts, and perform other policing actions. The most privileged role of administrator can perform all site actions.

Each role is actually a set of discrete permissions that determine what actions visitors possessing that role can initiate. The "add recipe" permission, for example, is granted to all roles but "guest".

Each visitor to the site is identified via an instance of a Member object in that visitor's session. In the JSP 1.x version of the application, a method on this object exposed the permissions that the member was granted based upon the role assigned to that member.

If we imagine a location on the site where an "Add Recipe" button will appear for those visitors that have the "add recipe" permission (which would be all but "guests"), you might have seen JSP code like this:

  <%
    Member member = (Member)session.getAttribute( "member" );
    if (member.hasPermission( "ADD_RECIPE" )) {
  %>
      <button type="button" onclick="onAddRecipe()">Add Recipe</button>
  <%
    }
  %>

Note: this is a simplification of the actual code. There were ownership considerations that frequently needed to be taken into account, and the strings for the permission names were exported as String constants rather than being hard-coded into the pages. But I'm trying to keep the example code focused on the point to be made.

Converting this to a scriptless equivalent using JSTL tags and the EL might seem straight-forward at first, but when we try to access the "hasPermission" method of the member object, we run into problems.

The EL can easily access properties of objects such as Member, but is unsuitable for calling general-purpose methods, such as hasPermission(), that take parameters.

The means to determine whether a member possesses a particular permission needed to be changed to a mechanism that was "EL-friendly".

One tactic could have been to replace the general purpose method with discrete property accessors. Under this approach each and every permission would need to become a property of Member:

  public boolean getHasPermissionAddRecipe();
  public boolean getHasPermissionApproveRecipes();
  public boolean getHasPermissionBanMember();
  ...

and so on.

I rejected this approach due to a number of problems. Not only did it not scale well -- as the number of permissions grows, so do the number of accessors necessary -- it artificially makes each individual permission a property of Member. While I had no problem modeling the set of permissions as a property of a Member, making the individual permissions Member properties violated my "OO sensibilities" as it introduced a coupling between the Member object and the available set of permissions. My original model had the Member interface independent from the set of available permissions, and I certainly did not want to gain simplification of the JSP pages at the expense of compromising the model abstraction.

The next thought that occurred to me was to consider using EL functions. Since the problem seemed to be that EL property expressions didn't allow for general function calls, perhaps defining some EL functions would do the trick.

EL functions are means to access static methods defined on a Java class. By creating a static function, perhaps on the Member class itself, I could pass the permission name as a string. But because the method must be static, I'd also need to pass the member object as well.

In a TLD file, such a function could be defined as:

  <function>
    <name>hasPermission</name>
    <function-class>com.whatever.membership.Member</function-class>
    <function-signature>
      boolean hasPermission( com.whatever.membership.Member, java.lang.String permission )
    </function-signature>
  </function>

and on-page, its usage would be (assuming that the TLD containing the function was declared and mapped to the prefix 'membership'):

  <c:if test="${membership:hasPermission( sessionScope.member, 'ADD_RECIPE' )}">...

Although I liked this solution much better than adding individual properties for the various permissions, I thought that it was a bit wordy on the page, didn't read well at all, and the static nature of the method seemed like a bit of a OO wart on the Member class.

What I really needed was a different means to map the name of a permission to its granted/denied setting.

Light dawned when I finally realized that the solution was in the problem statement itself all along: I needed a means to map the name of a permission to its granted/denied setting.

Thinking back to our previous example of ${xyz.abc}, we saw that not only could abc be a JavaBean property, but it could also be a map key. And one great advantage that a map key has over a JavaBean property, is that it is run-time assignable as opposed to the compile-time hard-coding of accessor methods.

My solution was to create a new property for the Member class that represented the set of permissions granted to that member. I named this property hasPermission and its value is a Map that associates a granted permission name to the value Boolean.TRUE.

Hence, its accessor is:

  public Map getHasPermission();

and it can be used on-page thusly:

  <c:if test="${sessionScope.member.hasPermission.ADD_RECIPE}">
    <button type="button" onclick="onAddRecipe()">Add Recipe</button>
  </c:if>

which makes for a beautifully readable EL test expression for the <c:if> tag.

All it takes is to add the permission names to be tested as a key to the Map -- in our example "ADD_RECIPE" -- with a value that evaluates to true (such as Boolean.TRUE).

Since the expression will evaluate (and without error) to false in the event that the Map lacks a specific key, we need only add granted permissions to the Map. Any denied permissions need not be explicitly added with a value of Boolean.FALSE as the expression will evaluate to false whenever the named entry cannot be found in the Map.

While this does indeed make access from the JSP page very readable, the signature of the accessor is rather odd-looking when used from Java code (permission checking is also performed quite often within the server-side code). But this need not be an issue since nothing prevents us from leaving the original hasPermission( String permissionName ) method on Member for use within Java code, and leave the new hasPermission property accessor for use solely from EL references.

Note on this example:

Even though the Add Recipe button is hidden on pages displayed to visitors that do not have permission to perform the "add recipe" action, this in no way constitutes adequate security against unauthorized attempts to execute this action. The server-side code for performing this operation (in the business layer of the application) performs its own stringent series of checks to make sure that the requested action is allowed by the visitor's granted permissions.

The point of hiding it on the UI is merely so that visitors without adequate permissions are not presented with a UI element that will result in a "permission denied" error upon its usage.

Another Case Study: Constants

A recent post in the JSP Forum of the JavaRanch Big Moose Saloon brought up another interesting case study.

In the post, the author -- another firm believer in the "goodness and light" of scriptless JSP pages -- lamented the fact that without scriptlets or scriptlet expressions, it was impossible to reference static constants defined in Java classes. Indeed, using the facilities of the Expression Language, this is not possible.

Such references proved quite useful in pre-scriptless applications. Take for example, a common bug introduced by a simple typo naming a form element on a JSP page. Let's say that in servlet SomeServlet to which a form on a page is to be submitted expects a request parameter named "description":

  String description = request.getParameter( "description" );

But on the page, the form element is coded as:

  <input type="text" name="decsription"/>

This error causes the request parameter value in the servlet to always be null since no form element with the expected name actually exists. This type of bug is easy enough to fix, but can waste a great deal of time trying to find.

By using a string constant defined on the servlet (or in some other abstraction as we will discuss later):

  public static final String KEY_DESCRIPTION = "description";

this type of bug can be avoided by using the constant in the servlet itself:

  String description = request.getParameter( KEY_DESCRIPTION );

and within the JSP as:

  <input type="text" name="<%= SomeServlet.KEY_DESCRIPTION %>"/>

assuming that SomeServlet has been imported into the JSP.

While this may be somewhat notationally heavy, it has the distinct advantage of generating a compile-time error should any typo in the key reference be made.

Within a JSP 2.0 scriptless page, such scriptlet expressions are not possible. And while even the power of the Map cannot achieve the invaluable utility of a compile-time check, it can be used to make such errors at least a little easier to spot.

Let's take the well-known example of a simple login form which consists of two entry fields: a username and a password. Knowing that simple string constants exported from a servlet, or any other class for that matter, will have no utility for our scriptless JSP pages, we'd like to use a Map to create references that can be readily and readably used on the JSP pages.

Since we're going to be exporting more information about the form and its elements than a simple set of string constants, it makes sense to formalize an abstraction of our "form" and its elements, decoupling it from any one specific servlet (or page).

In this abstraction we'd like to export information that is usable from any servlet that deals with our "login form", as well as from the JSP page that will implement the UI elements that present the login form to the user.

Here's how it might be done:

  public class LoginForm {
    public static final String KEY_USERNAME = "username";
    public static final String KEY_PASSWORD = "password";
    public static final Map FORM_KEYS = new HashMap();
    static {
      FORM_KEYS.put( "KEY_PASSWORD", KEY_PASSWORD );
      FORM_KEYS.put( "KEY_USERNAME", KEY_USERNAME );
    }
  }

In this class the form keys are exported as string constants that are easily used by any Java code (particularly servlets) that need to reference them.

A Map of the form element keys whose keys are named using the conventional naming format for constants is also exported. When placed onto request scope by code such as:

  request.setAttribute( "FormKeys", LoginForm.FORM_KEYS );

the form elements in the scriptless pages can now be coded as:

  <input type="text" name="${FormKeys.KEY_USERNAME}"/>
  <input type="password" name="${FormKeys.KEY_PASSWORD}"/>

Because of the names and naming conventions we used to create the Map and the scoped variable, the purpose of the references is immediately recognizable as mimicking constant values.

Note: it could be argued that even though the spirit of these references is to be used as constant values, that, since they are not, they should not be named like constant references. I'll leave such philosophical discussions for another time.

Operationally, if the FormKeys scoped variable does not exist or if the key name is mis-typed, no error is thrown, but blank output is rendered.

While this is nowhere near as useful as having a compile-time (or even run-time) error thrown that reaches out and slaps you in the face, a typo in the JSP page now results in a pattern that should be easier to spot by inspection, as well for which automated searches can be created. If, for example, the following error is made:

  <input type="text" name="${FormKeys.KEY_USRENAME}"/>

the resulting rendered HTML would be:

  <input type="text" name=""/>

which would be easier to spot in the rendered page than a hard-coded typo like:

  <input type="text" name="usrename"/>

and for which it is easy to create an automated search that finds instances of the name attribute with an empty value.

Whether it is worth all this setup for what some might think is marginal gain is up to the individual to decide. I include it here as another example of how a Map can be used in conjunction with JSP scriptless pages in ways that might not be obvious.

However, I will assert that the utility of creating a "form abstraction" as described here is more far-reaching than this example. Imagine that such a class was extended to be able to fetch its known parameters given a request instance, could convert the parameter values from strings to integers, dates or other non-string types as appropriate, and perhaps even perform simple, context-free validations on its elements. This would be a powerful abstraction that not only collects the form elements into a cohesive entity, but decouples the concepts of the "form" from the servlets (or other items) that reference it.

The utility of such an abstraction might not seem evident when thinking of our simple login form that possesses two simple string fields. But imagine a more complex form; say, the myriad fields of various types that go into selling an item on eBay®. Collecting all this information into an abstracted instance could significantly simplify the code that needs to deal with it.

Summary

In this article, we've looked at a number of ways to use the Map interface in conjunctions with JSP scriptless pages. Because Map keys can be referenced in an Expression Language expression as if they were properties, the Map provides a clever way to create "property names" that are not, or cannot, be known at compile time in a way that is not possible with formal JavaBean properties.

Discuss this article in The Big Moose Saloon!


Return to Top
The SCJP Tip Line
More About Conversions
by Corey McGlone

This month we're going to do a quick extension of my last article. In that article, we looked at the various types of conversion and casts that can be done in Java. This week, I'm going to look at a specific trick with casting that may very well appear on the exam - it most certainly appears on most mock exams.

Assignment Conversion vs. Method Invocation Conversion

Let's start off by taking a look at this code snippet:
Source Code
            
public class Conversions
{
    private static byte myMethod(byte b)  // 1
    {
        return 32;  // 2
    }
 
    public static void main(String[] args)
    {
        byte b = myMethod(50);  // 3
        System.out.println(b);  // 4
    }
}
            

So what's the output of that code? I sure hope you said that it produces a compiler error, because it certainly does. Let's take a look at all of the conversions that are taking place in that code - believe me, there are a lot.

Let's start at Line 3, which is the first line that will be executed. What data type is 50? Any integral literal is always considered an int by the compiler. Therefore, line 3 is passing an int to a method that takes a byte as a parameter. This is where our compiler error comes from. Passing a parameter to a method invokes a Method Invocation Conversion. A method invocation conversion can only perform an identity conversion (such as casting a byte to a byte, which is trivial) or a widening conversion. Obviously, casting an int to a byte is a narrowing conversion, so the method invocation conversion can't handle it. Hence, the compiler error. If we were passing a byte to a method that took an int, no problem - that's a widening conversion. But an int to a byte? That's a no-no. Let's modify line 3 to read like this:

byte b = myMethod((byte)50);

What does that do for us? Well, by first casting the int to a byte (through our explicit cast), we are passing a byte to a method that requires a byte. That's just an identity conversion so the method invocation conversion works just fine.

So now let's jump to Line 2. There's a conversion happening here, as well. What type is 32? Obviously, 32 is an int, just as we saw that 50 was an int. What conversion is happening here? Well, look at the return type of that method - we're supposed to return a byte. But we're returning an int! That should cause a compiler error, right? Wrong. Rather than using a method invocation conversion to perform the conversion, the compiler is going to use an Assignment Conversion (essentially assigning the value being returned to the return variable). There's a trick to an assignment conversion, though - the following comes straight from the JLS:

"Assignment conversion occurs when the value of an expression is assigned (?15.26) to a variable: the type of the expression must be converted to the type of the variable. Assignment contexts allow the use of an identity conversion (?5.1.1), a widening primitive conversion (?5.1.2), or a widening reference conversion (?5.1.4). In addition, a narrowing primitive conversion may be used if all of the following conditions are satisfied:
  • The expression is a constant expression of type byte, short, char or int.
  • The type of the variable is byte, short, or char.
  • The value of the expression (which is known at compile time, because it is a constant expression) is representable in the type of the variable.
If the type of the expression cannot be converted to the type of the variable by a conversion permitted in an assignment context, then a compile-time error occurs."


Essentially, that says that you can automatically assign a value to a variable, even if that assignment would require a narrowing conversion, as long as the value is known at compile time (a literal value, as we have here, or a final variable) and that value "fits" into the target type. In our case, we're trying to assign 32 to a byte. Well, 32 is a literal, so we know the type at compile time and it certainly falls within the range of a byte, which is from -128 to 127. Therefore, the Assignment Conversion handles this conversion automatically by doing an automatic narrowing cast.

Conclusion

Short update this week, but an important one. The differences between method invocation conversions and assignment conversions are small, but important. Certainly, such details about conversions can be considered "nit-picking" but a lot of the SCJP exam falls into that realm. The idea behind the SCJP exam is to have a good handle on the details of the language and I've seen questions about this material on many mock exams and the real SCJP exam.

Until next time,
Corey
Discuss this article in The Big Moose Saloon!


Return to Top
Programming with Contracts in Java
by Ernest Friedman-Hill

Recently I read Christopher Diggins' article "Programming with Contracts in C++" in the March 2005 Dr. Dobb's Journal, and it got me thinking about Programming with Contracts (PwC), a concept first explicitly articulated by Bertrand Meyer in the Eiffel programming language. In PwC, you not only code the logic for a method, but assertions about the method's preconditions (what must be true for the method to be called) and postconditions (what must be true after the method is called.)

What's the difference between PwC and the perhaps more common term Design by Contract? In practice, not much. In theory, DbC is a pure design activity, but of course, contracts are useless unless they are executed. Once they are executed, you're programming, and hence doing PwC. Six of one, a half-dozen of the other.

In PwC, the assertions can execute every time a method is executed, although typically they're turned on only during testing. This executable contract provides fine-grained assurances about an application that unit testing alone can't. Postconditions can test the effect of calling a method, which is quite like what you get from unit testing, but preconditions test how a method is called by an application, and thus they give you the benefits of very fine-grained and thorough application testing.

In Eiffel, pre- and postconditions are added directly to the code. It's a powerful technique. The downside is that code with a lot of conditions is very cluttered. It's very similar to adding assertions to C or Java source: a few assertions provide useful information about the code, but thorough contract descriptions make it hard to see the implementation for the trees.

There are PwC tools for Java; perhaps the first was the now-defunct iContract. With iContract, you defined your pre- and postconditions using special Javadoc tags, directly in a class source.

A current Java PwC framework, jContractor, lets you define your contracts in separate classes, and doesn't use a special expression language, but instead uses a number of special naming conventions to connect pre- and postconditions to the methods they apply to. Furthermore, jContractor uses bytecode instrumentation, which affects your build process. I was hoping for something simpler.

Diggins' approach to PwC in C++ interested me because it's interface based. For Diggins, a contract is a class that can act as a wrapper for the class it describes. Each method in the contract class simply implements one method in the interface of interest by asserting preconditions, forwarding the call to the implementation object, then asserting postconditions. The nice feature of this is that the contract can be arbitrarily complex without complicating the described class's implementation. Furthermore, this lets you write a single contract for an interface, and apply it to all implementations of that interface. Best of all, it requires no special tools, special syntax, or special rules -- and you can start using it right now.

A Tutorial Example

Let's say you have an Account interface that represents a financial account:

            
public interface Account {
    String getCustomerName();
    void debit(double amount);
    // More ...
}

Furthermore, let's say you imagine that while there will be many implementations of this interface, they're all going to have to follow certain rules. For example, getCustomerName() should always return a non-null, non-zero-length String, and debit() should be called with a positive argument less than or equal to the current balance.

You can write a contact for Account that looks, in part, like this:

            
public class AccountContract implements Account {
    private Account m_impl;

    public AccountContract(Account impl) {
        m_impl = impl;
    }

    public String getCustomerName() {
        String result = m_impl.getCustomerName();
        assert result != null : "Customer name is null";
        assert result.length() > 0 : "Customer name is empty";
        return result;
    }

    public void debit(double amount) {
        double balance = getBalance();
        assert amount > 0 : "Debit amount nonpositive";
        assert amount <= balance : "Debit amount would overdraw";
        m_impl.debit(amount);
        assert getBalance() == balance - amount : "Computed balance incorrect";
    }

    // More ...
}

I've used standard Java assertions to implement the pre- and postcondition checks. An alternative would be to use unchecked exceptions. The advantage of using assertions is that they can be turned off easily via a runtime configuration switch. Another alternative would be to use checked exceptions -- i.e., to require that the interface methods declare an exception that they can throw when conditions are not met, and then throw them from the contract class. Although this latter solution is rather heavyweight, it could be appropriate in certain situations, such as in testing EJBs or JDBC drivers or any other category of classes in which all methods are already defined to throw a specific exception type.

The centerpiece of each method of the contract is a call to the corresponding method of the m_impl object. Note how I'm always careful to call the implementation method once and only once; you must make sure that the meaning of the code won't change if assertions are turned off.

Now you can test any implementation of Account by "wrapping" an instance inside an AccountContract, and using the AccountContract as if it were an instance of the class under test. Because all our assertions are in AccountContract, the AccountImpl class is very simple:

            
public class AccountImpl implements Account  {
    private String m_name;
    private String m_acctNumber;
    private double m_balance;

    public AccountImpl(String name, String acctNumber) {
        m_name = name;
        m_acctNumber = acctNumber;
    }

    public String getCustomerName() {
        return m_name;
    }

    public void debit(double amount) {
        m_balance -= amount;
    }

    // More ...
}

Practicalities

You can use a factory to hide this process of creating the contract object:

            
public class AccountFactory {
    public static Account get(String name, String acctNumber) {
        Account acct = new AccountImpl(name, acctNumber);
        if (Account.class.desiredAssertionStatus())
            return new AccountContract(acct);
        else
            return acct;
    }
}

The java.lang.Class.desiredAssertionStatus() method (introduced in JDK 1.4 as part of the assertions facility) basically just returns true if assertions are enabled. It's a convenient way to select the appropriate behavior for our factory.

In this case, the implementation class has no default constructor. In practice, you may want to insist that all your implementation class do have one and have a standard initialization method the factory can call. This would make it easier to configure the factory at runtime, or to construct different implementation classes using an Abstract Factory pattern.

Observations

This form of PwC is useful whenever an interface is going to be implemented multiple times, especially if those implementations are going to be done by multiple people or teams, or if they will evolve over time. It's slightly less useful if an interface will be implemented only once, as then the implementor most likely understands the contract well already. Still, PwC could be used even then to check that the class was being used correctly by implementing preconditions.

PwC obviously has a significant impact. For the very simple class being tested here, it's obvious that there is more code in the pre- and postcondition checks than there is in the AccountImpl class itself. PwC, like the assertions I've used here, is generally used only during development and testing, and turned off during production. Java's assertion facility makes it easy to turn assertions on or off at runtime for an entire application or even for individual packages or classes, making assertions an especially convenient way to implement PwC.

Contracts check both problems with the behavior of a class and problems with how a class is used. For this reason, they provide some of the benefits of both unit and application tests. Using contracts doesn't excuse you from writing unit tests, but it does provide excellent integrity checks during application testing that otherwise wouldn't be done.

All the code for this article is available here.


Discuss this article in The Big Moose Saloon!


Return to Top
Movin' them dogies on the Cattle Drive
by Carol Murphy

Whut in tarnation?
The Cattle Drive is where you come to learn Java, and just like the cattle drivers of the old west, you're expected to pull your weight along the way.

The Cattle Drive forum is where the drivers get together to complain, uh rather, discuss their assignments and encourage each other. Thanks to the enthusiastic initiative of Johannes de Jong, you can keep track of your progress on the drive with the Assignment Log. If you're tough enough to get through the nitpicking, you'll start collecting moose heads at the Cattle Drive Hall of Fame.

Straight shootin'...
Well it's sure been a long dry spell since I've done any reporting on the doings of those intrepid souls on the Cattle Drive. 2005 has been a butt-kicker for a lot of folks it seems, but there are still a few who find the time to put in a few hours of roping and coding.

Fresh riders on the Drive...
There are only 4 active drivers as we go to press, and 3 of them are brand-spanking new. Please give a hearty welcome to Tom Henner, Tommy Leak, and Barb Rudnick. These cow punchers have been making fast progress on the first part of the drive, but the badlands of Say have proven to be the same old stumbling block it has always been. Anyone who has been there might want to stop by and give a little encouragement and moral support during this difficult time.

Another moose on the wall for...
Speaking of someone who has been there, Kate Head bagged her fourth and currently final moose head on March 29, when she completed JDBC 4. Congratulations, Kate!

Get along, little dogies...
David McCartney is still driving away out in Oop somewheres, and Adam Vinueza and Jean-Marc Bottin have been popping their heads up now and again. Hope they didn't fall down a prairie dog hole or something!

Juliane Gross has reappeared from where ever she has been holed up. Sure am glad to see folks back on the trail!

Behind the scenes...
Marilyn deQueiroz and Pauline McNamara, our 2 hard-working nit-pickers, have been unflagging in their work, which deserves special thanks since the assignments on the drive have been updated and reworked. I haven't had a chance to check out the changes yet, but apparently the assignments are so different that even those of us who have completed the drive would find it worth checking out.

Me, I'm wondering how the heck it has got to be August already. Seems like summer just began! Well, here's hoping to see more of you out on the trail, or just finding the time to hang out more at the ranch.

Mosey on over to The Cattle Drive Forum in The Big Moose Saloon!



Return to Top
Book Review of the Month
Ship It!

by Ernest Friedman-Hill

Author/s  : Jared Richardson, William A. Gwaltney
Publisher : Pragmatic Bookshelf
Category : Project Management, Process, and Best Practices
Review by : Ernest J. Friedman-Hill
Rating : 10 horseshoes

Ship It! is both a guide to running successful software projects, and a life preserver for projects that are failing. If you've ever worked on a troubled software project, you know what it feels like. The frustration. The sense of impending doom. The urge to polish your resume. We've all been there. So have Richardson and Gwaltney -- and they're offering to leverage their considerable experience to help save you and your project from this fate.

There's not much material that's truly new between these covers, but the presentation and point of view is refreshing. It's a rare book that speaks convincingly to both developers and managers, but this one does a good job. The book describes many of the practices of agile development -- continuous integration, automated testing, lightweight planning -- and combines them into a simple but powerful description of an approach to building software they call "Tracer Bullet Development." But the book doesn't assume you're going to do everything the authors suggest: they expect you to try just one thing as a time.

My favorite part of the book is compendium of one-page essays on common problems software projects have, and how to apply the principles and practices from the book to solve them. Unlike some other rather strained "antipatterns" catalogs that I've read, this section feels very practical and usable.

If your shop has trouble shipping quality software on time -- and let's face it, most do -- then this book is for you. If you're a manager, I'd say that doubly so.


More info at Amazon.com
More info at Amazon.co.uk

Discuss this book review in The Big Moose Saloon!


Return to Top
Upcoming Book Promotions
by Thomas Paul

We're got a whole mess of book giveaways coming up in the next few months. Find out how to win a free book! Here are the promotions scheduled for the rest of August.

Starting
Date
Book Author(s) Publisher JavaRanch Forum
August 16 SCJP 5.0 Exam Simulator Seema Manivannan Whizlabs Software Programmer Certification (SCJP)
SCWCD Exam Simulator Siva Sundaram Whizlabs Software Web Component Certification (SCWCD)
August 23 Hibernate Quickly Patrick Peak, Nick Heudecker Manning Object Relational Mapping
SCBCD Exam Simulator Seema Manivannan and Valentine Crettaz Whizlabs Software EJB Certification (SCBCD)
SCMAD Exam Simulator Sathya Srinivasan and Siva Sundaram Whizlabs Software Mobile Application Certification (SCMAD)
August 30 SCDJWS Exam Simulator Valentine Crettaz Whizlabs Software Web Services Certification (SCDJWS)
SCJP 5.0 Training Seema Manivannan Whizlabs Software Programmer Certification (SCJP)



Return to Top
Managing Editor: Ernest Friedman-Hill