Hacker Timesnew | past | comments | ask | show | jobs | submitlogin

The problem with Java is mainly that people think they have to use all the horribly complex, intrusive, badly written, underperforming frameworks that exist in the Java sphere. And then, of course, you will inevitably be screwed.

To this day it takes real effort to convince Java programmers that a lot of "best practices" are anything but.

For instance I still see Java programmers use frameworks that require them to maintain mountains of flimsy XML configs for things that they ought to have done in code. Both to get the benefit of letting the compiler do the work of weeding out boneheaded errors and to get rid of unnecessary flexibility that just leads to more work and more confusing, hard to read code.

Java is a great language in which you can be very productive. But productivity means that you have to crack down on people who drag along J2EE-crap, or whatever crap was invented to make J2EE-crap slightly less crap. It also means you have to mentor people actively and harass anyone who even thinks of doing in XML what can be accomplished much faster in testable, compiled Java code.



The problem with Java is mainly that people think they have to use all the horribly complex, intrusive, badly written, underperforming frameworks that exist in the Java sphere. And then, of course, you will inevitably be screwed.

Indeed. Back in 1998 I worked on a Java Web framework that was quite slick, easy to use, and relatively lightweight.

It used URLs to map requests to classes and methods (e.g. /foo/bar/baz meant get a reference to an instance of class Foo and invoke bar("baz") ). It used convention over configuration for the common stuff (e.g. where to find classes and views) and was quite robust using a custom request proxy to handle the interaction with Apache.

It was easy to add new behavior (while the app was running, even), easy to do internationalization and custom styling, and easy to deploy.

When the company I was working for got bought the owners decided that they wanted some J2EE thing that could be maintained by a redundant array of mediocre Java hacks so they dumped the fast, efficient, and fun custom code and rebuild the app using beans and entities and war files and all that nonsense.

I quit shortly thereafter.

Since then I've seen countless people bemoan the state of Java Web development, but the truth is that much of the sorrow is self-induced. You don't have to build complex, complicated Java frameworks. And you don't have use only what others have put before you.


> The problem with Java is mainly that people think they have to use all the horribly complex, intrusive, badly written, underperforming frameworks that exist in the Java sphere.

That is a problem with Java, but it is not the problem with Java.

The JVM platform, running server-side, is a proven technology that lets you get stuff done. The Java language, however, is underpowered by today's standards. It has essentially no technical advantage over newer JVM-based alternatives, which can do things better by taking advantage of a decade or more of hindsight that Java never had. Meanwhile, it does have clear technical limitations that make it difficult to use some important programming concepts.

For established projects, Java-the-language survives based on inertia, of course. However, I suspect that for newer projects, some of the alternative JVM languages are now mature enough, both technically and in other important areas such as community and tools development, that using them instead of Java itself should be almost automatic for a lot of projects.


We're talking orders of magnitude here. J2EE, Spring and other mammoth frameworks that force you to do things in rather convoluted ways are very large (negative) multipliers.

The Java language does lead to unnecessarily verbose code, but not shockingly so. I'd prefer somewhat verbose but idiomatic Java code over similarly idiomatic code-bases in many other languages.

Of course, part of the problem is that there are far too many bad programmers (and designers) in the Java community and the reputation of the language suffers because of these people. Java even started out with some of these horribly bad programmes on the staff of Sun. (Those of you who actually read the source code of the standard libraries can probably guess who I am talking about).

The thing is, though: I don't really see this as a problem. In part because it is possible to write reasonable code in Java itself and in part because there are alternative languages that are interoperable with plain Java such as Scala and Groovy. This means you can benefit from the Java ecosystem, but you have more choice when it comes to how you write code.

(That being said: I am skeptical to introducing some things into Java because I don't think it will lead to better code. For instance I don't want closures because it will tempt inept programmers to over-use these features in contexts where they are not a good fit. Closures can turn relatively linearly readable code into a horribly tangled mess that can be hard to reason about. And as I said earlier: Java has attracted a lot of talent-free programmers)


> The Java language does lead to unnecessarily verbose code, but not shockingly so.

I guess that's where we'd have to agree to disagree. It sounds like you are concerned that providing more expressive features, such as closures, will tempt bad programmers, of which the Java community has plenty, to write bad code. I take the view that there are also plenty of competent and some very good programmers out there, and that Java does not let these people get much useful work done as easily as more modern alternatives.

For the competent people, Java is horrendously verbose, and the evidence suggests that this does have a significant impact on the pace of development and the robustness of the finished product. Google Scholar will find you a wealth of reports about this if you're not familiar with the research, mostly based on controlled and fairly small-scale academic experiments, but in some cases looking at industrial case studies as well.

As you suggested, the solution to this is often to use other languages that also run on the JVM in preference to Java itself. I just don't see what redeeming value Java has at that point, unless your dev teams are composed of lots of incompetent devs, in which case frankly you're in trouble whatever language you choose.


I spent a lot of time writing as little code as possible.

This isn't (only) because I dislike typing a lot but because I try really hard to a) par down the problem until I understand it in its most basic form, and b) try to express any solution as simply as possible and as readably as possible.

if mere code terseness is important to you there are other languages that will provide that. however, there is no language that will compensate for the inability to avoid implementing lots of unneeded stuff that comes from not understanding the problem. and for the most part: that's what separates the really good programmers from the bad ones and this is where the majority of the line-count gets spent.

that being said, I fully agree that Java is too verbose. there are a lot of things that it'd be nice if Java took care of for you. this is what I like about, for instance, Groovy. (I've only dabbled in Scala so it would be premature to sing its praise, but I am sufficiently impressed to have planned to do a project in Scala this fall).


I agree with you completely on the simplicity and readability ideas. I think perhaps our difference is on where the unwarranted verbosity comes from.

I'm not advocating a very terse programming style, as tyically seen in Perl or C code.

However, Java doesn't let you compose basic data processing easily. If you have a list of Xs and you want to find those fitting a certain criterion, just compare the effort you have to go to in Haskell:

    results = filter (<10) xs
and in C#:

    var results = from x in xs where x < 10 select x
and in Python:

    results = [x for x in xs if x < 10]
and in Java with someone's collections library on top:

    results = CollectionLib.filter(xs, new CollectionLib.BooleanTest<X>()
        {
            public boolean test(X x)
            {
                return x < 10;
            }
        } );
That's pretty typical of the problems with pure computations, in my experience.

When you start talking about I/O and other programming with a time dimension, you find similarly clunky handling of everyday things like events/publish-subscribe/observer/whatever you want to call it, not least because everything has to be in an explicit interface before you even start. Meanwhile, other languages these days are offering tools like message passing and actor models, which both scale up with system size without compromising the basic architecture and support concurrency with relative readability and safety.

Please notice that none of this has anything to do with terseness as such. It's about whether the language provides simple, readable tools to implement widely applicable programming techniques.


Yep, I saw this same thing. Mountains of XML deployment descriptors / "component wiring" (some "Spring" garbage), needlessly verbose and usually unneeded mapper classes, useless interfaces (my rule is if you are only going to have ONE implementation save the interface for later after you know you got it right and need it), extra layers that do nothing (except "map", of course), etc.

kill me. Makes me want to kill myself.


This exactly describes my very brief experience working with Java professionally. Back in university it was no big deal - the differences between C++ and Java weren't that big. In a production environment, though; ... XML, XML, XML!

All the XML-wrapper tools for Java are supposedly the reason why there is so much XML config stuff going on - but the result is that you end up writing soo much code in XML instead of the actual language that you're supposed to be using.

It's like somebody looked quickly at the MVC pattern, got it all wrong, and now Java has very tight coupling between XML and Java code for any production environment that hopes to leverage existing tools.


And the really bad part is that in Java XML has always been extremely painful to work with.


That's one of the reasons I left my first and last employer. Tons of compnontent wiring written in xml, tons of configuration directives, but the end only the defaults were used anyway. Impossible to do updates because everything could break.


Spring offers some if the features to JAVA, that these newer languages have. Spring annotations lessens the XML configuration, none at times, it's AOP jar allows passing methods to methods as in some of the functional types, etc. Problem is people haven't updated their codebase and continue maintaining the old XMLs.


Just because a developer utilizes the JVM doesn't mean they're writing in Java. As I recall Twitter uses and is a big proponent of Scala, which sits on top of the JVM.


I agree. Java as a language has been abusively used (+XML), just like any other popular languages. But the JVM is very solid and luckily we can use other languages other than Java. So you get the best of both worlds :) I use Groovy and Scala for personal projects, but at work I still use Java.


You guys are never reading the OP submission: In the article the architecture of Twitter is a bit explained.


I most certainly did read the OP submission. Perhaps you meant to address the parent?


Totally true. Our stack is Java but the application doesn't have a single XML configuration file. J2EE is for IT that depends more on vendors than their employees for continuity.

http://bagcheck.com/bag/382


I think it depends on how the frameworks are used. Our development team moved from maintaining every dependency in code, to using Spring for dependency injection (and not much else) and saw measurable improvements in productivity. It is especially useful when working in a distributed team. If the team knows how to use the framework properly (for spring: use annotations, autowiring) a lot of the issues mentioned above can be mitigated. There is a reason why any serious project written in Java will generally use Spring or Guice (Google's DI framework).

Jave EE, on the other hand, is crap.


Annotations and auto-wiring for a "serious project"? Please no. If you want to see how to write code in java without going framework mad, look at this book http://www.growing-object-oriented-software.com

I have worked with one of the authors on a "serious project" in a bank and over time we gradually ripped out the frameworks, making the code much more explicit and less magic.


Indeed. But sometimes you need "magic". If you have a developer that is working on a specific part of an application, building business logic that does not require her to know how MQ transactions are handled, or which database drivers are used, using a DI framework like Spring or Guice may help. These frameworks may add some overhead, but they also make unit testing, documentation and reduce code complexity of business logic.

I guess it depends on the team you are working with. If you have solid, experienced engineers who understand the business domain, using Spring may not be relevant. But if you have a team that have different levels of skills and experience, a framework that abstracts away some of the underlying complexity is useful.

If you are building a real time trading system, you probably don't want to use Spring because you want to control each and every component. But for most other projects it can be useful.

Btw - your link mentions TDD. What tools did you use? (just out of curiousity..)


Have you tried Java EE 6 at all? It seems to be catching up to Spring. That said, there might not be many reasons to use it, especially since not many application servers support it.

I worked with Java EE in 2004, took a break, and started working with it again last year. It's not too bad, except for JSF. JSF is really a horrible mess. They should scrap it and start over.


There is a reason why I would generally assume that any developer that assumes that any serious project generally uses Spring is generally mediocre to bad. Generally.

Java may be a bit limp. But there's no reason to hit it over the head with a bent crutch as heavy as Spring. That doesn't make it better.

Generally.


Very good point. But - in a large enough project (I am talking more than 5 developers), especially with work being done offshore, there will be mediocre or inexperienced developers. I think having a framework like Spring is helpful.


So what are the frameworks or tools that you recommend? Serious question from someone that has so litte Java experience, you might as well call it "none."

All of the XML config stuff was, to some extent, what turned me away from Java so many years ago.

If I were to start over today, what kind of frameworks would be the wiser choices for desktop apps (gui frameworks) or web apps (web frameworks, maybe an ORM)?


The Play framework (http://www.playframework.org/) is a good example of how things can be done better with Java. None of the bloat or XML config, just a productive set of APIs to work with. It seems to mostly try to stay out of your way. I would love to try it on a real project one day.


That is a hard question to answer in general terms because the answer will depend on what sort of problems you solve. For a lot of my professional life i have worked on large scale information processing or search engines, and thus I know more about designing server components and relatively little about frontend stuff.

But if I were to come up with an answer it would be something along these lines: don't use of a framework or tool that cannot, with relative ease, be replaced by something else. For instance, in a well-designed networked application it is usually simple to replace one networking library with another. Or to replace one HTTP implementation with another. And I am not really talking about drop-in replacements.

Years ago I spent about about a week replacing the entire networking layer in a high traffic server, going from a pre-NIO blocking design to an asynchronous NIO-based design. This actually changed the entire execution model of the system as well as the networking parts, but it had a lot less impact than you'd think because there was proper separation of concerns, strong non-leaky abstractions and a lot of code that was written by people who were disciplined and consistent designers.

As for GUIs, I am not really the right person to ask. I've dabbled a bit in GWT, but I am not entirely certain I like it. Perhaps not so much because of GWT itself, but because it is tiresome to deal with building and deploying.

ORMs are generally a bad idea. Avoid them. You will feel some initial thrill when you can do some simple magic tricks and then everything ends in tears when you find that you actually have to understand exactly how it works and dig into the innards. Definitely not worth the trouble. (If you use ORMs by way of annotations you are doubly fucked because you will have one more thing that can go wrong which then necessitates dipping your toes into territory that you are not dealing with on a daily basis. I have no idea where some developers find the guts to depend on complex yet fragile subsystems that they have zero understanding of)

Instead you should design internal application specific APIs for dealing with stored state.

For instance, if you are writing a blogging server, you should design a interface that provides the operations you need against the blog store. Start by just implementing the storage operations in an implementation class. Then, if you need support for different types of blog stores, you extract an interface definition and then write implementations of that interface. (Of course, when you write the first implementation class you keep in mind that you might want to turn it into an interface later. This should keep you honest and ensure that you never, ever leak types that are specific to the underlying storage through your API).

In one of my current projects I did just that: I created an abstraction over what I needed to store in a database. The initial prototype didn't even use a database -- it was backed by in-memory data structures. Lists and Maps. This allowed me to prototype, experiment and discover what I actually needed without being side-tracked by details on how to realize this in a database.

Eventually we wrote implementations for both an SQL database (mostly as an experiment) and Cassandra. At that time, people depending on this server had already integrated with it -- before it was even capable of persisting a single byte to disk. As I wrote the in-memory implementation I wrote extensive unit tests. Both to test for the correctness of the code, but also to document what behavior was expected of an implementation. Not only did we later apply the same battery of unit tests to the other implementations, but the unit tests became the measure of whether new backends would be compliant.

As I said earlier, it is hard to give general advice, but I think it is very important to learn how to design software rather than picking a framework that will dictate the design for you. It is very hard to undo choice of architecture so at the very least one should make an effort to learn how to think about, and design, architecture. If nothing else so you can later choose the Least Evil Alternative.

I think 90% of people who got on the J2EE bandwagon were clueless about architecture and just did as they were told. the remaining 10% may have cared about architecture, but were not sufficiently averse to complexity and mindful about programming ergonomics to realize what a horribly bad idea it was. Of course, by the time people realized J2EE was a waste of time they had all this value locked into code that was really, really hard to re-use in a different context.

As for Spring and the over-use of dependency-injection and autowiring, that too will pass once the loudest monkeys in the tree get to change jobs a couple of times and realize that breeding complexity by scattering knowledge across a bunch of files is not a terribly bright thing to do. People usually get to hate Spring once they inherit someone else's non-trivial Spring-infested codebase.


Exactly this has made my working life absolute hell, and I agree wholeheartedly, but this sort of shit has long since reached criticality, and I don't hold out much hope for turning it around at this point.


I don't agree. I think the problem is that people tend to think they need to do things a certain way instead of believing in themselves, understanding that programming is about evolving ideas and code in tandem with reality, and just understanding the problems they are solving. Most programmers just attempt to map problem to solution directly without first understanding the problem. Which is okay for trivial problems, but a bad idea for anything that is more complex.


So, what should you use when coding in Java? In my experience the standard API is terrible, inconsistent and frustrating. (Not that I'd use it anyway, the language itself is too limited).


If you don't like the language or its standard library you should not use Java. You should use the language that best fits you.

I happen to not like C++. So I don't use it. See? Easy.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: