top | item 4549544

Everything that's wrong with Java in a single class

180 points| fpp | 13 years ago |plus.google.com | reply

155 comments

order
[+] cletus|13 years ago|reply
I hate this kind of post. It's the tech equivalent of "You're a stupidhead". If you want to criticize Java then at least make some meaningful points. Just off the top of my head:

- Java logging is a clusterfuck

- Something as simple as wanting symbolic links in a Maven build requires a third party plugin, last updated in 2007 (maven-junction-plugin) that requires something no longer in the central repo;

- No lambdas yet;

- Type erasure in generics and the consequences thereof (eg inability to create generics of primitive types unlike C#);

- Checked exceptions;

- No function references, lambdas, etc (still a year+ away);

- Eclipse is a hot mess (IMHO). And, no, for Java at least, vim/emacs simply are no better. IntelliJ is but for some reason they insist on making it hard to make plugins as their API changes every major version. Jetbrains seems to be going out of their way to make it hard;

And as far as Spring goes, it's probably long in the tooth now but people either forget or never knew just how influential Spring was in the early 2000s. Java at that time really was a hotbed for innovation (believe it or not). It may not have invented DI/IoC but it certainly popularized it.

But long class names? Really? Is that all you've got? Who cares?

EDIT: I don't care about the description either. If anything, it's probably poor text from someone who isn't a native English speaker.

As for the layering, it's nit-picking. I had a quick look and found only one use for this: CacheProxyFactoryBean. Perhaps there was more at some point? Who knows? But the subclass seems to be used in the Spring AOP stuff.

The thing that really bothers me about this is the tone. It's a bit like how among a certain set it's popular to deride PHP. In my experience, people who bother to do that (or simply enjoy it when others do) are nearly always closedminded dogmatic fools.

[+] famousactress|13 years ago|reply
In his defense, I don't think the long class name is the problem he's pointing out.. it's the over-patterned, over-generalized nature of something that barely does anything.

The class's description is "Convenient proxy factory bean superclass for proxy factory beans that create only singletons."

Seriously? That's fucking hilarious.

[+] rickmode|13 years ago|reply
The class combines no less than 6 concepts / design patterns:

  - Abstract
  - Singleton
  - Proxy
  - Factory
  - Bean
  - Interceptors
It's not just a long name. The class makes sense in the context of this framework. The core problem (as others here point out) is that the Java flavor of OOP makes writing this sort of code idiomatic.

On the upside, you feel really smart once you grok all these concepts simultaneously. After a couple years this you get to brand yourself a "Java Architect".

[+] T-hawk|13 years ago|reply
It's not the long name that's being mocked, it's the underlying problem of which the name is a symptom: that Java tends towards too many layers of abstraction, and the strict object-oriented nature means that every one of those layers is expressed as an inheritance level or a Factory object or a Proxy object, all a dozen levels away from where any action and logic is actually happening.
[+] mongol|13 years ago|reply
The title should have been "Everything that is wrong with Spring ... ". Then it would not have been especially accurate, but more accurate. I like Java better than I like Spring. Spring made a framework out of an idea, but not all ideas should be packaged. Ideas can also be embraced. Dependency injection is an idea that should be embraced, but not as a packaged solution. It is a pattern, not a a software project.
[+] pmahoney|13 years ago|reply
I actually really like Java logging (well, I like SLF4J and logback).

On Ruby, I'm constantly at a loss on how to do logging. Sure, in Rails there's the Rails logger available pretty much everywhere. But if I'm writing a reusable library, I can't count on that. So what do I do? Demand every user of my library configure it with a logger?

The stdlib Ruby logger also has no way to fine-tune log levels by class. In a Rails app, sometimes I want debug level, but I rarely care to see each and every SQL statement. (There tend to be hacks to monkey patch around the common cases suggesting others have been similarly frustrated.) Even if I use log4r or some other logger with more fine-grained tuning, within Rails, everything will be using the same logger object, so the typical Java method of tuning by giving each class its own logger doesn't work.

Bleh. Give me SLF4J with logback any day. When writing a reusable Java library, I really have no qualms about using SLF4J.

[+] koevet|13 years ago|reply
> Java logging is a clusterfuck

Care to explain? Logback is easy to configure and extremely efficient

> Something as simple as wanting symbolic links in a Maven build requires a third party plugin, last updated in 2007 (maven-junction-plugin) that requires something no longer in the central repo;

If you are still using Maven it's your problem. Switch to Gradle and your life will be much better.

> No lambdas yet;

True, but if you really need them use Groovy or Scala. Groovy 2.0 is almost as fast as Java and Scala is fun.

> Type erasure in generics and the consequences thereof (eg inability to create generics of primitive types unlike C#);

True, but doesn't this lack of feature harm framework developers mostly? The same people which the article is critiquing.

> Checked exceptions;

You can just ignore them when you write new code. If you have to deal with code that throws them, just deal with them. Most of the modern frameworks nowadays don't use them.

> No function references, lambdas, etc (still a year+ away);

Groovy, Scala and the favorite kid on the block, Clojure

> Eclipse is a hot mess (IMHO). And, no, for Java at least, vim/emacs simply are no better. IntelliJ is but for some reason they insist on making it hard to make plugins as their API changes every major version. Jetbrains seems to be going out of their way to make it hard;

This is the only point for which I tend to agree. Eclipse is difficult to work with. IntelliJ on the other hand is a valid alternative. These days I mostly code in Sublime Text 2 though.

[+] shortlived|13 years ago|reply
I totally agree on java logging. Lambdas would be nice. Checked exceptions? I love them.

Lastly Eclipse is THE best thing since sliced bread. I LOL'ed when you mentioned vim/emacs in the same sentence. Have you actually used Eclipse on a big code base? It's introspection is such a productivity booster. I've not used jetbrains in a decade, but nothing else out there beats it, hands down. Both in terms of speed and quality.

[+] xyzzy123|13 years ago|reply
It fascinates me that I also believe that Java has serious issues, but I differ on dimensions.

Well yes, logging. There is slf4j though. I think that works, although the fact that one needs a metaframework is... interesting.

Eclipse? I love eclipse. I used emacs every day for 2 years, IRC in emacs, news in emacs, EVERYTHING in emacs. Eventually I got sick of IMAP blocking and interrupting the world. I grew to love Eclipse because I realised I could not efficiently comprehend Java code any more without it.

Over-layering is a serious, serious problem in Java. I think I understand your point of view, but a big part of my job is performing code reviews. It really sh%ts me every time to have to jump through the Service, the ServiceImpl, then the Repository, the RepositoryImpl, the Dao, the DaoImpl and... oh, there's the fricking query. Thanks guys.

My huge problem in Java is that I always find 8 classes where 2 would do. The extra classes do serve a purpose; they fulfil stereotyped, expected roles. In some ways the boilerplace reduces cognitive overhead. In other ways, it really does not.

Personally as someone who reviews multi-million line codebases regularly for a living, I am actually terrified of hordes of new Java developers discovering lambdas or acquiring advanced generics. These things are tactical nuclear weapons of source code obfuscation in the hands of people whose judgement (through bitter experience) I no longer really trust.

Spring is not evil, but it does make life difficult because it's hard to follow references. Fortunately, whenever you see an interface Foo you normally just have to jump to FooImpl. Because it turns out that 90% of interfaces are actually not needed; except culturally, stylistically or dogmatically. Personally I think they're over-used, but that's because my observation is that most interfaces (seriously, 90% level) are implemented only once.

Agree on the checked exceptions though. That was a mistake.

I think actually there is nothing wrong with Java as a language, but without sane leadership the corporate culture of it becomes uniquely byzantine.

[+] pron|13 years ago|reply
Regardless of this post (which, indeed, has little to do with Java per-se), Java the language might be outdated for many applications. But I believe it's now pretty widely acknowledged that Java's contribution isn't the language, but the platform. The JVM is the best performing, most stable managed runtime in existence. Not to mention the invaluable runtime profiling an monitoring that is years ahead of anything else out there. The platform (possibly used with some other JVM language) still gives the most bang-for-the-buck for performance critical, scalable applications.
[+] rbanffy|13 years ago|reply
> But long class names? Really? Is that all you've got? Who cares?

Is that the only thing you think is wrong?

[+] godbolev|13 years ago|reply
Just out of curiosity, why do you think checked exceptions are bad?
[+] sutro|13 years ago|reply
I'm kind of partial to com.sun.java.swing.plaf.nimbus.InternalFrameInternalFrameTitlePaneInternalFrameTitlePaneMaximizeButtonWindowNotFocusedState.

A "non-haiku" has been written in its honor:

http://stackoverflow.com/a/891589

[+] dustingetz|13 years ago|reply
> "it's not java's fault" (from multiple comments)

languages have opinions. Java is designed around the principle of "everything should be a class" which makes everyone's first instinct to have lots of mutable instances with lots of mutable member variables. Turns out this leads to shitty code in the large.

Compare to Clojure, which supports mostly all the same features as Java, but emphasizes them differently. You can use mutable data, but by default everything is immutable. You can have methods and instances, but its easier to just use a function. Java can do higher order functions and closures, but they're so verbose that its better to choose imperative for/while loops over map/reduce/filter, which don't even come in the standard library. Clojure is designed to make higher order functions and expression-oriented thinking idiomatic, java makes this so difficult as to be not worth pursuing even with a team who already understands how to think this way.

Java's design leads people towards code that you're afraid to touch for fear of disturbing state somewhere else which causes failures unrelated to your change. That's why when you need to fix a bug, in Java, people will expose a hook here and there to make a minimum change that they are sure doesn't break code somewhere else. A decade of changes designed to expose little hooks to not break existing code, you end up with a AbstractSingletonProxyFactoryBean with intercepters and proxies and loaders. Nobody is claiming that AbstractSingletonProxyFactoryBean is an abstraction. It came into existence over time because it was the easiest way to fix bugs and adapt to changing requirements while not breaking existing code.

It's definitely java's fault, and all the best language designers know it.

PS Here's a paper that describes a team who migrated a bunch of excel macros to Java, found that they had built an unmaintainable mess, then took the same team and built it in OCaml, and have been using OCaml ever since. http://queue.acm.org/detail.cfm?id=2038036 - OCaml for the masses, Yaron Minsky, Jane Street

[+] mangler|13 years ago|reply
Clojure functions are Java classes. It's not much different from using a Java functional libs. Except that Java will probably be faster as Clojure still doesn't do primitives and stuff (not sure about that one, may be it already does)

You can do all the functional stuff in Java, Clojure is doing exactly that. It will be more verbose, but once you learn the ropes it just looks different, it is not different.

[+] eloisant|13 years ago|reply
It is true that "Java culture" leads to this case of design pattern abuse, but you don't have to do all that when using Java.

I dare you to find this kind of atrocity in Play Framework 1 (written fully in Java) or in Play 2's Java code.

[+] spacemanaki|13 years ago|reply
As others have pointed out, this really should be titled "Everything that's wrong with Java culture ..."

For a more technically critical look at Java the language, I recently stumbled on this video while watching a Scala talk Martin Odersky recommended in the first few sessions of his new Coursera class... http://www.youtube.com/watch?v=hcY8cYfAEwU

It's pretty meaty, although it looks only at Java 1.0. Many of the criticisms aren't things I would have necessarily thought of first, and it gave me something to think about in terms of what my own priorities are. (For instance, the lack of first-class functions and closures gets no mention at all)

[+] ww520|13 years ago|reply
What is the Java culture? I don't think there's anything. There are so many Java programmers that there are bound to be bad ones along with the good ones.
[+] chimeracoder|13 years ago|reply
> As others have pointed out, this really should be titled "Everything that's wrong with Java culture ..."

I think any UI designer would tell you that a culture doesn't happen spontaneously. Why do Quora, StackOverflow, and Yahoo! Answers feel like very different products despite providing essentially the same functionality?

You can say this about any language and its community, too, not just Java. And it works both ways. Perl, for all its faults, provides a very easy way to package libraries and a well-organized repository for doing so, hence the comprehensiveness of CPAN packages[1].

Java's culture is a result of the fact that Java-the-language promotes badly designed pseudoabstractions intended to guard against bad design. Java provides broken abstractions because it is itself a broken abstraction - the class is a very poor abstraction over an object, and an inconsistent one at that (Java supports multiple kinds - in the mathematical sense - a design choice which impacts the way people use it).

[1] This is particularly true if you turn the clock back ten years and compare with the state of programming languages back then.

[+] programminggeek|13 years ago|reply
The thing is, it's not Java's fault. You can write good Java code. It can be small, and easy, and nice. The problem is the word Enterprise and the abusive abstractions that seem to come along for the ride.

Also, many of the abstractions start as good ideas, but they soon become a hammer and everything else becomes an AbstractNailFactoryInterfaceManagerProxy.

[+] jefflinwood|13 years ago|reply
If anything, that's an indictment of the Spring framework, which you certainly don't need to write Java. For instance, there are over 500,000 Java apps in Google Play market, and I'm pretty confident most of them don't use Spring.

Now if you wanted to criticize Spring and cargo-cult enterprise Java development, I think that's reasonable.

[+] jebblue|13 years ago|reply
Good observation, I've read several posts which complain about factories and proxies. With Grails (which can be all Java no Groovy if you want), Zk, GWT, etc. I can do powerful web apps. No EJB and no Spring needed.
[+] Tichy|13 years ago|reply
My favorite joke in that vein is

"I had a problem and thought to use Java - now I have a ProblemFactory"

[+] dguaraglia|13 years ago|reply
More likely just one implementation of IProblemFactory.
[+] islon|13 years ago|reply
My opinion goes like this: java is a verbose and hard-to-change language compared to ruby/python/js/etc so people think "I'm going to create this extra layer/abstraction just in case someone needs to change/use it for something else later" while dynamic language guys just solve the problem at hand and then improve it later because it's painless to do so.
[+] snorkel|13 years ago|reply
Agree. Java coders seem to have a habit of over-solving the problem with useless layers of abstraction. I recall trying to create a silly video editor in Java, using a common vendor framework for media files, simply opening the file then extracting the Nth frame involved instantiating 12 layers of classes, like nested Russian dolls, every layer just as useless as it's parent class. What a waste of time it was to consider Java.
[+] zxcdw|13 years ago|reply
It's more a problem relating to the fact that many projects and their code bases are designed and planned to last for over a decade if not two or more. One simply can't just make drastic changes back and forth, because literally, peoples lives are on the line(let alone how much financial capital is invested...) with lots of written code. I'd grab Java, C++, heck, even C over Python or Ruby, let alone god damn JavaScript for a project which is going to ship after approximated 5 years of development and which has planned maintenance for at least 10 years afterwards. Considering how we miss deadlines, I'd assume such a project would be maintained after 20 or 25 years. Yes, someone would still work with the code base in 2037. Imagine that, and that's not even an unrealistic stretch. Welcome to enterprise software development! Do that with Python, Ruby or JavaScript and I'll give you a cake or two.
[+] aut0mat0n1c|13 years ago|reply
Hello and welcome to 2008!

Seriously though, if you are going to rehash this tired schtick then at least make intelligent points about the problems with the language. I have been writing Java for over a decade and I can tell you are a number.

[+] hmottestad|13 years ago|reply
No need to create javadoc, takes people 4 years to read it anyway :D
[+] labizaboffle|13 years ago|reply
No programming language that I have encountered so far is wrong. It is only different.

What is "really wrong with Java", not the language but part of the "culture", is a tendency for writing excessive code and xml, abstraction, mocking, etc. but overdoing things happens everywhere.

And a ridiculous "Ruby culture" thing was a DSL used for BDD called Cucumber. It promised tests that look like English so that analysts could write the tests, but then you had to write backing code so that would work. But a lot of people still use it.

And a ridiculous Javascript thing is Node. Javascript on the server? You have to be fucking kidding me. But now you can get a nice job in SF with JS experience.

Pointing these things out is useless. I make a lot of mistakes. Many publicly and online. People grasp onto "bad ideas", but really they are just ideas later proven to be not as good as some other idea. So, write your "everything that is wrong with Java" classes, SpringSource/VMWare/EMC employees. Nothing wrong with that.

[+] jasonwatkinspdx|13 years ago|reply
Cucumber has some flaws in my opinion, but I think saying its intent was to allow non-developers to write tests is mistaken.

It's more a straightjacket that ensures a minimum of mutual intelligibility, particularly when a developer and domain expert are collaborating. Trying to make a tool that non developers can use to write tests is nearly pointless (selenium remote control for example). But adopting an approach where an analyst can look at what's on the screen and say "Hey, no, that's not right. We have to get the foo form in the file before it goes to bar department, not after." It's also nice in the context of CI, where non developers can look at a status webpage and see the state of an app is without drowning in technical details.

As an aside, my criticisms:

I hate how favors a specific BDD template (As A, In Order, Given, When, Then etc) rather than letting people pick their own language sensible for their project. The product/business people I've put in front of cucumber generally disklike that language, and often feel resentful for it being forced on them.

And secondly, I think the way statements are matched to step definitions via regex is awkward. Regexes in general tend toward frustrating abstraction. Do I want $1 or $2 or $3 or wtf was $7 supposed to be again? They also don't compose well. In my experience this choice ends up making the step definitions a cluttered dumping ground that takes more effort to organize than I'd like.

I think both of these would be solved by using a more proper grammar mechanism, probably PEGs, and keeping the rest of the tooling ignorant about its specific definitions.

[+] csense|13 years ago|reply
"Convenient proxy factory bean superclass for proxy factory beans that create only singletons."

It's concise, precise, clear functional description of the class. It's also a profound commentary on the shortcomings of the Java ecosystem.

If you enjoyed this, recommended reading:

http://steve-yegge.blogspot.com/2006/03/execution-in-kingdom...

[+] 27182818284|13 years ago|reply
Similar to the classic dig on C++, "If you think C++ is not overly complicated, just what is a protected abstract virtual base pure virtual private destructor, and when was the last time you needed one?"
[+] runn1ng|13 years ago|reply
Can somebody smart please come and explain what this class actually does?
[+] jakejake|13 years ago|reply
I guess I don't get what the problem is with this? It seems a fad to me that people are bashing Java, for whatever reason everybody is jumping on the bandwagon. When I look at Objective C the syntax for doing simple things like initializing variables can be incredibly verbose, but all you hear on HN is how gorgeous it is.

I admit it is a bit funny to see a class with so many design patterns employed. But nothing about it is difficult to understand and the name is certainly descriptive. I don't see how it can be considered over-engineered without knowing the context. This just looks like one class in a larger framework to me.

[+] jmgao|13 years ago|reply
The carryovers from C, and resulting insane behavior when mixed with Java's usual syntax are pretty hilarious, too.

    public int[] what()[]
    {
        return new int[0][0];
    }
[+] jebblue|13 years ago|reply
I've been coding in Java since it came out in 1995 and I never did that, didn't know you could or why you would want to. So what's your point? Java, C, C++, even C# are readable by average people like me. LISP, Haskell, Ruby, Scala, Smalltalk all look like they were written by aliens.

If you really want to see something funny look at JavaScript code which combines integers and strings. Things that Java would complain about immediately, JavaScript tries to actually run with unpredictable results.

[+] matt2000|13 years ago|reply
This is pretty funny, and yes Spring itself is pure insanity, but it's not really fair to equate Java the language with Spring the framework.
[+] benjaminwootton|13 years ago|reply
And this is positively lightweight compared to J2EE which Spring superseded.
[+] jrabone|13 years ago|reply
Take a look at J2EE 6 - you might find it's Spring which is the heavyweight these days. Although as of 3.1 at least the need to write your programs in XML is going away...
[+] brown9-2|13 years ago|reply
I'm not sure how one framework developer's naming choice (a framework which by the way, needs to do some pretty meta things in regards to creating factories for other factories, and which is using the term "singleton" to mean something different than usual) is a criticism of an entire language.

You can come up with ugly names for classes in any language.

[+] columbo|13 years ago|reply
I think it speaks more to the community than the language (and arguably there is also no such thing as a community).

After years of consulting I can't remember how many times I've walked into an Enterprise Java Shop(TM) to find TemporalSystemLoadOrganizers, IntransitPredeterminedApplicationUtilitySources, MetaphysicalManipulatitiveQuantityDisorderRecognizers only to find out that at the end of the day these abstract-factory-driven-decorated-decoupled-dynamically-injected-frameworks tend to do such obscure/complicated things as "Update a user's first name" or "Show the last item the user has purchased"...

Again, not Java's fault and no question you can write very fast, beautiful and clear code in Java. I'm sure every language has specific warts and most of them probably reside more with the community than the syntax.

[+] advisory5739f2|13 years ago|reply
It's the remnants of the late 90's early 2000's software development overengineering disease, so aptly captured in the mess that was J2EE.

Similar to "nobody got fired for buying IBM", the mindset was that "nobody got fired for building layers of abstraction just in case."

It's the culmination of the second system effect.[1] Without a pervasive unit testing culture, the big enterprise answer to "what if" is "let's add a point of flexibility here."

Obviously, people should be held responsible for building unnecessary abstraction layers like that. They waste time and are often wrongly abstracted, so when you do need to go in to refactor, you end up having to fight the pre-existing "what if" abstraction.

[1] http://c2.com/cgi/wiki?SecondSystemEffect

[+] romaniv|13 years ago|reply
It's not about naming. This class actually does what its name says. That's the best part. The methods and their JavaDoc descriptions are pretty hilarious as well.

And it's not about the language per se. (You can write clean, simple code in Java, but you would have to write it pretty much from scratch.) It's about Java culture, which encourages this kind of stuff.

And yes, I had been a Java programmer for many years. I used to like the language at some point. But several integration projects made me like its culture less and less.

[+] meritt|13 years ago|reply
This isn't a verbose naming convention. The name is actually quite succinct in describing what this encompasses.

And that's precisely the issue.

[+] sandGorgon|13 years ago|reply
I have a simple question: is the root to all of this infrastructure problems (proxys, abstractions, etc.), the fact that Java introduces a fear of changing state (i.e. the existence of the "private" keyword) ? Since Java guards private variables so effectively and proselytizes a fear of state, the natural evolution of the community to build these layers.

Clojure is not a good comparison, since it avoids fear using immutable state. Ruby/Python is also not a good comparison since, well, it does not respect the privacy of state in any manner. The frameworks that have naturally evolved there, reflect the philosophy of need-to-keep-things-simple (which is the only way to work in a world where state cant be abstracted out).

Perhaps if you ask someone to build a Java framework WITHOUT using the "private" keyword, maybe it will lead to a whole different revolution ;)

[+] javajosh|13 years ago|reply
This is truly an issue with Spring, not with Java. An argument could be made that such a class is a symptom of some cultural problem with how Java developers tend to do things, but the OP is not making that point.

The issue with Spring, though, is very real. The key problem that framework authors want to solve is giving programmers the correct slots to place functions in. Oddly, Java is not very good at providing the kinds of slots that seem natural, particularly because of it's lack of lambdas. Plugging a function into a Java project requires that you participate in the inane Type-Name-Game whether you want to or not.

Play this horrible game long enough, and you will get the problematic names that the OP has discovered. And it only gets worse for in-house software.