There are some good things about Java. The virtual machine has been refined for quite some time. The garbage collector is likely to perform well. The standard library has gone through many iterations and is very encompassing and complete and amazingly well-documented. The community is enormous. The language is as cross-platform as you could reasonably expect any huge program to be. It has nice GUI frameworks (which nowadays even look native on Windows and Linux, if you use SWT), a good threading library, good socket libraries, and all the things I wish Ruby or Common Lisp had.
The one unignorably bad thing about Java is that you have to write it in Java. It's next to impossible to write Java by hand, and it's still a whole lot of pain even if you use one of the massive Java IDEs that trick you into not noticing the pain. The language is way too verbose. The syntax is busy and full of mandatory brackets and parens and punctuation and bullcrap. The demand that you catch every conceivable exception is tiresome. The ability to abstract all of those things away isn't present. The package / import scheme is way too much typing for any human being. No Lisp-style macros, no easy-to-use anonymous functions, clunky iterators, primitive looping constructs. Everything is forced into a Object Oriented mindset even if it doesn't fit well. And so on.
But the good thing is that nowadays you don't have to write Java in Java. You can write Java in Ruby using JRuby, or write Java in Lisp using Clojure. I gave both of these a try in the past week or so, and both are awesome. You can write the bulk of your program in a nice powerful fun-to-write language, and call out to Java to handle the GUI bits or whatever Java is good at handling. You can write tasty Ruby or Lisp abstractions that hide the horrible mess that is Java's syntax. (There's also Jython, if you swing that way.) You'd think it'd be more effort to write Ruby code that translates to Java than just to write plain old Java, but Ruby is so much better than Java that it actually ends up being easier. For me anyways.
It's an interesting trend which makes a lot of practical sense. No language is great at everything, so why bother limiting yourself to one language per program? Especially with computers being so fast today, we can get away with layering language on top of language. It's a nice situation, if you want to get programs done as fast and with as little effort as humanly possible.