Hacker News new | comments | show | ask | jobs | submit login
Java is just fine for your online service startup development (open-lab.com)
30 points by ppolsinelli 2964 days ago | hide | past | web | favorite | 49 comments

Good advice. If you know a technology well, then run with it. Focusing on actually delivering value vs. bragging rights to the latest and greatest dynamic language/framework.

On a side-note, I will say this - I am a Java developer (at my day job), and Java-land boasts some of the best tool support there is out there. On the flip side, the refactoring argument does not hold much water. These days almost everything in Java, especially when using any kind of framework means a lot of configuration and wiring using XML, Annotations and other syntaxes (EL - Expression Language comes to mind). Most tools don't see these as live code, so refactoring essentially boils down to a lot of text search and replace.

Java-land is learning a lot from the other communities and products out there. I have been told the Play Framework (http://www.playframework.org/) has some potential but haven't looked at it yet.

About refactoring ... even if a project is pure-Java, the refactoring-tools are too simple, boiling down to rename class/method/var, extract method/class and things like that which are just too simple for real-world needs (and in practice, kind of useless ... since I've been doing these same ops in dynamic languages with a combination of find / grep / sed / emacs macros... with unit-tests as guard).

When you want to radically change the architecture, as it happens when you've got the business/workflow model wrong, these refactoring tools won't help you.

My opinion about Java ... the JVM and the available tools kick ass, but the language is a PITA and this shows in the design of many Java-libraries. Things like PlayFramework are a wonder and it takes discipline and perseverance to build things like that (not to mention having the will to break every best practice set out by the community).

That is why we make an effort to keep at a minimum anything that breaks strong typing check. I agree that at times it is impossible, but you can keep it at a minimum.

If you are a Java expert and know nothing else, roll with it: learning something significantly different from scratch to a degree comparable with your today's Java expertise will take a long time. That part he got right.

But if your toolbox is bigger to begin with, I see very little advantages in using Java and his arguments aren't persuading: Java is a memory hog (which matters more than CPU cycles in the era of VPS), Java starts slow - it won't allow fluid workflows like Python/Ruby do. Java doesn't interface well with UNIX or anybody else for that matter.

Java-centric libraries and frameworks, while numerous, are tedious to work with: they tend to be over-engineered, overly-relying on XML to an unhealthy degree, hard to navigate and verbose to use.

I am coming from Microsoft/.NET and Ruby/Rails background and even after a year of adjusting, everything in JVM-centric world feels overly complex, slow and "rigid". Java people seem to swim in their own definition of object oriented programming and oh my... they stick with it. Even interviewing "Java-minded" people is painful.

All in all, I am 100% with the anonymous poster he quoted in the beginning of his post: "Its great for consultants because it means more billable hours" Not in a sense that it takes a lot of typing, but simply because there're lots of excuses to bill more for.

> Java is a memory hog

Tomcat with a simple app installed uses about 60 MB when it's idle and not much more with dozens of parallel requests. With Rails you need about 40 MB per instance for a very simple application.

Edit: And Java is lightning fast. An old project of mine running on a tomcat on a crappy VPS with 192 MB RAM serves the home page in about 100 ms, and without any manual caching, although it executes 7 queries to a postgres-db.

A simple rails app which I deployed on a VPS with twice as much RAM takes at least ten times as long to deliver the home page. And the only "dynamic" thing that happens on the home page is the formatting of a date. There is no database involved.

Honest question (I've never done Java web stuff): what does that 60MB actually buy you? Rails gives you a whole lot of tools in that space.

It's hard to compare but Tomcat is functionally equivalent to something like Passenger, Paster or Mongrel. And last time I looked, it actually ate 80MB. It doesn't make sense to compare empty application servers: it is your running application you should be concerned with.

JVM is fine if you're running only a single instance of it: just use threads instead of processes. The problem with JVM is that you often can't afford to have several of them running: in Java world everything is measured in hundreds of megabytes, that's the smallest unit of measurement they use (often supplemented with references to 32GB servers, "they're so cheap now"). Check out Batik Java library for rendering SVG. A single 45Kb SVG file, when fully parsed, eats up 150MB right here on my laptop. After serveral repeated test runs, JVM memory usage grew to a sweet 540MB, where it stopped because I capped it there via -Xmx. For comparison: Inkscape, which is an entire SVG IDE powerhouse, not just a parser, consumes only 3MB more when I open the same file in it, so that's like 50x less, plus it doesn't grow.

See, unlike CLR or Python/Perl/Ruby, JVM truly is a virtual computer, i.e. running a WAR file under Tomcat is kind of like running an Office 2008 inside of an invisible VMWare image with Windows pre-configured to occupy either 500MB or 1GB or comparable number. I just don't get why Java people are so damn proud of it. Moreover, they find nothing strange about this bizarre arrangement because they're completely absorbed by that JVM instance.

To demonstrate why Java doesn't belong on UNIX I invite you to implement find, grep, less and sort as Java programs, pipe them all together in a bash console and enjoy the show. :-)

In the end, there is nothing with Java that can't be dealt with by paying a few extra $ for hosting. The main issue is that JVM is an OS, a much more corporate, boring, uptight and over-engineered (and much less fun) than UNIX is.

I also want to address some of Tobias42 comments: for the most part I absolutely agree with him, except I don't follow his comparisons to Rails: we are comparing platforms here, not languages or frameworks. JVM is a memory hog compared to UNIX, and if he wants to compare Rails, I'd recommend loading his Rails app into JVM via JRuby/Tomcat and seeing what happens to his 192MB VPS box. Moreover, I wouldn't call 100ms/page (i.e. just 10 requests/second) "lightning fast", which makes his next comment about "Rails taking 10x longer" sound a bit strange: how hard does one need to try to build a web application with 1 request/second performance?

> 100ms/page (i.e. just 10 requests/second)

If a page takes 100ms, that doesn't mean you only have 10 requests/second. With a little care you can have thousands of requests per second, especially on top the JVM.

> A single 45Kb SVG file, when fully parsed, eats up 150MB right here on my laptop.

That's not the fault of the JVM, although I do agree that many Java-libraries are memory-hogs.

The only difference between the JVM and CLR/Python/Perl/Ruby is that the JVM doesn't return the used memory to the OS. This means that if the JVM reaches 1 GB of used memory, it will remain there even if the GC kicks. Also, when allocating memory, the JVM has to allocate more memory than it needs because it needs space to degragment the heap. But on the other hand compared to CPython / Ruby MRI / Perl ... the JVM's GC is generational and heap-compacting, making it much more efficient memory-wise for long-running processes ... allocation is cheaper, deallocation is smarter and you won't end-up with a heap that looks like swiss cheese.

If you compare JRuby with MRI Ruby, the memory consumption is indeed higher in JRuby. I am no expert in JRuby but as far as I know, the problem with it is that it can not fully take advantage of threading and thus suffers from similar problems as the MRI + some additional memory overhead.

A Java web application however needs very little additional memory per request-handling thread, which makes its memory footprint much smaller when many parallel requests are involved.

100 ms for the home page in my Java app might not be great but, considering that 7 separate queries to the database are involved and that it runs on a very weak server, I think it is quite decent. And because of the use of concurrency (threading) there is a good chance that 100 ms for a single request translates into more than 10 requests per second. But I still wouldn't call my webapp lightning fast. I was calling java lighning fast because in my case I still get decent response times on bad hardware and with an inefficiently programmed application (7 db requests that could as well be cached and only refreshed every hour or so).

You are absolutely right about the rails app however. The 1 second response time is not normal. I just measured again and suddenly I get similar response times as for the java app. The server must have been under heavy load before (maybe the automatic backup). I admit that my quick measurements are not very representative and apparently not reproducible reliably, but still: about the same response time as the Tomcat with no database activity and on a faster server. I also checked a different rails project of mine running on an equivalent VPS. Pages where two simple database request are involved, which, when directly invoked in psql, take 15 ms, take 300-400 ms to load if not cached.

About the Batik library: What makes you think that it is the JVMs fault that it uses that much memory? It seems much more likely that it is a just a crappy library with lots of memory leaks.

It doesn't give you that much. Servlets (kind of a CGI for Java) and JSPs, which you can use as a simple template engine or to interweave Java and HTML code (kind of like PHP). An ORM is not included for example.

But the point is: If you add additional stuff, the larger part of the memory footprint of that additional stuff is only added once, because you don't need a new Tomcat for every request which you process in parallel, but only a very lightweight thread.

Ok, fair enough. Does that hold true when you load it up with stuff to make it an apples-to-apples comparison, though?

I've got "loaded up" web application running fine in 128M RAM.

(Where "loaded up" equals a lot more than Rails/Django/etc gives you out of the box. We have a separate Tomcat running with a Solr instance for search, but that's for deployment reasons. If we put that in the same Tomcat I might push the RAM up to 192M, but it would probably be fine as it is)

It depends on the number of parallel request you want to handle. I don't know where the break-even in favor of Java is, but I guess it is a low single-digit number of threads.

192 GB of RAM or 192 GB of disk space?

192 MB RAM. Sorry, I corrected the typo.

So very true.

Since learning Ruby, I've noticed that my attitude towards Java has taken a complete 180. It feels like doing anything in Java is like mowing your lawn with a pair of hand scissors. You can get the job done, but it takes a lot of extra steps/effort when compared to more powerful programming languages.

I don't think that the majority of people who are using something else besides Java to build their web app are doing so just because they read some Java-bashing statements on a website. They're either basing their technology choices on prior experience or are just picking something that appeals to them and rolling with that.

And of course the point is that there is nothing in the nature of the language and tools that forces you to use complex solutions.

While it is definitely true that there is nothing in the nature of Java that forces you to use the kind of complex solutions often foisted on Java programmers, there definitely is something in the nature of Java that leads to needlessly complex code and heavyweight patterns that are not needed at all in more powerful languages.

To me this article just seems like a justification to use Java where none is needed. You can do a startup in any language, and the best one is the one your dev team is most proficient with. Java is the 500-lb gorilla these days and doesn't need any advocacy.

"We should all be grateful to the dynamic language communities, that with their repeated successes have shown that the "king is naked" and self-referential practices of formal code quality or blind following of methodologies valid for over-ruled corporations are useless advice in many environments, and that a more socially oriented testing and user interface design is what wins for creating online services. But I believe the development language involved is accidental."

It's possible that English is not the OP's first language, but even with this in mind nothing in this article makes any sense.

Actually it makes alot of sense. He's saying that the quality and innovation of what you're building is what is important, not the fact that you're using the newest framework. By using a mature language/environment/community you'll be able to spend more time on your real problem and less on reinventing the wheel.

It's a good point. Frameworks like Rails have had a big influence on the Java ecosystem (Spring MVC, Grails, AppFuse), which goes to show you that it's not Java -the language- that would prevent a startup from considering Java, but rather the enterprisey, overengineered Java frameworks that haven't evolved.

actually his core argument is completely true. There is nothing in java the language that makes it heavy or verbose. The libraries and frameworks associated with java make it seem that way. But there is no reason you can't write fast lean and clean java code. Since doing java regularly I've concluded that java the language doesn't suck. But a lot of java's apis and frameworks do. That's an important distinction to keep in mind.

No, the language itself forces you to be verbose, and the libraries follow. Yegge's "Kingdom of Nouns" makes the point well.

Agree to disagree.

Nothing in the language forces verboseness for the sake of verboseness.

Classes and methods aren't objects, no closures, clunky collection APIs and no collection literals, impedance mismatch between primitives and arrays and objects, no default interface implementations, incredibly convoluted syntax for generics, etc, etc. Most of which could be fixed with minor changes, but because Java is so entrenched in the enterprise, backwards compatibility trumps everything.

Do you consider boilerplate to be verbosity? Because I don't.

Verbosity is a bad thing, because it can cause bugs etc. But that's not what Java is.

"private static void" is just boilerplate. It's stuff you type to get what you want, but it can't really be considered verbosity.

Then we have different definitions of verbosity.

Thanks for the (verbose... kidding!) explanation.


Not verbose:

    puts "Hello, world"

    public class Hello {
        public static void main(String[] args) {
            System.out.println("Hello, world!");

See I read those two code snippets exactly the same.

The 'verbose' one, I read as ...println("Hello, world!")...

Perhaps I'm not normal, but I 'see' those code snippets to be identical in terms of code.

Lets face it, we're never going to be bound by typing speed, and as I say, there's no chance of getting a bug into that 'verbosity' in java. So the only real issue is down to taste, which is up to the individual.

It's more about the reading than the writing. All of the extra words interfere with what's actually going on. Even in this most minimal of cases, there's so many extra things to read that it obscures the meaning.

Also, have you seen those studies that show that everyone has a number n, and every n lines, you make an error? If you're writing 3n lines in Java for every n lines you write in $LANGUAGE, you're making 3 times the errors.

That study, is absolute BS. Complete and utter BS.

Try and make an 'error' in the phrase 'public static void'. See how well it compiles if you mistype 'public' as 'pubic'.

If you're not able to read the code well, then that's one thing (Learn to read code better). But don't spread the misinformation about errors. And no. You're not writing 3 times as much code unless you're an idiot. LOC in Java is pretty much the same as LOC in python for example when written properly.

I can't actually find a link to the study in the 5 minutes before work, so I guess we'll have to throw that out.

It's not that you'd make errors in typing, of course your compiler will check those. It's that code you don't write is bug-free, and every line you do write has a non-zero chance of containing a logic (not syntax) error...

But anyway, it's very easy to write 3x LOC in Java. If you don't write much smaller Python code, you don't know how to code in Python. I can't think of a single task (mind you, I'm a Rubyist, so I very well could be wrong) that would take less in Java, and even ones with identical LOC, you still have things like

    BufferedReader myFile = new BufferedReader(new FileReader(argFilename));

    myFile = open(argFilename)

our example is an api not a language issue though. Theoretically you could create an equivalent api to your open(filename) example. There is no reason you can't and thus the API vs Language point my post was actually about.

Orangecat, I actually agree with your remark. I just believe that these defects of the language are not great obstacles for building today new online services.

public static void blah blah blah...

That is categorically NOT verbosity.

"public static void" has zero chance of containing errors. If you make a typo, it won't compile. It's not code, it's just "stuff". It doesn't translate to code. It doesn't "do" anything.

If you really can't learn to look past the "stuff" into the code, get your editor to hide it from you if you must.

Using "public static void" as an argument is almost as ridiculous as people who cite the lines of code needed to program HelloWorld.

Verbosity in a language should be measured in terms of actual code that does stuff. Not characters in source code.

For example, would you consider Basic with line numbers to be a verbose language since it has a number at the start of each line? Well no, because those numbers aren't code.

Another example:

Regexps are extremely terse and compact. Would you rather debug regexps, or java code? Which is easier to work with? Is it easier to make a mistake and introduce a bug in a regexp, or in java code?

The argument that less lines/characters = less bugs is not a good one.

"public static void" has zero chance of containing errors. If you make a typo, it won't compile. It's not code, it's just "stuff". It doesn't translate to code. It doesn't "do" anything.

It is verbosity. It's less harmful than some other instances because as you note it's extremely unlikely to cause bugs, but it's still noise that detracts from readability by obscuring the code that's actually relevant to the task at hand.

Would you rather debug regexps, or java code? Which is easier to work with?

If the regexp is expressing a concept that would otherwise take 20 lines of ad-hoc string processing in Java, I'll take the regexp.

That's why I said "Agree to disagree".

If I'm looking at code, the "public static void" doesn't detract from readability at all. I would much rather see "public static void" than some new 'less verbose' &$%||foo|| stuff I have to look up. I find it much easier to read words than characters.

It's a wonder anything works in some of these new 'unverbose' languages, where a 'concept' is a single character, and a single char typo can mean you've suddenly got a bug you have to go find.

    1 : containing more words than necessary
      : wordy <a verbose reply>; also
      : impaired by wordiness <a verbose style>
    2 : given to wordiness <a verbose orator>
The word has a definition and you're either ignoring it to suit your point of view, or you don't know what it means.

If you want to argue that there are good kinds of verbosity and bad kinds that's fine, but don't try to make up your own definition and expect anyone to buy it.

In the realm of programming, I consider 'word' to mean a unit of code.

I agree though, it's perhaps not the best word to use.

Use what you enjoy using though. But please don't buy the FUD about verbosity.

The regular expression example makes no sense for me. A regexp is a very specialized way of express what a pattern must match, opossed to a java code that express how to perform the matching.

You don't regexp's compact syntax. That's fine. You would have a point if you say that its more readable, let's say:

   1: EXACT <a>(3)
   3: PLUS(15)
   4:   ANYOF[ab](0)
  15: OPEN1(17)
  17:   EXACT <cd>(19)
  19:   CURLY {0,1}(23)
  21:     EXACT <s>(0)
  23: CLOSE1(25)
  25: END(0)


but it's much easier to introduce a bug in 20 lines of Java code that deals with an ad-hoc parsing than in a regexp, specially if you have to change the pattern.

This is quite a well-argued post with decent examples. A point well worth repeating.

Mature language and tools, stable and "fast execution", clean interaction with popular services. Its not sexy but if you are competent enough - it can get the job done and get it done fast.

Wasn't it obvious? I mean, this is applicable for almost any language, let it be C++, ASP, TCL or whatever isn't considered trendy anymore but it's proven and stable, and isn't completely unsuited for the task(COBOL, 4GL, RPG...)

Takes at the very least a year to became proficient in any language, and spending that time learning about your tools, that's is a luxury a startup doesn't have. Wasn't it pure common sense?


Isn't this based on the questionable assumption one can be as productive with Java web frameworks as they would be with, say, Rails or Django?

Wouldn't the cost of learning a more productive (assuming the initial supposition is incorrect and that there is a difference of productivity between technologies) framework be diluted in the total lifetime of the product?

If all you have in your toolbox is a blunt axe, wouldn't it make sense to get a sharper one before you attack the forest?

In the end, it all depends on the lifetime of the product. If it's a one iteration release, then go with whatever you already know that solves the problem. If the lifetime of the product tends to infinity, go with the language that expresses the product in the most concise way and manage to learn it well. The vast gray area between these points is where you can place all those fancy languages and frameworks wherever your expertise and product dictate.

One common theme I learned when working with Java developers is that there are vast amount of information out there regarding:

* Design Patterns (GoF + newer patterns) * OOAD/OOP * Refactoring * TDD, Agile, and XP * "Reusable", "Generalization", "Framework"

that Java developers read the topics lightly and apply immediately without taking the time to understand them and when to use them. This doesn't happen much in other programming language communities because I rarely see someone writing design pattern tutorial in Perl. I won't be surprised that we will see these issues again in Ruby...

well, this generalization is a little out of left field, I suggest you go read Zed Shaw's post about rails is a ghetto http://www.zedshaw.com/rants/rails_is_a_ghetto.html

although there are improvements, its still relevant

but this is history, boring, and by now not very interesting

So it is in the past, boring, and in the past and boring. OK.

Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | DMCA | Apply to YC | Contact