Eric E. Allen

Rice University Computer Science Department

JavaPLT Group

eallen@alumni.cs.rice.edu

I am a former Ph.D. graduate student in the JavaPLT group in the CS Department at Rice University. I graduated from Rice in May 2003. I am now a researcher at Sun Labs in Burlington Massachusetts.

My undergraduate degree is in computer science and mathematics from Cornell University. While at Rice, I was the lead developer of the NextGen compiler. I was also a project manager of the DrJava development team. DrJava is an open-source, GPL'd, development environment for Java, with an integrated read-eval-print loop, available at SourceForge.


Books

Allen. Bug Patterns in Java. Apress, 2002.
Online Software.
Table of Contents and Sample Chapter.
Write-up in the Rice News.

Theses

M.S. Thesis: Efficient Implementation of Run-time Generic Types for Java. pdf
Ph.D. Dissertation: A First-Class Approach to Genericity. pdf

Papers

Allen, Cartwright, Stoler. DrJava: A lightweight pedagogic environment for Java. SIGCSE 2002, Northern Kentucky, March 2002. pdf ps

Allen, Cartwright, Stoler. Efficient Implementation of Run-time Generic Types for Java. IFIP WG2.1 Working Conference on Generic Programming, July 2002.pdf

Allen, Cartwright. The Case for Run-time Types in Generic Java. Principles and Practice of Programming in Java, June 2002. Awarded best paper of the conference. pdf

Allen, Bannet, Cartwright. A First-Class Approach to Genericity. OOPSLA 2003. Awarded best student paper of the conference. pdf

Allen, Cartwright, Reis. Production Programming in the Classroom. SIGCSE 2003. pdf


Technical Reports

Allen, Bannet, Cartwright. Mixins in Generic Java are Sound. December 2002. pdf

Allen, Cartwright. Safe Instantiation in Generic Java. pdf

Stoler and Allen. Improved Error Reporting for the Cryptyc Protocol Language. December 2001. pdf

Allen. Proving Type Soundness: Featherweight GJ. June 2001. ps

Selected PowerPoint Presentations

Ph.D. Defense: A First-Class Approach to Genericity

M.S. Defense: Efficient Implementation of Run-time Generic Types for Java

Debugging Security Protocols with Static Type Checking

The Case For Run-Time Types In Generic Java

Unit Testing with JUnit and DrJava

Modeling Mutation via Explicit Ref Cells

Static type checking: What is it and why do we care?

Continuation-Passing-Style and the Meaning of Function Application

Streams and I/O in Java (introductory)

Articles

These are links to articles about programming in Java that I've written for various webzines. Most of them are part of Diagnosing Java, my monthly column for the IBM developerWorks Java Zone.

Developerworks

Java generics without the pain
February 2003
Level: Intermediate
This article introduces generic types and the features to support them scheduled for inclusion in Tiger, Java version 1.5, scheduled for release late in 2003. Eric Allen offers code samples that illustrate the ups and downs around generic types by focusing on such Tiger features as limitations on primitive types, constrained generics, and polymorphic methods.

Design for easy code maintenance
January 2003
Level: Intermediate
This month, Eric Allen explains how avoiding and controlling gratuitous mutation is key to retaining code robustness while making the code easier to maintain. He focuses on such concepts as functional style code crafting and ways of marking fields, methods, and classes to handle and prevent mutability. Also, Eric explains the role of unit testing and refactoring in this task, and offers two tools to aid in refactoring efforts.

Killer combo -- Mixins, Jam, and unit testing
December 2002
Level: Intermediate
The safety of single-inheritance programming in the Java language comes at a price: sometimes code must be copied along multiple paths in the inheritance hierarchy. To regain much of the lost expressiveness in single-inheritance Java code, we can integrate mixins as one extension. This month, Eric Allen explains the notion of mixins (classes that are parameterized by their parent class) and how they can aid in unit testing. He also describes a tool for mixin-based programming and discusses potential approaches for adding mixins to your Java code.

Decoupling package dependencies
November 2002
Level: Introductory
In testing programs, how do you meet the tough challenge of simulating outside resources and library connections? Component-based programming and decoupling package dependencies may be the answer. Often touted as a means of facilitating code reuse, component-based software development also makes for more testable code. Eric Allen illustrates this concept of programming with examples from Jiazzi, a powerful, free tool for component-based programming using the Java language.

Unit tests and automated code analysis working together
October 2002
Level: Introductory
Unit testing and static analysis are often seen as unrelated ways to help ensure the correctness of a program. This article examines the relationship between these two methods and covers how the tools that form the working backbone of each method can be used to leverage one another to mutual advantage. Specifically, Eric Allen discusses some of the exciting new applications available that allow you to further leverage your unit tests.

Using temporal logic with bug patterns
August 2002
Level: Introductory
Temporal logic is a formalism used to describe how a program state will change over time. In this article, his second on temporal logic and assertions, Eric Allen discusses how several of the most common bug patterns can be prevented by the use of temporal logic assertions.

Assertions and temporal logic in Java programming
July 2002
Level: Introductory
Although traditional assertions can increase the amount of checking that can be done over Java code, there are many checks you just can't perform with them. One way to fill this gap is with temporal logic, a formalism used to describe how a program state will change over time. In this article, Eric Allen discusses assertions, introduces temporal logic, and describes a tool for processing temporal logic assertions in your programs.

The case for static types
June 2002
Level: Introductory
Many popular languages -- such as Ruby, Python, and other so-called scripting languages -- have moved away from static type checking as a means to help improve the reliability of code. Still, static type checking can be one of the key weapons in a powerful arsenal against introducing and for detecting bugs. In this article, Eric Allen makes a case for static type checking, explains why we should be glad that the Java language supports it, and discusses how it can be made even better.

Platform-dependence "gotchas"
May 2002
Level: Introductory
Write once, run anywhere. That's the promise, but sometimes the Java language doesn't deliver. Sure, the JVM provides an unprecedented degree of cross-platform interoperability, but minor glitches at both the specification and implementation levels often prevent programs from behaving correctly on multiple platforms. In this article, Eric Allen discusses some platform-dependent aspects of Java programming to watch out for, such as tail-recursive calls, as well as built-in vendor, version, and operating system dependence. Eric also demonstrates some ways around this type of dependence.

The Run-on Initializer bug pattern
April 2002
Level: Introductory
Often you see code that initializes a class not just by calling a constructor, but also through several follow-up actions intended to set various fields. Such follow-up actions, unfortunately, are hot spots for bugs, introducing a type of run-on initialization. In this installment of Diagnosing Java Code, Eric Allen explores the Run-on Initializer bug, discusses why and how it should be avoided, and demonstrates how to minimize the damage it may cause.

Repls provide interactive evaluation
March 2002
Level: Introductory
Normally, when running a Java program, it's necessary to run the program from a main() method, passing in parameters using the String[] input argument. But when a program is still being debugged, this can be a cumbersome task. This month, Eric Allen discusses the advantages of interactively evaluating the expressions and statements in your program, and offers some Java repls ("read-eval-print-loop" tools) that help you with this task. He also discusses how interactive evaluation can be useful for building GUIs and exploring new APIs. After reading this article, you'll understand why and how to interactively diagnose glitches in pre-debugged programs and you'll have access to some Java tools to facilitate your work.

Walking the specification tightrope
February 2002
Level: Introductory
Program specifications are a critical but time-consuming part of any software project. In this installment of Diagnosing Java Code, author Eric Allen discusses why a well-defined specification for your code is necessary and explores traditional software engineering approaches as well as extreme programming methods, comparing the advantages and disadvantages. Eric also discusses ways in which you don't want to define a program specification, and explains why. After reading this article, you'll understand how to weigh the costs and benefits of maintaining precise design specs.

Depth-first visitors and broken dispatches
January 2002
Level: Intermediate
Depth-first visitors, a variant on the Visitor pattern, may be used to increase the terseness of your code. In this article, Eric Allen describes the technique, discusses the advantages and the "gotchas," cautions the reader about the bug patterns associated with its use, and illustrates depth-first visitors in the context of a specific example.

Designing extensible applications, Part 4
December 2001
Level: Introductory
In this installment of Diagnosing Java Code, author Eric Allen illustrates how S-expressions -- syntactic representations of lists of elements delimited by parentheses -- can be used to provide a useful and lightweight form of black box extensibility. The advantages of using S-expressions are discussed in the context of a particular example. Also, the author details the limitations of S-expressions and notes when they may not be the best fit for an application. After reading this article, you'll know when to use S-expressions to create black box extensibility.

Designing extensible applications, Part 3
November 2001
Level: Introductory
Black box extensibility refers to the ways in which a software system may be extended when the source code is neither available for viewing nor for modifying. In this article, Eric Allen expands on the topic of black box extensibility, explains how extensions are made through system configuration or scripting languages, and offers some tips on how to implement black box extensibility.

Designing extensible applications, Part 2
October 2001
Level: Introductory
Glass box extensibility refers to the ways in which a software system may be extended when the source code is available for viewing, but not for modifying -- it lies as the happy medium between black box design (in which extensions are built without viewing the original code) and open box design (extensions are coded directly into the base code). Because the new extensions are based directly on the original code but don't alter it, the glass box design is probably the most effective, and safest, method of extending a software system. In this installment of Diagnosing Java Code, Eric Allen expands on the topic of glass box extensibility touched on last month. After reading this article, you'll know when to use the glass box and will have some tips on how to implement it.

Designing extensible applications, Part 1
September 2001
Level: Introductory
In this and several upcoming installments of Diagnosing Java Code, Eric Allen focuses his discussion on considerations involved in determining how extensible a new system should be, when extensibility is best applied, and how extensibility relates to other factors, particularly testability. In this first article, he examines the various ways in which a software system may be extensible and in what contexts each form of extensibility is most useful.

Designing testable applications
September 2001
Level: Introductory
In this installment of Diagnosing Java Code, Eric Allen takes a break from examining specific bug patterns and opts instead to discuss the issues involved in designing software that is easy, and even pleasurable, to test. He outlines seven design principles that can greatly increase your productivity in writing tests, and thereby improve the robustness of the resulting code base.

The Orphaned Thread bug pattern
August 2001
Level: Introductory
In multithreaded code, it is often common to use a single, master thread that drives the actions the other threads take. This master thread may send messages, often by placing them on a queue, that are then processed by the other threads. But if the master thread throws an exception, the remaining threads may continue to run, awaiting more input to the queue, causing the program to freeze. In this installment of Diagnosing Java Code, full-time Java developer and part-time exterminator Eric Allen discusses detecting, fixing, and avoiding this bug pattern.

The Fictitious Implementation bug pattern, Part 2
August 2001
Level: Introductory
In the last installment of Diagnosing Java Code, we saw that it is possible to implement a Java interface without actually meeting its intended semantics. This second article in a two-part series demonstrates two handy tools to fight such false implementation bugs. Eric Allen shows you how to use assertions and unit tests as executable documentation, making your code safer and more portable.

The Fictitious Implementation bug pattern, Part 1
July 2001
Level: Introductory
The Java language is free from many of the problems endemic to languages that support multiple inheritance -- in part because it restricts the specification of interface invariants to type signatures. But that restriction can combine with poor documentation to create problems: if you make incorrect assumptions about how an interface will be implemented, you may encounter frustrating bugs at run time. This article, first in a two-part series, outlines the development practices that can lead to such errors -- and ways to avoid them.

The Split Cleaner bug pattern
July 2001
Level: Introductory
One of the features of the Java programming language is that storage is automatically managed, saving the programmer from the bug-prone task of freeing memory after it has been used. Nevertheless, many programs still have to manipulate resources, such as files and database connections, that must be explicitly freed after use. Like manual storage management, there are many pitfalls that a programmer might encounter when managing resources in this way. One of these pitfalls is the topic of this week's column -- the Split Cleaner bug pattern.

The Impostor Type bug pattern
July 2001
Level: Introductory
When special tags in fields are used to distinguish between types of objects, errors are possible in which a tag mislabels the associated data -- a bug pattern known as the Impostor Type. In this installment of Diagnosing Java Code, Eric Allen examines the symptoms and causes of this bug, defines ways to prevent this error from occurring, and discusses a tempting hybrid implementation that does not use impostor types but, in the end, turns out to have many of the same weaknesses.

Recorders test for proper method invocation
June 2001
Level: Introductory
Unit testing with JUnit can be a powerful way to ensure the integrity of your code base, but some invariants that you might want to check with unit tests are trickier to test than others. In this installment of Diagnosing Java Code, Eric Allen discusses a way to write unit tests to ensure that a sequence of method invocations occurs in the proper order.

Improve the performance of your Java code
May 2001
Level: Introductory
Many algorithms are expressed most concisely as tail-recursive methods. Compilers can automatically transform such methods into loops and thereby improve program performance, but this transformation is not required by the Java language specification, so not all JVMs will perform it. This means that tail-recursive methods in the Java language can result in unexpectedly large memory usage. In this article, Eric Allen demonstrates that dynamic compilation maintains the language's semantics while static compilation often doesn't. He shows why this matters and offers a bit of code to help you determine whether your just-in-time (JIT) compiler can transform tail recursion on code while preserving semantics.

The Broken Dispatch bug pattern
May 2001
Level: Introductory
Method dispatch in an object-oriented language such as the Java language, in which methods can be overloaded and overridden, can cause difficulties of code management in even moderately complex programs. In this week's Diagnosing Java Code, Eric Allen discusses the bug pattern caused by these difficulties, outlining the symptoms when argument mismatches cause the wrong method to be invoked, and offering a few solutions to combat the problem.

The Saboteur Data bug pattern
May 2001
Level: Introductory
When a program crashes due to corrupted data, the saboteur can be elusive. Often a program can crash dead in its tracks while manipulating its own internal data, even after working flawlessly for long periods. This article discusses a bug pattern that can be the culprit of this sort of crash, why it exists, and several methods to eliminate it -- before and after it occurs.

The Liar View bug pattern
April 2001
Level: Introductory
GUIs are generally designed with a model-view-controller architecture in which the view is decoupled from the model. The separation presents a challenge to automated testing because it's difficult to verify that a state change in the model is reflected appropriately in the view -- it spawns the infamous Liar View. This installment of Diagnosing Java Code examines the Liar View bug pattern.

The Double Descent bug pattern
April 2001
Level: Introductory
Although usually easier to debug than other, more insidious erroneous behaviors, class-casting error messages are often symptoms of conceptual errors in recursively descending a composite data structure. In this installment of Diagnosing Java Code, Eric Allen discusses where programmers should look to find this pattern of bug, how to recognize the pattern, and what they can do to minimize its occurrence.

The Null Flag bug pattern
March 2001
Level: Introductory
Often, our efforts to develop robust programs by substituting null pointers for exceptional conditions actually limits control flow to the ordinary paths of method invocation and return, and buries evidence of where an exceptional condition occured. In this column, Eric Allen shows how this bug pattern, which he calls the Null Flag bug pattern, produces unexpected results that are difficult to debug. As with the other bug patterns that we have discussed, you can minimize occurrences of this pattern by applying certain programming techniques.

The Dangling Composite bug pattern
March 2001
Level: Introductory
One of the most commonly recurring (and most complained about) bugs in Java programming is the null-pointer exception. Tracking down the cause of one of these bugs can truly make you question your career decision. In this installment of Diagnosing Java Code, we'll continue with our examination of bug patterns by cataloging one of the most common patterns associated with null-pointer exceptions and step through an example of a class that contains it. We will then review several programming techniques that can help you minimize the pattern's occurrence.

Bug patterns: An introduction
February 2001
Level: Introductory
This premier article introduces the notion of bug patterns, an extremely useful concept that will increase your ability to detect and remedy bugs in your code. You will learn about one of the most common bug patterns, which will lay the groundwork for you to begin recognizing and avoiding more advanced patterns.

Javaworld

Behold the power of parametric polymorphism
Adding generic types to Java could mean less coding and fewer bugs

January 2000
What are the advantages of adding generic types to Java? Currently, when defining a class with a varying type field in Java, you must choose between losing precise static type checking and copying a class separately for each data type it might hold (such as int, boolean, float, and so on). Eric Allen explains that, by adding parametric polymorphism, or generic types, to Java, you can achieve more precise static type checking while still preserving inheritance polymorphism.


Extra-curricular Activities

Founder of the (no longer active) Rice Blackboard Debate Society, a small club of debaters here at Rice. We've developed our own style of debate, emphasizing the logical structure of arguments. Although this club is no longer active, you can find information on this new style of debate we invented here.

Send comments or questions to Eric E. Allen.