Why Java Sucks

I’ve been using Java seriously for about 2–3 years. When using an IDE like Eclipse I can be very productive, I can probably code faster in Java using Eclipse than in any other language (including PHP and Python), debugging is easy, errors can be found quickly and easily. But as any platform does to some extent: Java sucks, and I’ll tell you why.

Swing
I haven’t used it a lot myself, thankfully, but to me it seems too complicated, slow and on top of all: ugly. When I use an OS, I like consistent behaviour and looks. I don’t want some friggin’ purple, slow, ugly looking window on my screen that eats away half of my memory. Who really uses a Java application that uses Swing? Nobody, and for a reason: Swing sucks. We want native-looking GUIs. That’s why IBM developed SWT which uses native widgets supplied by the OS. Not only is this a lot faster and uses less memory, it looks better too. Proposed Swing slogan: “Sure it looks like shit, but at least it does so consistently on all operating systems. ”

J2EE
J2EE is the Java way to build “Enterprise Applications”. It’s widely used in many enterprises. I have some experience with the Servlet/JSP part of it and it works reasonably well. One thing though: Sun loves XML. Every servlet you create, every JSP taglibrary tag you write has to be registered in an XML file. That sucks. The first thing I did when I developed KeyTopic is work around the servlet registration problem (by using only a single servlet). I also briefly looked at EJB, that’s even much, much worse. Every EJB has like an interface file, home-thing file, remote-thing file, and a couple of XML files attached to it. Most of this can be generated automatically by using applications like XDoclets, but still, it’s a mess. It’s confusing, complex, and most importantly: so much more complex than it has to be. At least, that’s the feeling I get when I look at it. For example, check out this post about What Should a Good Enterprise Java Developer Know. I’ll just quote the list, to make it more clear:

  • You need to be proficient in object-oriented analysis and design (OOA/D), design patterns (GoF, J2EEDP), and integration patterns. You should be intimately familiar with UML, especially class, object, interaction, and state diagrams.
  • You need to learn Java the language and its core class libraries (collections, serialization, streams, networking, multithreading, reflection, event handling, NIO, localization, etc.).
  • You should understand how the JVM, class loaders, and garbage collector work in general. You should be able to decompile a class file and comprehend basic byte code instructions.
  • If you’re going to write clients, you need to learn applets for the web and Swing, AWT, or SWT for the desktop. You should also be familiar with the JavaBeans component model for UI widgets. JavaBeans are also used in JSP to isolate business logic from the presentation tier.
  • You need to learn the JDBC API and how to use at least one persistence/ORM framework like Hibernate, JDO, CocoBase, TopLink, or iBatis. You also need to understand the implications of the object-relation impedance mismatch, how it will affect your business objects’ interactions with a relational database, and its performance consequences.
  • You need to learn about the Java sandbox security model (class loaders, byte code verification, managers, policy and permissions, code signing, digital signatures, cryptography, certification, Kerberos, etc) and the various security/authentication APIs, like JAAS (Java Authentication and Authorization Service), JCE (Java Cryptography Extension), JSSE (Java Secure Socket Extension), and JGSS (Java General Security Service).
  • You need to learn Servlets, JSP, and optionally JSTL (Standard Tag Libraries).
  • You need to be familiar with popular web frameworks, like JSF, Struts, Tapestry, Cocoon, WebWork, and their underlying design models, such as MVC/Model2.
  • You need to learn how to use and administer web containers, like Tomcat, and how to deploy and maintain web applications on them.
  • You need to learn about distributed objects and remoting APIs, like RMI and RMI/IIOP.
  • You need to learn at least one XML API, like JAXP (Java API for XML Processing), JDOM (Java for XML Document Object Model), or DOM4J.
  • You need to learn how to build Web Services using Java APIs and tools, such as JAX-RPC (Java API for XML/RPC), SAAJ (SOAP with Attachments API for Java), JAXB (Java Architecture for XML Binding), JAXM (Java API for XML Messaging), JAXR (Java API for XML Registeries), and JWSDP (Java Web Services Developer Pack).
  • You need to learn a lightweight application framework, like Spring, PicoContainer, Avalon, and their IoC/DI idiom (setter, constructor, interface injection).
  • You need to be familiar with various J2EE technologies, like JNDI (Java Naming and Directory Interface), JMS (Java Message Service), JTA/JTS (Java Transaction API/Java Transaction Service), JMX (Java Management eXtensions), and JavaMail.
  • You need to learn about Enterprise Java Beans (EJB) and their various component models: Stateless/Stateful Session Beans, Entity Beans (with Bean-Managed Persistence [BMP] or Container-Managed Persistence [CMP] and its EJB-QL), and Message-Driven Beans (MDB).
  • You need to learn how to manage and configure a J2EE application server, such as WebLogic, and utilize its add-on services, like clustering, connection pools, and distributed transactions support. You should also learn how to package and deploy applications on it, and be able to monitor its performance and tune it.
  • You need to be familiar with Aspect Oriented Programming and Attribute Oriented Programming — both are confusingly abbreviated as AOP — and their popular Java specifications and implementations, like AspectJ and AspectWerkz.
  • You need to be familiar with various utility APIs and frameworks, like Log4J (logging/tracing), Quartz (scheduling), JGroups (network group communication), JCache (distributed caching), Lucene (full-text search), Jakarta Commons, etc.
  • If you’re going to interface or integrate with legacy systems or native platforms, you need to learn JNI (Java Native Interface) and JCA (Java Connector Architecture).
  • You should be familiar with Jini technology as it relates to distributing systems.
  • You should be familiar with the Java Community Process (JCP) and its various Java Specification Requests (JSRs), like Portlets (168), JOLAP (69), Data Mining API (73), etc.
  • You should master a Java IDE, like JetBrains IntelliJ IDEA or Eclipse. (Some people prefer vi/emacs with make files. Whatever makes you tick!)
  • Java is verbose and requires a lot of code artifacts (e.g. EJB); therefore you should be familiar with code generation tools, like XDoclet.
  • You need to be familiar with a unit testing framework (JUnit) and learn various build and deployment tools (Ant, Maven).
  • You should be familiar with several software engineering processes commonly used in Java development, like RUP (Rational Unified Process) and Agile methodologies.

Aargh! Kill me!

Choice
With Java you have choice. Too much choice. You have a choice in everything: widget sets (AWT, Swing, SWT), XML parsers (W3C DOM, SAX, JDOM, …), web developement frameworks (like a hundred, so it seems). It’s so much choice that I just don’t know what to choose and what the implications will be. This is a major reason why I hesitated to start with Java, it’s just so amazingly overwhelming and complex.

Purity
Basically the only proper way to write your software in Java is system independent; you’re stuck with the common denominator. On the server side this usually isn’t the biggest problem, but when you do client stuff, you might want to use the system tray in Windows. No! Thou shallt write pure code! Oh sorry, I bought this really cool OS that has all those cool features, but now I can’t use them because that’d affect my purity. Get the f*@#$)(*#@$*@#!

The Language
Java is a fine language, still. With Java 1.5 (not out yet) some stupid decissions were made. Generics for example. Generics in Java use a wipe-mechanism to retain backward compatibility with previous Java versions. Some of the drawbacks are these:

  • No parameter type information is retained on a generic collection. You can’t ask what the type parameters were of a certain collection at run-time, for example.
  • You can’t use a primitve type as a type parameter.
  • The new boxing features and generics won’t always work as you might expect.
  • You can’t create an array of generic collections.
  • There is some additional minor stuff that involves inconsistently using the keyword ‘extends’ when actually implementing interfaces (for which Java always used ‘implements’, not with generics).

The problem with this is that you can only understand why this stuff doesn’t work by understanding how they implemented those features, which is a typical example of a leaky abstraction. More information on these problems with Java 1.5 can be found in Bruce Eckel’s presentation (Real Media).

Some smaller things

  • The Classpath: As a beginner you’ll always have problems with the classpath. Java can’t find the class you’re trying to use, says the package declaration is wrong. Trouble, trouble, trouble.
  • In Java not everything is an object (or can be treated that way): there’s also primitives. Primitives (int, float, char, double, byte, …) are radically different than objects. The only reason they’re here is for speed’s sake, and to complicate things more. This sucks.
  • Applets: They suck: they either don’t work; don’t work everywhere; take a lot of time to load; nobody has the Java plugin installed correctly or at all; and are barely used for the right thing. Avoid.
  • James Gosling, the founder of Java, says stupid things: “Java always has been faster or as fast as C++.” (source: Bruce Eckel)

The Alternative
C# and .NET score much better on most of these points. .NET 2.0 will have CLR support built-in for generics and won’t use a hack, like the wiping that will be used in Java 1.5; the GUIs use native widgets; .NET allows purity, but you don’t have to avoid dark alleys for the rest of your life if you step out of the managed .NET world; there’s a lot less choice in application frameworks (they basically all come from Microsoft); there are no classpath problems; there are value types and reference types, which are, arguably, more natural than primitives and object types; C# is a more feature rich (and in my opinion better) language than Java; and XML file usage is more sensible. Sure, .NET isn’t perfect either, but, arguably, it sucks less.

More Java Suckage

Disclaimer
Of course I’m exaggerating. Java is a good platform to develop software for and with. It’s really not that bad as I make it look. On top of that, as I said in the introduction, every language sucks in a way: C# sucks, C++ sucks, Python sucks, Perl sucks and most of all: PHP sucks.