From Java Platform Improvements to Better Teaching: A Conversation With Java Champion Cay Horstmann

   
By Janice J. Heiss, February 2008    

Interviews Index

This is the second in a series of interviews with Java Champions, individuals who have received special recognition from Java technology developers across industry, academia, Java User Groups (JUGs), and the larger community.

  Bio: Cay Horstmann grew up in northern Germany and attended the Christian-Albrechts-Universität in Kiel, a harbor town by the Baltic Sea. With an M.S. in computer science from Syracuse University and a Ph.D. in mathematics from the University of Michigan, he is now a professor of computer science at San Jose State University in California. He was named a Java Champion in 2005.
 

Horstmann is the coauthor of Core Java and Core JavaServer Faces , and he is working on Enterprise Java for Elvis . He was influential in getting the College Board to include Java programming in the advanced placement (AP) computer science exam for high school students. He was formerly a VP and CTO of a dot-com startup and, previous to that, owner of a successful company that sold a DOS program for editing scientific documents. In his spare time, Horstmann now consults in Internet programming.

java[dot]sun[dot]com (JSC): Heinz Kabutz, a fellow Java Champion, when asked about the biggest mistakes of Java developers, pointed to the failure to unit test. He said, "At conferences, I ask, 'How many of you have unit tests for your code?' Almost no one raises their hands -- and these are experienced professionals." Your reaction?

 
"I perform an occasional unit test after I've encountered a failure that I don't want to have recur, but I rarely write the tests first. If so many experienced developers don't write unit tests, what does that say?"
 
 
Cay Horstmann
Professor of Computer Science, San Jose State University

Horstmann: Ugh. I would not have raised my hand either. I perform an occasional unit test after I've encountered a failure that I don't want to have recur, but I rarely write the tests first. If so many experienced developers don't write unit tests, what does that say? Maybe they would be even better developers if they followed Heinz's advice. Maybe they don't make many mistakes that unit tests would catch because they're already experienced. The truth is probably somewhere in between.

JSC: When I asked Sun's Brian Goetz the key to writing fast Java code, he said that developers should write "dumb code," by which he meant straightforward, clean code that follows the most obvious object-oriented principles in order to get the best compiler optimization. Compilers are big pattern-matching engines written by humans who have schedules and time budgets, so they focus their efforts on the most common code patterns in order to get the most leverage. Goetz argues that clever, hacked-up, bit-banging code will get poorer results. Your thoughts?

Horstmann: I agree with Brian. I learned over the years that it never pays to optimize code until after you profile. We all fret over caching values rather than recomputing them, eliminating layers, and so on. More often than not, it makes little difference in performance but introduces a huge headache in debugging.

I saw that you asked Heinz Kabutz the same question. He says, "I usually encourage software development companies to train all of their programmers in design patterns, from the most junior to the wise architect." I'm a bit uncomfortable with this. I agree that patterns should be a part of everyone's education, but I've had too many junior programmers sprinkle patterns over their code in the hope of improving it. Patterns are not magic potions, and it takes quite a bit more experience than is commonly acknowledged to use them wisely.

Take the Java I/O library, which is imbued with the value of the decorator pattern. For example, BufferedReader is a decorator, and to get buffered reading from a file, you do this:

Reader reader = new BufferedReader(new FileReader("foo.txt"));
 

What if you also want lookahead? Now you need to insert a PushbackReader into the decorator chain.

What a pain! I would have preferred more usability and less pattern dogma. In C++, buffering and lookahead are part of every file stream, which is so much more convenient in practice.

Mistakes to Watch Out for With JavaServer Faces Technology

JSC: What are some crucial mistakes that developers make in JavaServer Faces development, often called JSF?

Horstmann: I don't want to blame developers for weaknesses in the framework and deployment platform.

The single biggest issue that hampers productivity is "the stack trace from hell." If you make an innocent typo, your IDE probably won't catch it -- either because the IDEs are not all that savvy about JSF or because JSF was not designed with compile-time checking in mind, for example, with value expressions. Consequently, when you deploy your app, you get a huge stack trace that tells you the life story of the app server. You then must divine which part of the stack trace is relevant and what it tells you about the source of failure. A junior developer can't be expected to do this. All they know is that something failed. So productivity instantly goes down the drain.

Who's to blame? First, the JSF library implementers, for doing a poor job of tracing back the cause of the error to the cause in the programmer's code. Whenever there's a failure, the mantra must be "File name, line number, file name, line number." This is not easy. JSF is built upon JavaServer Pages (JSP) technology. The JSP parser must be rigged to capture the file name and line number of every artifact and to associate it with the data structures that it hands to the JSF implementation.

Second, the app server implementers are to blame for hiding behind the fiction that they produce software for deployment, not development. When something goes wrong, the app server just belches and whines -- it has no pathway to propagate an error with file name and line number to the development environment.

The folks at Netbeans do the best they can, scraping the stack traces for clues. However, they can only report what the app server tells them. The app servers need to have a development mode that tells the IDE the precise file name and line number that caused a failure.

Look at it this way -- suppose the compiler had the same attitude as the app server. If the programmer is slovenly enough to feed it a program with errors, it just returns a stack trace and exits. Nobody could be productive with such a system. Yet this is the fundamental flaw with JSF.

JSC: So where do programmers go wrong with JSF?

Horstmann: I see two problems.

First, they don't separate presentation and code. JSF makes it hard but not impossible to smuggle code into JSF pages. Yet every time I've seen JSP scriptlets or JSTL (JavaServer Pages Standard Tag Library) put into a JSF page, the result was a mess. I suggest sticking with pure JSF -- no code at all in the pages. If you want to repeat something, use a data table. If you want to hide something conditionally, use the rendered attribute. If you need anything more sophisticated, write a custom component.

Second, in a JSF- JPA (Java Persistence API) application, programmers fret over the distribution of code in managed beans and session beans. Avoid the hassle. Simply use Seam, soon to be WebBeans.

Mistakes With Threads
 
"It's hard to blame developers for what is in hindsight a broken programming model. Threads and shared memory are too hard to get right if all you have is locks."
 
 
Cay Horstmann
Professor of Computer Science, San Jose State University

JSC: What are the most serious mistakes that Java developers make with threads?

Horstmann: Again, it's hard to blame developers for what is in hindsight a broken programming model. Threads and shared memory are too hard to get right if all you have is locks. Brian Goetz told me that we need something for thread programming that's the equivalent of garbage collection for memory management. Probably few people remember the abject pain of manual memory management in C and C++. So the biggest mistake is to use the primitive features. Don't share data. Use safe data structures to communicate information between threads. Brian wrote a whole book about it.

I usually start out sharing no data and use bounded queues for communication -- it makes me look at my threading problems in a new and usually safer way. Or look at inherently safe models of computation such as the actors in Scala.

Advice for Beginners

JSC: What advice do you have for beginners?

Horstmann: First, don't panic. When students first see the API with thousands of classes, they despair. I used to be able to tell them, "That's OK, at least the language itself is very simple." But that was before this:

static <T extends Object & Comparable<? super T>> T
Collections.max(Collection<? extends T> coll)
 

As a student, you need to stay within a safe subset of the Java language and the API so that you can use it as a tool to learn some good computer science.

Next, code. Professional programmers often forget how hard it is for most beginners to actually program. It's so unlike most activities. The computer is unforgiving. When you're wrong, you're told very quickly that you were sloppy or stupid -- not a good thing for a fragile ego. And when you are wrong, you need to stop and think. Random tinkering rarely gets you anywhere.

This is a really hard sell to today's students. Your ego isn't stroked very much, and you'll get a headache trying to fix your mistakes. A career in divorce law sounds so much more attractive. But when you succeed, it sure feels good. The trick is to get students to that point.

Last summer at a faculty summit at Google, bigwig professors from big-name universities expounded on their efforts to reform the computer science curriculum and make it less focused on programming. The organizers from Google said, "That's all fine and good, as long as the students can code when they graduate."

Mistakes in Teaching

JSC: What are the biggest mistakes that your fellow teachers of Java programming make?

Horstmann: They lecture too much. I think it's horribly ineffective to lecture for 50 or even 75 minutes without giving the students a chance to try out what they're learning. These days, all my students have laptops and we have a 15- to 20-minute lecture, a lab, another minilecture and lab, and a five-minute wrap-up.

Let me share a pet peeve: Some teachers have a hard time thinking outside of the box. Here is an example. I was on the College Board committee that revised the advanced placement computer science curriculum to use the Java language instead of C++. We created a small subset of Java material that is testable on the exam. After all, the focus of the exam is computer science, not Java syntax. We didn't put the char type into the subset. If an exam question needs to get a single character, it just uses a string of length 1.

This did not go over well with some instructors. They had this worldview that char was somehow hugely important, the atomic building block of strings. Curiously, they did not feel that the bit was equally important as the building block of integers.

In hindsight, of course, the committee made the right decision. As of J2SE 5.0, a char value is merely an artifact of the UTF-16 encoding of Unicode -- some Unicode characters require two char values.

It would be so much better to teach less of the Java language and more computer science in the first course, but inflexible instructors make it difficult to take trivia and minutiae out of the curriculum.

Ask Alice

JSC: How has BlueJ helped you teach your students?

Horstmann: I really like BlueJ and the new Greenfoot tool that Michael Kölling and his team have produced, but I'll tell you about another tool that is a bit more far out: the Alice programming environment.

In Alice, you learn programming by manipulating 3D objects: toasters, wizards, dinosaurs, ballet dancers, whatever. Alice is a real programming language, with syntax, statements, variables, objects, methods, classes, and a complete development environment. But instead of computing the minimum number in an array, the students make the evil stepsister eat the closest cookie. It's much more fun.

Most importantly, in Alice, you can never make a syntax error. You write a program by dragging tiles, and anything that you can drag is a valid program. At first, I thought, So what? But after a few weeks of Alice, my students moved on to a Java environment. I had forgotten how awful first contact with Java programming can be. Students were driven to distraction by one silly syntax error after another. This is when they drop out from frustration. But since they knew Alice, they persevered a bit longer, a huge help.

Hopes for Java SE 7

JSC: What do you want to see in Java SE 7? Do you want closures?

Horstmann: Yes, I want to see closures. I am in basic agreement with the BGGA proposal. There are some fine points about nonlocal return, which are right now in flux, where I would quibble with Neal Gafter, but I'd much rather have closures with minor warts than not have them, or only have wimpy syntax improvements around inner classes.

Whenever I see a post by someone who says, "Oh my, the syntax is so crazy, how am I ever going to understand {int, int, Random => BigInteger}", I say, OK, what are you going to say, that your feeble brain can't grasp the concept of a function with three parameters -- of type int, int, and Random -- and a return type BigInteger?

When I teach closures in a programming languages class, the syntax doesn't trip students up. They are surprised that local variables keep living when they are captured by the closure. And they get over it pretty quickly.

Closures will give library writers the ability to write code that is easier for application programmers. That's been the theme of the big language extensions in J2SE 5.0. Look at annotations. It takes true wizardry to write an annotation processor. But my students have no problem using them. Here's an example:

@Entity public class Student
{
   @OneToMany private List<Quiz> quizzes;
   ...
}
 

For that matter, you hear a lot of bellyaching about generics. I agree that generics could have been done better, and that it's unfortunate that it takes an expert to understand all their subtleties. But in most cases, generics are simple and useful. Look at the code that I just wrote. It is so much better to say List<Quiz> than just List.

First-year students can use ArrayList<Robot> to collect instances of Robot objects. Can everyone deal with ArrayList<T extends Comparable<? super T>>? No, but so what? It isn't something that comes up a lot in practice.

Generics would have been easier without primitive versus reference types or without type erasure. That would have been preferable, and I still hope that some of the warts can be fixed in future versions.

As for what I want to see in Java SE 7 or 8 -- I don't think all of these extensions are going to make it into Java SE 7 -- my favorite microchange is alternative exception types, something like this:

catch (IllegalAccessException | IllegalArgumentException |
InvocationTargetException ex)
{
   ex.printStackTrace();
}
 

The other major change that I want to see is Java properties. I am so sick of reading:

@Entity
public class LineItem implements java.io.Serializable
{
   private int id;
   private double subtotal;
   private int quantity;
   private String product;
   private Order order;

   @Id @GeneratedValue(strategy=GenerationType.AUTO)
   public int getId()
   {
      return id;
   }

   public void setId(int id)
   {
      this.id = id;
   }

   public double getSubtotal()
   {
      return subtotal;
   }

   public void setSubtotal(double subtotal)
   {
      this.subtotal = subtotal;
   }

   public int getQuantity()
   {
      return quantity;
   }

   public void setQuantity(int quantity)
   {
      this.quantity = quantity;
   }

   public String getProduct()
   {
      return product;
   }

   public void setProduct(String product)
   {
      this.product = product;
   }

   @ManyToOne
   @JoinColumn(name = "order_id")
   public Order getOrder()
   {
      return order;
   }

   public void setOrder(Order order)
   {
      this.order = order;
   }
}
 

when I really want to read something like this:

@Entity
public class LineItem implements java.io.Serializable
{
   @Id @GeneratedValue(strategy=GenerationType.AUTO)
   private property int id;
   private property double subtotal;
   private property int quantity;
   private property String product;
   @ManyToOne
   @JoinColumn(name = "order_id")
   private property Order order;
}
 

And I am so sick of people telling me, "What's the big deal? Eclipse writes the code for me." I don't just write code -- I also read it. Eclipse does not simplify my task of reading all that property boilerplate. I suppose it could fold the boilerplate, but it doesn't. Before you say, "Sure, that's the solution," think through how you would fold the Javadoc comments.

Every other language, from C# and PHP to Ruby and Scala, supports properties in some way. In the Java language, we have the ball and chain of JavaBeans compatibility, but this can be solved. It's just not very sexy, and the really smart people, such as Neal Gafter and Josh Bloch, won't touch it with a 10-foot pole because they know there's no glory in solving it.

I have seen dozens of blogs that start out with "We've got to do something about properties," followed by a halfhearted attempt at an initial proposal. I have written a couple of similar blogs. One of my students, Nikolay Botev, put together a nifty Wiki that collects all the proposals. I hope that will get us to survey the design space with a bit more focus and come up with a proposal.

JSC: What is the Java class that you couldn't live without?

Horstmann: java.lang.Object

JSC: What recent changes to the platform have made your life easier?

Horstmann: At a macrolevel, generics. It is so much better to have List<Robot> than List.

At a microlevel, I enjoy the enhanced for loop. I smile every time I can write:

for (Foo x : foos)
 

instead of:

for (int i = 0; i < foos.size(); i++)
{
   Foo x = foos.get(i);
   ...
}
 

Of course, there are tons of library enhancements that I am happy about: regular expressions, the Scanner class, XPath support, JPA. Even though it's not recent, I love Java 2D. I do look forward to the Swing application framework.

Too Many Scripting Languages
 
"What is the point of having Python and Groovy and Ruby and PHP and Perl? I want to learn one scripting language really well rather than dabble in five of them."
 
 
Cay Horstmann
Professor of Computer Science, San Jose State University

JSC: What is your view of the proliferation of scripting languages -- Perl, PHP, Python, Groovy, Ruby -- each ostensibly intended for different domains of application?

Horstmann: You know how to pick my hot-button issues. I think it's great that people come up with new programming languages for research purposes. But these languages ought to die a quick death. What is the point of having Python and Groovy and Ruby and PHP and Perl? I want to learn one scripting language really well rather than dabble in five of them.

From a Java language perspective, Groovy seems the best candidate. Groovy has a Java language-like syntax and a metaobject protocol that makes Grails possible. But it's taken a long time to achieve professional language design, and core parts of the language are still poorly defined and even in flux. For example, I can't really understand the Groovy MOP, except by reading the Grails source code.

I was not happy to see that JavaFX Script is yet another programming language. My graduate student, Sadiya Hameed, is implementing DSLs that have the key operators of JavaFX Script, such as bind and dur, with Scala and Groovy as the host languages. It works just fine. The syntax is a little different but really no better or worse.

Pragmatically, neither language would have worked for Sun at this point in time. I am told that it's important that JavaFX Script can be compiled, so Groovy would not be an optimal host. And graphic designers are probably not ready for Scala. Still, it drives me crazy to see yet another language.

Programming Error -- Keeping a Buggy Program Running

JSC: What is the biggest mistake you have made over the years as a programmer?

Horstmann: It's embarrassing, but back in the days of C programming, I felt that it was sometimes better to keep a buggy program running than to bail. This was before exception handling.

I had a small company that sold a word processor for scientific papers. When the program died, our customers screamed. When it wrote a corrupted file, they weren't happy, but they preferred that to losing all their work. At the time, I gave the really bad advice that it might be better to silently do nothing when being given a null pointer or invalid index instead of raising an exception.

Underestimating the Value of Open-Source Software
 
"Twenty years ago, when I had my software company, I heard a talk by Richard Stallman, who said that having proprietary source code was immoral. I had made some money off that software company and thought he was nuts. Well, he wasn't."
 
 
Cay Horstmann
Professor of Computer Science, San Jose State University

JSC: You are teaching a course on open-source development. What should developers and architects understand about the benefits and risks of using, integrating, and modifying open-source software?

Horstmann: Over time, I have become more radically pro-open source. In my experience, programmers aren't encountering problems working with open source. Figuring out the ramifications of an open-source license isn't rocket science.

The biggest misunderstanding is that many people underestimate the quality of open-source software. They believe that it's all written by hobbyists. That may have been the case at one time, but nowadays many large companies -- such as Sun Microsystems and IBM -- spend considerable resources in open-source development.

At the same time, there are many small open-source projects doing amazing work without major corporate support. I will work around the limitations of an open-source program or contribute a fix rather than work with a closed-source program because I know from experience that I can count on the open-source program to be around for a while.

Many years ago, I had a small company that sold a pretty nifty DOS program for editing scientific documents. At a panel discussion in a math conference, someone said that while my program was undeniably nifty, it wasn't going to make it in the long run, whereas his files -- written with Don Knuth's open-source TeX -- would still be readable 20 years later. Well, it is now 20 years later, and he was right and I was wrong. My company was slaughtered when Microsoft gave away Word for free in order to kill WordPerfect, and when our efforts to make a Windows version faltered because we didn't know the secret API calls that were necessary to make a word processor perform acceptably under Windows 3.0. The other fellow can still process his TeX files.

Twenty years ago, when I had my software company, I heard a talk by Richard Stallman, who said that having proprietary source code was immoral. I had made some money off that software company and thought he was nuts. Well, he wasn't. Now the Java platform is GPL licensed, and it will live forever, just like Linux, whereas my software company is long gone.

The Spirit of Java Developers

JSC: Finally, what else haven't I asked you that you'd like to discuss?

Horstmann: When I compare blogs about C# and Java technology, I'm struck by the differences in tone. Many C# bloggers talk about the latest goodie that came from the heavens at Redmond and how they might use it. But the Java technology bloggers write about why something is no good and needs to be improved. Now it could be that C# is such a wonderful creation that no one needs to complain. But I don't think so. If it were, more people would use it by choice. Instead, I think that the Java community has a culture of healthy whining.

We have both the will and the means to improve things and do not passively accept what is handed to us. We don't wait for Sun or someone else to fix what doesn't work. We tinker in a thousand projects and build improved libraries, frameworks, and even new languages. The open sourcing of the Java platform will enable it to be viable for years to come.

See Also

Core Java, Volume I--Fundamentals, Eighth Edition
Book Review: Core Java: Volume I, Fundamentals (8th Edition)
Cay Horstmann's Home Page
Cay Horstmann's Java.net Blog
Becoming a Better Programmer: A Conversation With Java Champion Heinz Kabutz
Writing Better Code: A Conversation With Sun Microsystems Technology Evangelist Brian Goetz
Java Champions Project
Java Champion -- Geert Bevin and His Work With JavaScript

Rate and Review
Tell us what you think of the content of this page.
Excellent   Good   Fair   Poor  
Comments:
Your email address (no reply is possible without an address):
Sun Privacy Policy

Note: We are not able to respond to all submitted comments.