It seems impossible to constructively praise or criticize Java without eliciting strong reactions. It comes from both sides; some seem to love to hate Java, and parts of the Java community become defensive as a reaction.

For example, Paul Buchheit recently posted some insights into API design, referring to poor examples that happen to be written in Java. He immediately states he doesn't hate Java. The post is about APIs, not the language. Even so, he still had to update his post saying "It's not about Java, really", presumably because of some polarized reactions. This is unfortunate because it distracts us from Paul's excellent commentary.

I suspect the polarization starts from a trap I have fallen into myself. Like many involved in language discussions, I use Java professionally and other languages at night, so I run into examples analogous to the one described by Paul Buchheit. I sometimes get frustrated with poor APIs, and also with the Java language -- either directly or by association with poor APIs. I wonder, couldn't it use powerful constructs I use in other languages, or could the APIs just plain be simpler?

The problem is my frustration may linger when I discuss programming languages, and (knowingly or unknowingly) be reflected in my tone when discussing Java. The resulting post is more acidic, and less level handed than I would like. Those who disagree with my arguments are likely to pick up on that tone and may respond in kind. Before long we've spiraled into isolated camps, and meaningful discussion is hard to achieve. My last post had signs of this.

So, where did I go wrong? When discussing constructive criticism of Java and its APIs, we need to view Java with some perspective. We need to remember its history. So my first point is:
We are critical of Java in a context different from the one in which it was designed.
A key goal for Java was to replace C++, and this goal led to design decisions that are often targets for criticism today. In 1996 it wasn't clear we could create a sufficiently fast language without primitive types and arrays. It wasn't clear how much boilerplate code would be required by anonymous callback classes or checked exceptions. It wasn't clear that since the new syntax exactly specifies implementation, factory patterns would proliferate, and so on. So my second point:
Criticisms of Java should not imply any negatives about the designers of Java. Critics of Java are likely working in a problem space that differs from Java's original design goals, or incorporating new knowledge from the past decade.
There are certainly some that disagreed with the above decisions in 1996, but it was surely more debatable then, and different decisions may have slowed Java's proliferation -- which was opposed to its original design goals.

The key is we need to keep this background in mind whenever discussing Java. We can criticize Java and its APIs without insulting anyone. When being critical of Java, any frustrations should be tempered by knowing the landscape has changed. Similarly, apologists should recognize that criticism need not be viewed as an attack; it might be an attempt to make things better.