Part of the answer is Java itself. It's verbose, static typed, and requires a lot of boilerplate code to do properly. The fact that classes are a compile-time concern, rather than a runtime concern, is just such a drag. You end up with interfaces you don't really need, only so that you can inject them into constructors so that your app is properly decoupled and testable.
Part of it is a framework issue. Struts is horrible...absolutely, stunningly horrible. Your controller is an XML file (seriously). Freemarker (the main templating language) makes ColdFusion look awesome.
Play is better, but it seems built for the way websites were created in mid-2000. JSON is still a second-class citizen. Static actions are a weird choice given IoC is achieved via DI in a static language.
Edit: I should add that there's also the persistence story. Anyone who's done [n]Hibernate knows that it's, at best, a mixed blessing. Even Java's NoSQL drivers are verbose compared to their dynamic brothers (first-class hash support is a big issue here, for some drivers in particular). I'm not sure something like Sequel would even be possible to write, and the AR implementations are, again, limited by the compiled-time nature of the language and the inability of bend the syntax into a nice DSL.
Java also lacks lambdas, and generic support is weak. And what's up with int vs Integer...the list goes on and on.
I think you need to reconsider your views regarding play. Version 2.0 has been a major improvement regarding a lot of issues. Asynchronous Requests are inbuilt as well as Websockets. (And Json serialization is as easy as Json.toJson())
I agree that static controllers are not always ideal considering that Java does not support inheritance of static methods, but the arguments of why static controllers are chosen can be found here: http://stackoverflow.com/a/5193721/616974
Still I think that developing with the play framework is a very productive process and can be compared with the likes of ror/django etc with the benefits of type safety all the way (including the templates)
I did look at 2.0 when it came out, and I'm under the impression that you still need to write a custom binder. Just now I tried to look it up, but the documentation points to:
...and that is why the latest generation of JVM languages such as Scala, Clojure and Groovy are so popular. Java the platform is extremely stable, highly optimized and heavily instrumented. Java is much less verbose than C++ (the main alternative when it was released), but the times have moved on.
With Scala statically typed and verbose are not synonymous. Statically typed = high performance. Type inference and compact syntax = expressive. Best of both worlds. Languages like Ruby bring expressive syntax, but performance suffers. Performance is becoming increasingly important with mobile applications, one of many reasons Ruby adoption has stagnated since the end of 2010 (see open source contribution and indeed.com charts).
There's no advantage to the need to over-architect. It's purely a bi-product of Java (or static languages in general). Because you can figure out how to properly write a Java program doesn't make you clever, sorry.
C/C++ programmers moaned about Java and garbage collectors the same way Java programmers are moaning about dynamic language.
Static languages have some advantages. It's not quite the same thing (Perl being dynamic and all) but I have gone towards Moose in Perl which gives some of the things I see as advantages of static languages (such as the ability to engineer in constraints declaratively, assuming those are enforced by the language. SQL is great this way.)
The real reason to use languages like C and C++ is performance. The reason for dynamic languages is rapid prototyping. Java is somewhere in the middle but not really ideal except for where you want to compile your software to run on an imaginary CPU which can be emulated everywhere :-)
I'm not saying they don't have their advantages. I want to be clear about that. But for most web apps, the limitations probably outnumber the benefits. Especially since the stateless nature of most web apps allow for easy horizontal scaling, thus negating the performance advantage.
As for performance, it really is amazing how fast node.js is. It's like a slow static language rather than a fast dynamic language (by that I mean, the gap between it and Java is smaller than the gab between it and Python). I don't know why that is, but I hope every dynamic language has that potential and that someone manages to unlock it.
I think there is a more fundamental reason. Java, being a compiled language that has traditionally aimed at compile once, run anywhere, offers a significant overhead, but with a development speed of a compiled language. It may or may not be faster to write code in Java vs C++, but it's certainly way faster to write code in Perl, Python, or Ruby.
I have always felt that Java was ill-suited to web applications generally, and that the main advantage of using it for web apps was being able to make use of third party libraries written in it. In this regard it's kind of like "why would you write your web app using DCOM on Windows?" Well, maybe because you are recycling VB logic from desktop apps?
> So basically, it's due to lazy programmers who moan if they have to type or think too hard.
Typing is a problem. Thinking too hard? Where does the OP imply he is averse to thinking? Being turned off that "fucking XML files are controllers" is being averse to thinking?
> Also very very much fashion lead by hipsters who must be using the newest coolest untested thing on the planet.
And those untested things would be? Rails is untested? Or Django? Or Flask?
XML has absolutely nothing whatsoever to do with Java the language. Some frameworks might use XML. There might be some built in functions/objects that deal with XML. But that doesn't mean you have to use XML. I certainly haven't in the 12 years I've been using Java.
> XML has absolutely nothing whatsoever to do with Java the language.
Weren't we talking about what OP said, and how per you, it's being averse to thinking?
> Part of it is a framework issue. Struts is horrible...absolutely, stunningly horrible. Your controller is an XML file (seriously). Freemarker (the main templating language) makes ColdFusion look awesome.
Now if some framework has achieved this level of retardation, I would rather not think about it. There are better things to think about. I would be absolutely fine being averse to thinking about it.
The OP asked why Java isn't used for the web. One of the more popular Java web frameworks heavily relies on XML. It has nothing to do with Java, but it has everything to do with what the OP asked about.
You can have a pretty good Java web server going in about 200 lines of code.
No, you can't.
Your "simple HTTP server" proposal is roughly on a par with suggesting that a web developer should design his own security protocols. The idea is simple enough, but there is a lot of subtlety involved in covering all the edges cases properly, and a lot of very smart people have spent a lot of time building, testing and maintaining good tools for these jobs. Why would you reinvent the wheel, with a flat edge across part of it, a single spoke connecting to the axel, and in only one size that won't be the one that fits under the arch next week anyway?
XML may have nothing to do with Java, but some Java frameworks (e.g. Spring) are obsessed with it. Many (most?) Java devs don't even like Spring. Who in their right mind would want to write code to call constructors in XML? no type checking, no refactoring support etc.
I suspect the main reason Java became XML obsessed is because MS came out with C# and bragged about their XML and web services support. Ever since then Javaland has gone out of it's way to prove it was more XML and webservice centric. Net result is Java devs writing XML instead of code.
Actually, with Java, I type more than I think. A lot more.
Compare this to Haskell, where a single keyword might involve substantial thought, or APL, where one character more or less could represent a pretty fundamental restructuring of part of the program.
That Java makes you repeat yourself is not controversial. That being averse to this means you dislike thought is a somewhat bizarre position to hold.
> That Java makes you repeat yourself is not controversial. That being averse to this means you dislike thought is a somewhat bizarre position to hold.
The English language makes you repeat yourself. I don't see it as a bottleneck. I've never considered <speed of typing> a bottleneck to programming. possibly when programming some assembly routines. But if you're typing too much, you're probably repeating yourself too much, which means you're doing something wrong.
Things that can be libraries in other languages end up being "design patterns" in Java. It's just not flexible enouth, both Ruby and Haskell are more flexible than it. Both in different ways.
In Java, I type too much every time I have to deal with the fact int and Integer are two different types. That's a design flaw in Java, not in anything I've ever written using Java. And that's just a trivial example off the top of my head.
> why does a language designed around an OOP perspective need a lambda
Because only through lambdas can you actually do OOP: a core of OOP is to tell objects to do things. That you can do with lambdas, through customizing "the thing". Without lambdas, you are left with the requirement to painfully and painstakingly get bits and pieces in or out of objects in order to do the thing yourself, ending up with a horrendously procedural language with a smattering of objects added on top.
Now think of how to write that code not using lambdas.
In Java where people seem to like typing unnecessary stuff it would make sense to not have lambdas as then you can type extra stuff. Also lambdas would reduce KLOCs thus making teams using java with lambdas less productive.
This is similar to the reduced productivity seen by teams using scala or clojure on the JVM.
Also, OOP has nothing to do with procedural or functional languages, it's completely orthogonal.
Purity is orthogonal to lambda abstractions. It's matter of what function can do (pure or not) and function creation (a lambda or something more verbose).
>Part of it is a framework issue. Struts is horrible...absolutely, stunningly horrible. Your controller is an XML file (seriously). Freemarker (the main templating language) makes ColdFusion look awesome.
Play is better, but it seems built for the way websites were created in mid-2000. JSON is still a second-class citizen. Static actions are a weird choice given IoC is achieved via DI in a static language.
99% of websites are still built "the way they were built in mid-2000", and there's nothing wrong with that way.
Client-side rendering and such is not the "new way", is just an alternative way for certain types of websites, that is still quite immature and can take you to a world of pain if done bad (see Twitter).
My complaint isn't about client-side rendering. It's about _anything_ that involves getting in JSON or outputting JSON. It's essentially being able to easily bind json to objects on the way in, and being able to use respond_to and to_json on the way out.
"public static void main()" isn't a lot of code. It's three keywords, and one identifier. You may consider it a lot of characters, but it's pretty rare that a programmers bottleneck is speed of typing.
I wish people would stop confusing "number of characters" with "amount of code".
And FWIW, I find your example far harder to decipher. I have to know what => means, # means, what : means, etc etc etc.
Add to that, in your example, if you typo one of those characters, your code may well still run, but will fail. With Java, if you typo a single character, it's more likely the code just won't compile.
We could all code in regular expressions or something akin to that, maybe perl one liners. But "number of characters" isn't a good aim. Readable, maintainable, well written code is.
The last part of your comment is just language bias. symbols and hashes are fundamental to ruby. Why would I use string concatenation like my parent, when the language support string interpolation. It's as unclear to you as generics or annotations might be to someone who didn't know Java. Surely you see that?
I think you are being pedantic about characters vs code. But, for what it's worth, I disagree. You are having to create 2 classes, define a field, a constructor and use four framework specific annotation. I consider all of that code (made up of characters).
Both versions should be unit tested. The unit test might be more important in the Ruby version, but so too will it be easier to write.
I grew up reading assembly code listings. Being able to read code is a really really important skill IMHO. Something like Java is very very easy to read. It's mainly keyword based, rather than special character based. I'd much rather read a 1,000 line Java program, than a 100 line <concise language> program.
The other point I'd make is that Java is probably about as verbose as english is. But we all manage, using English. We don't moan on and on that talking, writing, reading is so inefficient and we should all switch to something better. English also has odd grammar and spelling rules which are inconsistent and plain stupid sometimes. Yet, English works pretty well for what we use it for. Communicating.
You'd much rather read a Java program because you are already biased towards it. Yes it's easy to read, but you need to acknowledge that many other skilled developers would find it easier to read Python, or Ruby, and indeed would rather read 1,000 lines of the same over 100 lines of Java. Otherwise you are simply being willfully ignorant.
Why is Java considered inefficient and English not? Maybe because we don't need to create a new class for every concept in English. Yours is a pretty poor analogy; English vocabulary is extensive but it is not inherently verbose.
Anyway I am only writing not to say you are wrong, but rather, since other people are arguing with you reasonably and you are dismissing them without consideration, your argumentation is wrong.
"An unordered tuple Z going from a1 to an is a defined as for every x in Z then x is a1 or x is a2 ... or x is an"
than
"An unordered tuple Z (a1,...,an) is defined as [x : x = a1 v x = a2 v ... x = an]"?
I take that as not being (or not wanting to be) familiar with the language you are reading. If you'll read Ruby, at least browse a manual to know what {} and # mean.
The psuedo-Ruby code posted there is characteristic of someone who is having a knee-jerk reaction against something they don't understand. The person we are arguing against is obviously a Java zealot that will never consider using another language, so as long as he's going to accept that different people like different languages I think that's good enough for today.
The other point I'd make is that Java is probably about as verbose as english is. But we all manage, using English. We don't moan on and on that talking, writing, reading is so inefficient and we should all switch to something better.
You've made this argument in multiple posts now, so I'm just going to point out here that people doing science and engineering use formal, mathematical notations precisely because they do offer more precise and concise ways of expressing the necessary technical concepts.
There are plenty of reasons to criticise some of those notations with hindsight, but "not being English" is not among them.
This is just a sad Stokholm defence - against languages that threatens your sacred cow - which is understandable since the Java code example got pwned.
So rather than defending the code example on merit, you dive into pedantic nit-picking territory. I used to be defensive about my choice language as well, till I matured and realized holding onto sacred cows just hurts your ability to learn from others doing it better and being more productive; and just clouds your ability to choose the right tool for the job.
More code = more code, to read, to decipher, that hides intent, that adds complexity, that can have bugs and can go wrong. Code-size is codes worst enemy.
I don't even know Ruby, but it's implementation is vastly more readable and would look a lot closer to what the perfect DSL would look like for this task, than the Java example.
The sibling comments point out some good points about your general critique, but it's worth noting your code isn't really "equivalent"; almost everything you chopped was a datatype declaration, which isn't required in Java any more than in Ruby:
@GET
public Map<String,String> greet(@PathParam("name") String name) {
return singletonMap( "content", "Hello, " + name );
}
I like both of these systems, and Java is undeniably the more verbose language, but this framework really isn't an egregious example of that.
I've been trying to ignore this particular flame-war, but your example is doing fundamentally less, because it's not binding objects to json (which was what you originally asked for).
I actually cannot write your example easily in Sinatra/Ruby/etc, without making my object either a Hash or an ORM subclass, customizing serialization, or pulling in uncommon libraries.
Here's your complete example, in reasonable Ruby. It's longer than the Java.
class Greeting < Struct.new(:content)
def content
"Hello, #{super.content}"
end
def to_xml
{:content => content}.to_xml
end
def to_json
{:content => content}.to_json
end
end
get '/hello' do
response = { :content => Greeting.new(params[:name]) }
respond_to do |wants|
wants.json { response.to_json }
wants.xml { response.to_xml }
end
end
If I create an imaginary library that does exactly what we'd want here, it'd look like the following. It's marginally shorter than the java, but hard to argue anything about it being fundamentally better.
class Greeting
include JsonObject
field :content
def content
"Hello, #{@content}"
end
end
get '/hello' do
response = { :content => Greeting.new(params[:name]) }
respond_to do |wants|
wants.json { response.to_json }
wants.xml { response.to_xml }
end
end
That's a funny complaint when evaluating 4 lines of code one of which is end.
Java makes the assumption that you need a lot of boilerplate code, so being able to make changes easily seems like a big deal. Other languages avoid that boilerplate and can make the changes just as easily for free.
Making changes to a complex system is a "big deal" in any language. Pretty (and compact) syntax doesn't help much, especially when the refactoring tools are weak.
Its fine code once the design its settled, but while you're changing the schema, the backend java code and the frontend javascript, having to change all those classes gets tedious.
I spent three long years doing Big Freaking Enterprise Java web apps. You can certainly do modern web dev in a Java stack (we were Struts, Hibernate, Spring, and an internal framework). It just fought us every single step of the way, and every time we had to do something new (that couldn't be templates off of working code) they'd have to get one of our three best engineers to spend a week fighting the new library into submission. Sometimes the libraries won.
The easiest way I can describe it is that everything you like about e.g. Rails was designed as a specific dig against the Java stack. I am told Play is less painful.
On the plus side: Java devs are plentiful, the library support is worlds deeper than the ruby ecosystem (particular around enterprise-y needs), and it plays well with teams of dozens (which you will probably need). I honestly think "restricts your developers terribly" is not a bug for typical Java projects, since the outsourcing shops contributing lots of our code base would have been even more dangerous if the code didn't restrict what modules thy could break.
Incidentally, the bit about many of Rails' features being a dig at Java isn't poetic license. Rails' original marketing angle was essentially "Look how different we are from Java!"
I think that's why the difficulty of deploying Rails apps in those days wasn't much of an obstacle — they positioned themselves not against PHP or Perl, but against Java, so the difficulty of deployment didn't look like so bad.
I've been hacking Rails since 2004, and I've made the switch to Java (dropwizard+mustache) for basic web development this year (sometimes with a meteor-like micro-framework I rolled myself).
Benefits:
- Higher quality code. Java is easier to refactor than Ruby, which makes up for the lower language power.
- Performance!
- Actual concurrency!
- Faster server spinup and incremental changes. Rails with 20 gems in development mode is super sluggish.
- Better library ecosystem!
- Better dependency management system (maven > rubygems)
- Better debuggers
- Better profilers
- Easier deployment and ops environment(java -jar myjar, vs bundle install, ruby/passenger/unicorns)
I'm kinda testing the same setup. There are a couple nice things, but one thing that hurts me coming from Python is that in Python an SQL row was just an dict with data, and I could change my schema (and add/remove entries from this object) and then return it as JSON quite easily.
Now in Java/Dropwizard the tendency is to map from SQL rows to objects, then from objects to JSON. Which is a PITA, even more when your design/database changes too much. (The upside is that when you get some object, the data IS there).
I tend to work more with document-like stores than SQL these days, so there may be more idiomatic solutions....
If you're complaining about having to update the fields in your object, I think thats kinda silly. You bought into the idea of static typing at some point, and now your data has type constraints. If you need need need flexibility you can of course make some field a Map<String, Object>.
If you're complaining about boilerplate, you can at least automate the mapping with code like:
class Util {
public static <T> T resultSetToObject(ResultSet rs, Class<T> klass) {
List<Map<String, Object>> rows = new ArrayList<Map<String, Object>>();
ResultSetMetaData metaData = resultSet.getMetaData();
int columnCount = metaData.getColumnCount();
while (resultSet.next()) {
Map<String, Object> columns = new LinkedHashMap<String, Object>();
for (int i = 1; i <= columnCount; i++) {
columns.put(metaData.getColumnLabel(i), resultSet.getObject(i));
}
rows.add(columns);
}
return new ObjectMapper().convertValue(rows, klass)
}
}
> Higher quality code. Java is easier to refactor than Ruby, which makes up for the lower language power.
Let me rephrase:
"It's easier in Java to rename identifiers than ruby, because my IDE does it for me."
Now that's fine, but I don't see how do you conclude:
Easier to rename identifiers => Higher quality code. How on earth?
Easier to rename identifiers => Makes up for lower language power. What language deficiencies does renaming identifiers make up for?
Other than renaming(which can be done for ruby, though it requires manual effort), there is no refactoring which Java does better than Ruby.
> Actual concurrency!
Am curious. Where in basic web development does concurrency help? As far as servers go, evented servers(thin, mongrel) will perform as good as, if not better, than a threaded server. And evented servers can handle much more concurrent requests than threaded servers.
As far as concurrency at language level goes, very rarely have I needed to spawn a thread(I go for gevent) in the controller. Controller's job is to dispatch ASAP - everything else goes in the queue where you use EventMachine or gevent or whatever if you need concurrent processing.
> Faster server spinup and incremental changes. Rails with 20 gems in development mode is super sluggish.
Rails is more sluggish compared to "stop the world. I am compiling" Eclipse?
As long as we are just throwing out claims without backing them, ruby library and bundler/gem are 1000x better than mvn.
> Better debuggers
> Better profilers
Not everyone is a fan of graphical everything. Going by this line of reasoning, Windows has better support for git because gui?
> Easier deployment and ops environment(java -jar myjar, vs bundle install, ruby/passenger/unicorns)
`java -jar myjar` starts your app server, your web server, minifies your css, js, migrates the db....? You can very well bundle the dependencies along with your app for rails, but I don't see why I would do it for a webapp. Also, your jar works only when you don't have java calling into native code. If you don't have native extensions, ruby is platform independent as well(i.e can be bundled).
Your Java IDE also lets you move methods and fields, extract interfaces from concrete classes, push members up or down, find all references to a member (reliably), view inheritance relationships, and much more. And it can do all of those safely, warning you if you'll shadow another name. I wish I had that stuff in a Ruby IDE.
I've used Eclipse for a long time, but not for JEE projects, and I don't see any "stop the world" behavior when it's compiling Java. Java compile jobs run at a low priority and rarely block another workspace job. If you want to save a file that's being compiled, Eclipse will let you and restart the build. Maybe you mean "stop the world I'm launching a JEE app?"
> Your Java IDE also lets you move methods and fields, extract interfaces from concrete classes, push members up or down, find all references to a member (reliably), view inheritance relationships, and much more. And it can do all of those safely, warning you if you'll shadow another name. I wish I had that stuff in a Ruby IDE.
Some of it isn't applicable to Ruby, and some of it has to be done manually. True that you will have to rely on tests or something to make sure you didn't shadow anything, or you renamed at all places, or you didn't rename something which shouldn't have been renamed.
> I've used Eclipse for a long time, but not for JEE projects, and I don't see any "stop the world" behavior when it's compiling Java
What machine do you use? I was using a 4 gigs, dual core machine, and eclipse regularly stalled while compiling and launching.
I'm usually in a 64-bit Linux VM (in VMware Workstation) on a 4 core i5 Xeon from about 3 years ago. 5 GB RAM total, Oracle Java 7 with -Xmx800M for Eclipse. My workspace includes 50 projects, most of them are Eclipse plug-ins themselves.
In my experience, if Eclipse "stops the world", Java is collecting garbage. Java 6 and 7 have become much better at doing incremental collection more often (maybe parallel is the default now?) and the result is a more responsive UI. To me, Eclipse itself feels snappier over time (each release from 3.3 to 3.7 has felt better on similar hardware).
Another thing I've noticed is that Eclipse is significantly faster cleaning/building large workspaces on Linux compared to Windows on the same hardware. I assume this is a result of Linux's aggressive filesystem caching.
''Am curious. Where in basic web development does concurrency help? As far as servers go, evented servers(thin, mongrel) will perform as good as, if not better, than a threaded server. And evented servers can handle much more concurrent requests than threaded servers.''
I don't know what is 'basic web development', but the argument 'why do we need concurrency if I rarely use it' doesn't work. I mean if you are a front-end developer/designer and mess with CSS/JS/HTML all day (without format CS education), you are probably wondering why concurrency even exists, but in real-world programming you can't go far without it.
The type of web development where your controller renders a page. BTW I was quoting OP, where he mentioned he uses Java for basic web development.
> I mean if you are a front-end developer/designer and mess with CSS/JS/HTML all day (without format CS education), you are probably wondering why concurrency even exists, but in real-world programming you can't go far without it.
I said evented servers out-perform threaded servers. Threaded servers will eat more RAM and have higher cost of context switching. As far as application code goes, your controller isn't supposed to spawn threads(at least mine doesn't). The heavy-lifting should be done by the background services, and you can very well do concurrency in Ruby/Python(EventMachine, gevent). Generally, threaded code doesn't cut it where number of threads are large.
And I am pointing this out for the second time. You ignored it all and went on a tangential regarding how I am a frontend developer/designer without formal cs education, and am wondering why concurrency even exists.
> but in real-world programming you can't go far without it.
Yay. No true scottsman. All programming is real world programming, and you can go far without concurrency. Are templating engines real-world programming per your certification institute?
""Yay. No true scottsman. All programming is real world programming, and you can go far without concurrency. Are templating engines real-world programming per your certification institute?""
Oh yes, part of the real-world where concurrency (via threads) is the core of the system, not some niche sub-technology like 'slow templating PHP engine'.
Now we are not talking about events vs threads, I still can't understand why someone should be stopping from starting a thread in any point of code, front-end or back-end.
""As far as concurrency at language level goes, very rarely have I needed to spawn a thread(I go for gevent) in the controller. Controller's job is to dispatch ASAP - everything else goes in the queue where you use EventMachine or gevent or whatever if you need concurrent processing.""
If your language of choice is bad at threads (and threads are hard to implement, hard to use, hard to debug, we know that) then you are lucky you can use something else to hack your way out. But to push it as a normal standard way of doing things... what for? Java is great at concurrency. It also has 'event' frameworks for those who really need it for some very specific use-cases like networking (netty, grizzly,something from apache, etc ). For the majority of us? Threads do just fine...
> Oh yes, part of the real-world where concurrency (via threads) is the core of the system, not some niche sub-technology like 'slow templating PHP engine'.
Your claim was "you can't go far without threads in real world programming" which is now "real world programming where concurrency is the core of the system". Does it need to be said that you won't go far without concurrency in a system which needs concurrency? Isn't that a tautology?
And I wasn't referring to PHP. I was referring to Jinja2. Jinja2 is neither slow nor simple, but that's tangential. What if it's slow? Adding threads will do shit as far as rendering templates is concerned.
> Now we are not talking about events vs threads,
I don't care about events vs threads. I care about throughput(parallelism - make 5 dns requests in shortest span of time) or co-ordinating processes(spell checker thread while I type). Processes, threads, events are all implementation details.
> I still can't understand why someone should be stopping from starting a thread in any point of code, front-end or back-end.
So you are twitter. I post a tweet. I have 1500 followers. Your cute little java process spawns 1500 threads to update the timeline for my 1500 followers, and I am waiting at my browser watching the loading git. How about 15000 followers? 150000?
A controllers job is to return ASAP. Spawn threads all you want. Nobody is stopping you. I was talking about why you don't want that.
> If your language of choice is bad at threads (and threads are hard to implement, hard to use, hard to debug, we know that) then you are lucky you can use something else to hack your way out.
For the second time, I don't care about threads. Processes, threads, events, agents, transactions with STM - whatever it is doesn't matter as long as I can get the job done.
> But to push it as a normal standard way of doing things... what for?
I am not pushing it as normal standard of doing things. For the tasks I generally write, threads won't cut it(Java or no java). Take 1000 threads on a 4 core machine - we will have (memory per thread) * 1000 ram usage, 1000 threads contending for execution on 4 cores. Threads work fine for small values of n, and even for small values for n, threads itself come with a lot of baggage and extra care has to be taken to ensure correctness.
> It also has 'event' frameworks for those who really need it for some very specific use-cases like networking (netty, grizzly,something from apache, etc ).
You are responding to claims I didn't make. I didn't say Java is bad at concurrency or Java doesn't have evented frameworks.
I've used both Java and Ruby and Java is by far the more advanced runtime with better support. Ruby may have much cleaner syntax than Java, but better tooling is NOT one of Ruby's strengths.
Reading your post I suspect you've had very little exposure outside of Ruby.
> Reading your post I suspect you've had very little exposure outside of Ruby.
Reading your post, I see that you just throw claims around.
> I've used both Java and Ruby
Congratulations. You aren't the first or the only one.
> Java is by far the more advanced runtime with better support.
There are a lot of good things about JVM. I never contended that.
> but better tooling is NOT one of Ruby's strengths.
I don't remember saying it. I said "easier to refactor => high quality code" or "mvn is better at dependency management than bundler/gem"...is bullshit.
On a large project the ability to refactor is important. Making structural changes to a large Ruby project is extremely time consuming and error prone. Pretty much anything is better at dependency management than bundler/gem. If you have to compile your dependencies at install time you're probably doing something wrong. Not to mention the version incompatibilities between gem versions and syntax changes.
> Making structural changes to a large Ruby project
Only the structural changes which are some form of rename. Refactoring is more than renaming. What eclipse provide is a very limited form of refactoring. Most of the refactoring is to be done by the programmer and can't be done by the IDE.
> Pretty much anything is better at dependency management than bundler/gem.
Yeah. How so?
> If you have to compile your dependencies at install time you're probably doing something wrong.
1. There is no compilation when the code is ruby.
2. When there are native extensions, the compilation is required. Dev platform isn't the same as production most of the times, and precompiled so can't be bundled up.
3. If there are only ruby dependencies, `bundle package` will pack them in vendor/cache and next `bundle install` will install from the cache.
> Not to mention the version incompatibilities between gem versions and syntax changes.
How has this got to do with anything? I am maintaining a gem. In this version, it does pagination. In next version, it will delete your home directory. Version compatibility you say? Go cry me a river. What is bundler supposed to do? Does maven stop me from doing this?
That doesn't mean that Ruby is so compact that it's impossible to get a large code base in it. When Ruby projects get large making changes to the code is both painful and scary (I would know since I've had to do just that).
Is your codebase well covered by tests? Do they still run after the change? Did you write tests for the change you just made (preferably before the change)? If you answered yes to all these questions, fear not. You are every bit as covered than you'd be with a Java codebase and you probably have the afternoon for code review.
>> Other than renaming(which can be done for ruby, though it requires manual effort), there is no refactoring which Java does better than Ruby.
Perhaps you could name this mysterious IDE which you claim provides reliable refactoring support for Ruby which is equivalent to the refactorings provided by Java IDEs? RubyMine is the best one I've seen http://www.jetbrains.com/ruby/features/index.html, but it doesn't match what can be done in Java.
The JVM is very fast to start on my machines. For Java 7 on Linux x86_64:
t:~% time java HelloWorld
Hello from Java!
java HelloWorld 0.04s user 0.02s system 94% cpu 0.063 total
It's not as fast as C or Ruby, but who cares about .063 seconds spent once at start-up?
t:~% time ./hello
Hello from C!
./hello 0.00s user 0.00s system 0% cpu 0.002 total
t:~% time ruby hello.rb
Hello from Ruby!
ruby hello.rb 0.00s user 0.00s system 86% cpu 0.009 total
I get the same times, more or less. I'm not sure the -client switch changes any behavior that early in the VM's life, before any garbage collection or sizable allocation happens. It would still be using a 64-bit data model with the -client switch (-d32 gives me: "Error: This Java instance does not support a 32-bit JVM.").
> But I can't help thinking to myself, "I could do this much faster if I were using Java," primarily due to my relative experience levels.
If you are more comfortable with Java, and are just beginning with Rails, it goes without saying you will miss Java. That's not a very useful metric. Give rails 4 weeks, then compare them for ease of use and expressiveness.
If you don't have a month to learn rails, then stick with Java.
> But also because I haven't seen anything critical "missing" from Java, preventing me from building the same application.
"It can be done with Java" isn't the same as "It can be done concisely with Java".
I would say learn Rails/Django. Use them for CRUD. I have checked Java ecosystem recently, and they are still far behind in terms of expressiveness when it comes to regular web programming. Play framework is close - I haven't used it personally apart from toy examples.
For long running services, depending on your needs, you can either write it in Ruby/Python on top of some infrastructure tool(resque, zmq, celery....), or you can write in in Java if your service is CPU intensive.
> At the cost of throwing internationalisation out of the window. At least the example you led with is more conducive to localisation.
Right. i18n is the reason you have to import two taglibs and the template doesn't support basic conditionals.
/s
JSP is horrendous. There is not a single reason for its existence, and it should be quarantined.
As far as i18n/l10n goes, the example I quoted was from play framework. This is how an internationalized version will look like:
# Messages file
unread_emails=You have %s %s
no_email=You have no email
# Template
#{if (emails.unread) }
&{'unread_emails', emails.unread, emails.unread?.pluralize('email')}
#{/if}
#{else}
&{'no_emails'}
#{/else}
Are you arguing internationalized jsp is somehow better than this? I tried really hard, but I failed to think of a single templating engine that's worse than JSP.
I like JSPX. Designers and HTML front-end engineers intuitively understand custom tags, and any imperative non-declarative logic should ideally be pushed back into Java or a custom JSP tag, such that you rarely see it.
> Designers and HTML front-end engineers intuitively understand custom tags, and any imperative non-declarative logic should ideally be pushed back into Java or a custom JSP tag, such that you rarely see it.
Have you used other templates say Jinja2 or Django templates? The traits you listed aren't unique to JSPX. Jinja2 is designer friendly, doesn't have non-declarative logic, and is pleasant and concise to use.
ERB(or slim or haml) allows embedding code in templates, but that doesn't mean you are mandated to do it. Java will allow you to put n non-public classes in one file - that doesn't mean you code your whole app in a single .java file. Just because it's possible is hardly an excuse for it being bad.
There are use-cases where code in templates are useful. I would rather not jump through the hoops of defining a custom tag for an one-off use-case.
The choice is less clear obvious when you've started to ask why use server-side templating at all? I've spent quite a bit of time on both Rails and Java webapps. The conclusion I've come to is I'd really rather the server just returned JSON and rendering happened client-side. I'm not working on Twitter-scale stuff, though.
Google (at least Gmail), LinkedIn, etc are to me modern web applications & AFAIK they are written in Java (or at least partly in Java) and I'm not counting countless enterprise web apps.
Java is what they call mature technology. It's past the hype and language flame war phase. Those who know its value, just use it to GTD without any ceremonies.
I've worked with PHP for 16 years, and with Grails for almost 5. There are some aspects of Grails and Groovy that make me more productive than developing in PHP. GORM simplicity and expressiveness, and CriteriaBuilder stuff, combined make using direct SQL very rare (required in a few cases, but rare).
However, there are aspects of PHP that make things more simple, and this gets down to somewhat of a cultural thing. Of the PHP people I know, many (most?) of them have done some server setup and understand the entire request stack. I know a lot of PHP people don't grok all that as well, but of the people I know personally, many do. That number is far higher than the number of Java folks I know who really grok the full web stack. I'm not saying none do, but... many don't have to as much as PHP folks.
A friend of mine who's done Java for a decade (and Groovy some too) was confused by a complaint I was having about Java web stuff. Specifically, I was (am?) having some trouble getting session replication stuff working. We need to load balance web servers, and I really want to avoid server affinity on a load balancer. In PHP, sessions are serialized to disk, but serializing to memcache or some other database is pretty simple. Java... not so much.
My friend's confusion was "why are you doing that? just tell the ops guys to set it up". Well... I am the ops guy. Which gets to the culture of dev stacks. Historically, the Java shops I've seen inside are larger, and there's a bigger separation of concerns - the server/ops person often isn't even much of a developer, they just drop in a war file and keep websphere running, etc. Again - YMMV, but that's been mostly what I've seen.
The 'separation of concerns' here is the heart of the issue. In PHP, all session stuff is handled in code. In Java... well, your app server takes care of that for you - 'out of the box' you don't have any real direct control over how they're handled, and configuration of such is never done in code, but at the server level.
I'm reminded of PHP in 96/97. If you were doing PHP back then, it's because you really loved it, not because it was your job, and you really needed to grok everything about everything to get it set up and working (locally, anyway). If you're really set on using alt.java tech, you likely have a greater commitment to getting your hands dirty in multiple levels.
disclosure - i run groovymag.com and have a bias towards all things grails and groovy :)
I can't see why you can't serialize session to database or memcache or anything else if you want. The amount of code involved is almost zero... Also I don't see a reason to have a shared storage for session objects in a scalable distributed application you are trying to build.
In Java you could, for example, use ehcache with out-of-box replication - simpler than using external C-based application like memcache.
And in Java world you have to deal with different applications servers (Weblogic/WebSphere/JBoss etc.) where apache http and nginx installation and configuration is very primitive in comparison. Yes, it involves sharp skills when it comes to huge loads and replication, but that's another story.
Your friend is probably a young junior developer, you can't be a serious java developer without a decent server skills - there is no ops team at home to do it for you and you can't really gain a lot of knowledge only doing stuff at work.
Friend in question is certainly not a young junior dev - >10 years of dev experience, 8 in java, and does java training. Trainers may be more focused on language stuff vs admin stuff, so I cut some slack there. But.. the majority of java people I've known have been developers only, who don't do any server admin. Again, not saying java devs who know sys/server admin don't exist, but, the ones I know who do that aren't 'java devs' in the sense of only doing java, but tend to be polyglots with experience from multiple backgrounds.
I'm not sure why you'd not have a shared storage for session data in a multi-server system. What else do you suggest?
http://ehcache.org/documentation/configuration/configuration - that's an insane amount of configuration it looks like compared to something like PHP. It also looks like you're tying yourself to a specific caching solution vs having generalized session data.
Groovy, Scala + Clojure = next generation of languages being adopted by Java devs. All the things we love about Java combined with a more modern syntax.
It doesn't compile to binary like C/C++ and it isn't high-level and interpreted like a Ruby or Python.
It's a weird middle-times language. It originally appeared in 1995 and is somewhat pioneering in the web space. But it isn't as clean as C# since C# appeared in 2001 and was able to learn from the mistakes of Java. It's definitely not as clean as Go which appeared in about 2009 and was able to learn from the mistakes of C, C++, Java, and C#.
The framework choice is probably more important than the language choice.
There is a fragmentation of frameworks. Starting a greenfield project with Spring, Struts, Stripe, WebObjects, etc would probably be a bad choice. Play is probably a reasonable choice.
But this is not an issue with Ruby or Python. You're probably going to pick Rails or Sinatra as your choice if you go with Ruby. You're probably going to go with Django if you go with Python.
Tyranny of choice is a problem with Java frameworks.
Nah, there are always favourites and 90% of the industry is following them. If you google 100 MVC web frameworks for Java, that doesn't mean anything but that the language is popular.
There are only a couple of frameworks that are in real use. Some large and 'lucky' companies are glued to IBM/Oracle so are forced to use proprietary solutions without this luxury of googling for something new.
Yes. Endless XML configs, and a ton of overhead to get started. Anyone can get productive with Play in 5 minutes. Spring + Hibernate were smart choices in 2003, but no longer the case.
When starting web development, I found it easier to learn Ruby and the Rails Framework from scratch than to use Java which I had several formal classes in. I think that says something about Java's documentation/community support.
Ruby/Rails has railstutorial.org, tryruby.org, rails for zombies/code school, and railscasts. All these high quality beginner resources made using Ruby instead of Java an easy choice.
The other reason for me is that I find the code I write in Java to be too wordy and found the more concise syntax of Ruby refreshing and fun.
I don't think the problem is Java documentation/community support.
It's really that with the exception of Play/Grails/Vert.x the frameworks are horrifically over-engineered by developers who live and breathe in the enterprise space. Nobody has ever really cared much about smaller, more startup land developers.
So Java has required so much knowledge and involvement just to do the simplest things.
I would take a look at frameworks like Play for the future of the platform.
Java is the only language mentioned by name. Last time I talked to them about a thing I was working on and mentioned I would soon have (now actually do have) a Python implementation, the response was basically "That's neat, but can you do it in Java too?"
So, in my little world at least, web development is the only place where Java actually does get used.
I programmed java web apps for 10 years before I switched to python, 4+ years ago. I feel that I'm much more productive using python and can get much more done in a shorter period of time, and to be honest, I'm much happier when I develop in python. Here are some of the reasons why I think python is better then Java based on my personal experience, your milage may very.
Web Frameworks:
When I first start programming web apps in Java, Struts just came out, and it wasn't great, but it was the best thing available. I created a bunch of struts apps, and a few in other frameworks along the way. Whenever a new framework came out (Tapestry, Wicket, GWT, stripe, grails, AppFuse, Play, RichFaces, Spring, etc), I would try it out and see if it was any better, and most times it was only a little better, and sometimes not better at all. I do have to say the play framework is a step in the right direction.
Batteries not included:
One of the most annoying parts of Java was the fact that most of the libraries that you use were not included in java itself, you had to include a ton of 3rd party libs from places like apache commons. If you use something like hibernate with any other large library, you end up in Jar dependency hell, where hibernate needs one version of a jar, and something else needs another version. If you load the jar files in the wrong order, you are out of luck. You need to depend on tools like maven, and ivy to manage your dependencies, and this just brings in more dependencies into your project which results in projects being huge. I had some war files 100MB+ war files for the simplest web apps.
Too many options:
For some reason there seems to be way too many different ways to do the same thing in Java. There are over 38 different web frameworks for java according to wikipedia (http://en.wikipedia.org/wiki/Comparison_of_web_application_f...) and 23 different ORM's (http://en.wikipedia.org/wiki/List_of_object-relational_mappi...) just to name a couple of examples. If you look at other languages they have a more reasonable number. Some people think that having lots of options is a good thing, but it isn't it leads to a lot of wasted effort in the developer community, everyone is reinventing the same wheel, and if you are a new person to the language you have too many option to pick from.
App servers:
Java web applications are really heavy, and require a lot of resources to run. They are especially memory hungry. Like any piece of software they can be tuned to reduce their resource footprint, but compared to other languages their out of the box setup is horrible. In my past I have used weblogic, websphere, Jboss, tomcat, and jetty. I only used the first three when I was forced to use EJB's, but even if you aren't using EJB's they were large app servers and sometimes hard to configure and get running correctly. Tomcat and Jetty are much better and easier to setup, but are still resource hogs.
App Hosting:
If you aren't running your own server it is real hard to find shared hosting for your java apps at a reasonable price. The main reason is because java apps require much more memory compared to other languages, so it doesn't make sense for a shared hosting provider to spend their valuable RAM running a java site, when they could run 5 php sites in the same place. That means there are less providers offering java hosting, which in turn means higher costs to run your website.
Development Time:
When I developing in java, I found myself much slower then what I can do in python. I would need to make a change, compile, redeploy and then test, and this slows down the iterative process. I know there are ways to make this faster, but even at it's best, I felt much slower then what I can do in python.
There is also a lot less boilerplate code to do the same thing in python, so I spend less time developing the code as well.
Java just feels over engineered in a lot of parts, A lot of the API's and interfaces are just way to complicated for what you want to do. And everyone and their brother thinks they are a java architect and this results in big complicated systems that are hard to use and develop with.
IDE:
When I was developing in Java, I felt stuck to the IDE, I was lost without it. IntelliJ is the best IDE's on the market, and it was hard switching to python because there wasn't anything like it for python. So instead of an IDE, I just used textmate, which is just a normal text editor. It was hard at first, but because it was just a text editor, it was a really fast and responsive application. I could open my whole project in a few seconds, whereas when I want to open a project in an IDE it could take a minute or more, with a machine with a ton of RAM. The makers of IntelliJ came out with a python editor called pycharm, I bought it when it first came out, and it is great. But what I realized is that I don't need an IDE for python, I'm fine with a text editor. When I go back to working on Java web apps which I have to do from time to time, I try to use the text editor, but I haven't quite mastered that yet. I personally need the IDE for Java more because If I mess up something it takes longer to recompile and redeploy, which slows me down.
ORM:
When I first started using Hibernate as an IDE, I thought it was great, it had it's problems, and it wasn't perfect, but it was better then what I was doing before. I was happy with it, until I did an application with Django's ORM on a python project, and that opened up my eyes, that is how an ORM is suppose to work. After that project I went back to hibernate, and I just felt disappointed, and longed for going back to Django's ORM. Another great python ORM is sqlalchemy, which is similar to Django's ORM, but a little different. I have limited experience with ROR's ORM, but from what I remember, it was pretty good as well.
Templates:
The web templating systems in Java aren't that good, and I think I have tried them all (tiles, freemarker, velocity, etc). Most of them offer only basic functionality and are a pain to work with. On the Python side, my two favorites are Django templates and Jinja2, they have everything that I could need in a templating engine, and are really easy to use.
I think all of this was true 4 years ago. But Java EE 6 has changed a lot of this. My main experience has been on the Microsoft stack, but I have learned and worked with a lot of tech, including Rails and Django. Last year I worked on a project for which we chose Java EE 6.
There's a lot of good stuff there; for instance simple, bloat-free architecture, JPA (the new persistence architecture), CDI (context and dependency injection), JAX-RS (REST), JSF + PrimeFaces (very productive front-end development) and lightweight, fast web application servers (Tomcat 7, Glassfish).
And you have access, when and if you need it, to a very mature, stable and capable set of libraries, open source projects and tools. Plus the ability to deploy to almost anywhere including PaaS platforms.
For what it is worth, I have used Java 7, JPA (with hibernate), tomcat 7 and glassfish, and I didn't notice much difference. Jersey (JAX-RS) is pretty nice, one of the better libraries to come out of Java in a while.
I do agree that Java is moving in the right direction, but it is a very slow progression. I think the major cause of the slowness is because of the fact that SUN was bought by Oracle, and it took a little while for that to settle down, and now things are slowly moving forward again.
One of the things that Java did right was their WAR files. It is the envy of most other programming languages. You compile your WAR file, and deploy anywhere assuming it is a compliant servlet container. I wish Python had something like this.
You are right the popularity of PaaS's like dotCloud make it much easier to deploy and run your application. On dotCloud you just need to push up your WAR file, and you are running, by far the easiest of all the languages to deploy.
I really like Java as a language, I just think it has a long way to go on the web application front, before it can catch up to the features and speed of development of the other languages.
This is a very thorough, albeit not necessary accurate, story of one's experience using Java.
I agree that there are TONS of duplicated effort out there:
Tapestry, Struts 1/2, JSF, Wicket, etc are all "MVC _and_ Component Oriented".
Hibernate vs JPA (yes, I know Hibernate is JPA 2 compliant, and yes, I know JPA 2 has less features).
XML processors. Java common utilities, the list goes on.
But these days there seems to be a quite select few of winners in my book: Google Guava, JUnit (TestNG is neat, but JUnit is good enough for 80% cases), GWT, Spring Framework or Java EE6 (your choice, or mixed).
Java based ORMs can't beat dynamic language ORMs in terms of "it's fun to use" (or less setup). Period. But having said that, Java based ORMs took different approach compare to ActiveRecord or Django Model. Java based ORMs are more similar to Ruby DataMapper; they required a little bit of setups (have to define your own model, etc) but in the long run, I think these second concept (or known as the Data Mapper pattern: http://martinfowler.com/eaaCatalog/dataMapper.html) may have been a better choice. Of course that is for the long run... not weekend project, get-prototype, get-funded, and get rich-quick scheme.
Java-based App Servers are heavy but with a caveat, depending on your loads, Java-based App Servers may use less resources (or degrade gracefully) because they are utilizing thread vs bringing up Rails + Ruby process per request.
When it comes to dev-time that depends on your experience. For example: I use JUnit, Eclipse, and JUnit plugin as faux-REPL. No re-compilation needed. Setting up the tools I mentioned is done via Maven + vanilla Eclipse. In another word: don't get too gung-ho with the number of tools I mentioned. It's fairly simple to get it to work.
I do have to say this though: as much as people hate Maven, there's no better and more complete build/dependency management/project management tools in other ecosystems (Ruby, Python, Lisp, Haskell) compare to Maven. None.
When it comes to IDE, I love the shortcut navigation keys of my IDE, Eclipse. I'm contemplating to purchase RubyMine in the future as well because quite frankly I can't live with VIM/Emacs. NetBeans has a decent Ruby IDE for a while until Oracle decided not to invest in Ruby anymore. Not sure what the stats these days. I need my "press X to go to Class/Method definition" to read the actual source code.
Yes, Java has been slow moving forward under SUN. Things have changed under Oracle. They're pushing it aggressively and toward the right direction.
People keep saying that the "WAR" deployment is one of the best thing that happened in Java. I heard Oracle is preparing Java EE7 that supports multi-tenant architecture.
Google is heavily reliant on Java. LinkedIn and Twitter both use Scala and Java. I'm not really sure that pointing out that Google has some C++ code really disproves that Java is used heavily at google. Java is still very widely used, more so than more fashionable languages like python and ruby, but the syntax is a bit long on the tooth, hence the popularity of Scala, Clojure and Groovy.
" I'm not really sure that pointing out that Google has some C++ code really disproves that Java is used heavily at google. "
Of course not
"Java is still very widely used, more so than more fashionable languages like python and ruby""
Yes, but "widely used" is a tricky term, I'm sure cases both for and against can be found.
But to talk about Google, last I heard it's only possible to develop application there in the following languages: JS, Java, C++, Python (there are exceptions of course, for specific libraries or things like ObjC for iOS)
As a young developer (early 20's) I think Java's lack of usage in webdev has to do with several "problems".
1.) Java has the rep of being bloated and slow. (At least when compared to C/C++)
2.) Related to #1, almost all the tools the majority of webdevers use are written in C/C++ and not Java. For instance, Apache, Nginx, Redis, MongoDB, MySQL, SQLite, Webkit, V8 - which gives me the feeling that using/improving C/C++ gives me a better understanding of my toolset whereas Java doesn't have any perceived added benefit.
3.) For Application Development itself, using scripting languages like Ruby/Python/PHP makes for BLAZING fast development especially when using a framework like Rails.
4.) The LAMP Stack (if implemented correctly) can handle a LOT of traffic, I'm talking millions of daily users.
So this leaves almost every web developer (I'd say around 98%) with no reason to use Java - ever. Why should they? With the current tools, I can build highly scalable apps extremely fast and because I'm using scripting languages I'm free to experiment, mix/match, combine, and build new tools in innovative ways. Also, I think because Java is associated with the group of C/C++ and "lower level" languages it really does loose cred simply because it can't compete in effeciency terms with those languages.
Personally, as a programmer who loves C, Ruby and Haskell (so yea I'm biased but who isn't?) just looking at the Syntax of Java makes me seriously wonder what Sun was thinking.
yes, but if you noticed I'm comparing Java to C in terms of program language speed. I'm comparing Java to Ruby in development speed NOT language speed, I thought this was obvious... sorry, If I wasn't clear enough above.
You were clear, but if you're going to compare languages you can't cherry pick which features to compare. You compared Java to C performance and then Java to Ruby in terms of expressiveness. Since Ruby does not have the performance of C and C does not have the expressiveness of Ruby it's not really a fair comparison to Java.
I do a lot of work in Python now, which is great. But the one thing that I really really really miss from Java is better dependency management and packaging.
I wish I could just create a .war file for my Python project and copy it to a deploy directory on a server to get it going.
Using a virtualenv and pip or easy_install works ok but a simple maven config to define my project and it's dependencies is still lightyears ahead of the mess we have in Python now.
It is really difficult to beat: 'mvn package && scp target/my-app-1.0.war server:~/deploy/'
We (plumgine.com - in private beta) have been using Java with a success with Play Framework and asynchronous AJAX fronted (some parts with Backbone.JS).
I have been using Java for a while (8 years - J2EE, Android, some desktop utils) and back in the JSF days I used to hate the Java web with a passion. Then I found Stripes (step in a good direction) and Play Framework (absolutely awesome Java web framework).
These days I can whip out prototype in Java+Play Framework faster than anything else.
Some of the reasons:
* I don't have to worry about naming methods/members because I can safely rename them later
* I can easily map Java objects to JSON and back using Jackson
* most of the time I don't worry about database schema - Hibernate (JPA) generates it for me
* Play Framework works in the "hit refresh" mode to see changes
* deployment to Heroku is as seamless as any other.
There is increasingly more action going on in the browser in JavaScript and I think Java (with Play Framework) is a great tool for building backend APIs that will be consumed by your JavaScript client.
Some syntax issues (no function pointers, no lambda, no rich literals, enforcing everything to reside in an object) endears it to Enterprise OO mindset where you want large teams of programmers working "efficiently" - but ultimately a risk conscious and ego driven manager just wants a large team of developers to further their career - and doesn't care how much boilerplate is present or how few lines of code actually do something productive. These are slowly being addressed with newer versions of Java, but it's a long hard road out of hell... and the mental association of Java as enterprise VB is here to stay.
I'd say it's guilt by association with the early years of a java. It reminds lots of people of the bad old days of programming. Getters and setters instead of pure data. Using java objects to hardcode schemas in the middle tier. Horrendeous death by meaningless patterns (form over function). Gigantic libraries configured by XML (how can you take a modern language seriously that doesn't have rich literals). Build dependencies and process that again can't be efficiently specified in the native literal forms of the language.
Finally Java has no useful pedigree as a client side or UI language. Thus the J2ME fiasco. The AWT fiasco. The android sluggish UI fiasco.
You can write a modern web app in BCPL, or Java. But for many people the other options are simply more appealing.
The question should be "Why isn't Java used by startups or for small projects?". Java certainly used for "modern Web apps" at more established companies. The issue is one of speed vs scale. Startups need to get to minimum viable product. They are usually small teams of 1-3 engineers, and value iteration speed over performance or maintainability. Running up against scalability issues or team code code maintenance issues is a problem "you'd like to have", that is, by the time you reach that stage, it's a sign your initial implementation helped you over the initial hump of getting customers or investment. You can afford to rewrite the app at that point.
A company like Google can afford the luxury of building things for scale up front, even though they may be wasting their time implementing scaling for something that might get no users, because they can absorb the loss.
At least, that's my opinion, that many many "cool", "hip", "modern" companies build small apps with small teams where iteration speed and simplicity are the greatest requirements.
Correct but also a company like Google knows that the moment they put up a link in the frontpage they can drive vast amounts of traffic towards the new property.
Secondary reason is that a web app from Google that doesn't scale is really bad PR and draws comments like "omg, lulz it's Google and they can't handle traffic???!!!1!"
Hence, they build with scaling in mind.
A startup has none of these concerns and just cares about time to market and making some money to convince VC's that it's worth investing.
I think because of it's age, the pitfalls and limitations of the language may be more well understood, so it may suffer from a sort of 'grass is greener' effect.
Its age relative to what? Python is older by any measure, and the first public release of Ruby was only 7 months after Java's. Java certainly had a higher profile than either at the time, but they're all from essentially the same period.
This is just my experience but if there has existed a common line of thinking with the rabid Java fans I've worked with, it would be closed mindedness to the point of being its own brand of Stockholm syndrome. The thinking that whatever the project at hand may be, a Java based solution is always the correct answer and there is nothing to learn from alternative platforms. I've heard "Why would anyone want to use anything other than Spring?" or "C# is shit" more than once. However, if you were to compare the experience of using Spring + Eclipse to C# + ASP.MVC + Visual Studio, you'd have to be pretty set in your ways not to admit that the latter is a much nicer platform to work with and that the Java eco-system shouldn't take something away from it. Having a standard web framework (ASP.MVC) makes .NET teams miles more efficient than the framework fragmentation that is Java web dev.
And if you're comparing it to Rails or Django, I honestly don't think you can easily find a 3 or 4 engineer Spring team that could deliver a product as good (or scalable) as Instragram in the 2 years it took them to do it in Django. You just can't iterate as fast.
>>the rabid Java fans I've worked with [closed mindedness]
It is hard to argue against anecdotal evidence, but of the cases you mention -- java, Rails, Django -- imho, it is not exactly the Java people who seem to be the worst language/framework fanatics...
(That said, scripting languages eat static languages' lunch for development speed in most every case I've seen.)
That kind of framework enthusiasm doesn't really stem from the closed minded mindset I was referring to. Most Ruby & Python devs I've met would admit that Java is a much better choice than their perspective languages for something like that requires distributed concurrency and speed (like Cassandra or Redis). The people I'm talking about are the ones that wouldn't look seriously at RabbitMQ because it's written in Erlang, not Java.
I got your point, I wrote that according to my personal experience the other cases are quite a bit worse. Which is worth as much as your personal stories.
Because Web is type-less, purely text-based, and dynamic. And Java is not. I remain a Java aficionado, but would reach for it last in the Web tier. Put a dynamic language upfront and hook it to a SOA-based Java backend.
I actually think the IDEs for Java, e.g. Eclipse and IntelliJ, are quite evolved and help speed webapp development, and they do it in ways that make up for Java's verbosity and boilerplate.
For me a lot of the web frameworks for Java felt cumbersome and I found that Java worked better when functioning as a high-throughput backend service instead of handling front-end UI. Oddly, with Java, I was more concerned with concurrency issues, GC tuning, threading, and other systems-y problems, and with Python I was more concerned with concise and Pythonic syntax and faster iteration.
I think that Java still has a strong role for writing REST web services and heavy lifting back end stuff because of the robustness of the JVM and lots of great tools and frameworks.
That said, most of the web services I have written this year are in Ruby (with some Python in the last few weeks).
For web app front ends I really prefer lighter weight tools like Rails.
No it is not the coolness factor, it is the paradigm. Java forces you to use OOP and OOP is not very fit for web development: you want to answer fast to a stateless request by checking some data trough different filters (eg a template), you don't want to recreate a full world of objects and pass along some messages.
Yes, and there is this ORM impedance mismatch thing. I stopped writing classes for all tables and it removed many useless code and many issues related to stateful methods. Just one example: if you delete a book with book.delete() then how come you can two or many lines later change its title with book.title = Foo?
We use Java to develop web apps because while we could use anything ( I run a research team) I know that I will face problems downstreaming the work if we do. The application support groups can get a Java developer with a whistle, the same is just not the case for any other language, apart from possibly PHP.
imho, Java is a great tool when it is deployed for its original goal: Platform independent GUI clients. Unfortunate its now mainly used on the server side, where it fits badly.
The main reason I'm not using Java on server side is memory footprint. A typical Lighttpd, fastcgi, Rails, MySQL stack runs well within 256mb of memory on a Xen instance. A typical Apache, Tomcat, JBoss, Hybernate, Spring, Oracle stack requires 4GB or more on a root server.
I think most startup coders shy Java, because they know it mainly by maintaining enterprise dead horses and bloatware.
I seriously recommend that you re-look your stack. Java is simply the most performant (RAM and CPU) stack vs Rails in a pure apples-to-apples comparison.
The two stacks you have compared are apples to watermelons - here are a couple of questions:
1. Why both Tomcat and Jboss ? Choose one or the other. In fact for the best performance you can run your application on Jetty.
2. Mysql vs Oracle ? you need to compare equally. I hope you do realize that JDBC/JNDI are perfectly compatible with Mysql - more so, since they are the same business entity.
3. Lighttpd vs Apache is again an unfair comparison. You can perfectly run Lighttpd in front of Tomcat.
I seriously suggest you re-evaluate Java if you are purely looking for performance. Developer productivity is a whole different story altogether.
all true - but my unfair comparison was between the typical java enterprise dead horse, and a typical startup stack.
I did not compare Java best practice for one reason:
The enterprise bloat is how Java is perceived. Its not about why Java is not suited for startups, but why Java is not choosen by startups.
Users generally dislike java on the client side because the widgets don't integrate with their platform quite right. Java apps don't "feel right". A good web app is generally easier and cheaper to build and better than a bad GUI app.
I think the server is where Java shines. Good Java is almost as fast as good C (if it's not, you're using bloaty libraries or being cavalier with memory), and when something breaks you get a stack trace that a support team can make some sense of, and the build/dependency system is a lot nicer.
Sun sold Java as a plug-together ecosystems. They encouraged a mindset of putting together big teams of developers who live in padded IDEs and lean on bloaty frameworks, and not to think about resource usage. This won a mental traction with companies who wanted to believe that software work and developers should be a commodity, but has lead to a lot of bad systems. The results cause people to have some strange ideas about Java, like that it's slow.
The Java world places a lot of emphasis on inheritance, which may be an anti-feature. Before I became fluent with python I used to create thick abstract class hierarchies that aimed for perfection and reuse. In truth the result was a bloaty, brittle mess. Python's awful inheritance model forced me to learn how to think in ways other than inheritance.
Your example technology stack isn't a like-for-like criticism. You're criticising Java because Oracle takes up stack of memory and because you'd choose to use hybernate and spring. Why can't you use lighttpd, fastcgi, Java and mysql? The rails ORM isn't sophisticated, and it'd only be a couple of days' work to hack something up equivalent in Java. The result will be faster than rails and less memory intensive.
You missed the obvious advantage of rails over java for web development - a lot of web development involves heavy string processing, and the tools you get in ruby/python style languages for list processing and string manipulation are a luxury compared to what you get in Java! That was the main reason I moved away from Java for web work. With Java you try to build things to be configurable. You might need to do a different option later, and you know that it will be a laborious refactor. Whereas with scripting languages, the configuration language and the programming language are the same thing. So you just write the thing to do what you need it to do. And if you needs change a bit later, you throw away what you had without it feeling like the death of a child and then do the new thing and get on with your life.
Disclaimer: This is cribbed from my upcoming "The Well-Grounded Java Developer"
---------------------
If you investigate Ola Bini's pyramid where languages fall into static, dynamic and DSL layers you'll see his arguments for what type of programming tasks suite which layers. Java sits firmly in the stable layer, and so do all of its various web frameworks.
As expected for a popular and mature language, Java has a large variety of web frameworks, such as these:
Spring MVC, GWT, Struts 2, Wicket, Tapestry, JSF (and other related “Faces” libraries), Vaadin, Play, Plain old JSP/Servlet
Java has no de facto leader in this space, and this partly stems from Java simply not being an ideal language for rapid web development.
The former leader of the Struts 2 project, a popular Java-based web framework, had this to say on the subject:
"I’ve gone over to the dark side :-) and much prefer to develop in Rails -- for the conciseness mentioned above, but also because I don’t ever have to do a “build” or “deploy” step during my development cycle any more. But you guys and gals need to be reminded that this is the kind of thing you are competing against if you expect to attract Rails developers ... or to avoid even more “previously Java web developer” defectors like me :-).
Craig McClanahan, Oct. 23, 2007"(http://markmail.org/thread/qfb5sekad33eobh2)
Java is a compiled language, and as alluded to previously, this means that every time you make a code change to a web application, you have to go through all of these steps:
1. Recompile the Java code.
2. Stop your web server.
3. Redeploy the changes to your web server.
4. Start your web server.
As you can imagine, this wastes an awful lot of time! Especially when you’re making lots of small code changes, such as altering the destinations in a controller or making small changes to the view.
If you’re a seasoned web developer, you’ll know that there are some techniques you can use to try and solve this problem. Most of these approaches rely on some sort of ability to apply code changes without stopping and starting the web server, which is also known as hot deployment. Hot deployment can come in the form of replacing all of the resources (such as an entire WAR file) or just a select few (such as a single JSP page). Unfortunately, hot deployment has never been 100 percent reliable, and the web server often still has to perform expensive recompilation of code.
If you must use a Java-based web framework, I highly recommend products called JRebel and LiveRebel (http://www.zeroturnaround.com/jrebel/). JRebel sits in between your IDE and your web server, and when you make source code changes locally, they’re automatically applied to your running web server through some genuinely impressive JVM trickery (LiveRebel is used for production deploys). It’s basically hot deployment done right, and these tools are seen as industry standards for solving the hot deployment problem.
Generally speaking, Java-based web frameworks don’t reliably allow you to have a fast turnaround time for your changes. But that isn’t the only concern with Java-based web frameworks. Another factor that slows down rapid web development is the flexibility of the language, and this is where static typing can be a drawback.
In the early stages of developing a new product or feature, it’s often wise to keep an open-ended design (with regards to typing) of the user presentation layer. It’s all too easy for a user to demand that a numeric value have decimal precision, or for a list of books to become a list of books and toys instead. Having a statically typed language can be a great hindrance here. If you have to change a list of Book objects into a list of BookOrToy objects, you’d have to change your static types throughout your codebase.
Although it’s true that you can always use the base type as the type of objects in container classes (for example, Java’s Object class), this is certainly not seen as a best practice—this is effectively reverting to pregenerics Java.
As a result, choosing a web framework that’s based on a language in the dynamic layer is certainly a valid option to investigate.
"1. Recompile the Java code. 2. Stop your web server. 3. Redeploy the changes to your web server. 4. Start your web server.
...
Unfortunately, hot deployment has never been 100 percent reliable, and the web server often still has to perform expensive recompilation of code."
- Last I checked
i) the hot deployment in Tomcat/Jetty/SBT/etc is pretty solid, especially if we are talking development.
ii) Java supports incremental compilation which means you only need to compile what has been changed, especially if we are still taking development phase again. Unless you compile after making changes to 100+ files, I don't see how expensive this step can be.
"Generally speaking, Java-based web frameworks don’t reliably allow you to have a fast turnaround time for your changes. But that isn’t the only concern with Java-based web frameworks. Another factor that slows down rapid web development is the flexibility of the language, and this is where static typing can be a drawback."
- This argument about dynamic typing faster/better than static typing is just BS. Each offers it's own advantages and can be better/faster depending on where/when/how you apply it and how good a developer are you at actually using their power. Your first example of changing number value to have decimal precision can be achieved in static typing languages like Java/C# just as fast and reliably when one uses refactoring. Your second example of changing list of Book objects to a list of BookOrToy objects, could have been avoided all together by coding to interfaces and not concrete objects. If that has failed, refactoring again solves this.
Not only does hot deployment work almost always, so does in-place compilation of modified code within deployed modules while connected to a remote application server in debug mode.
To both of these points, you still have classloader issues which cannot be resolved (App/Web server vs application classloading). This is one of the reasons that Java 8 is going down the modular Jigsaw route (taking ideas from OSGi along the way). Some web/app servers have put together clever tricks over the years and JRebel also helps, but it's certainly not foolproof.
I'll concede that the static vs dynamic language gap is narrowing in terms of flexibility (and yes BookAndToy is a _very_ contrived example), but dynamic language fans love the fact that you don't have to refactor at all.
FWIW, we've had some problems with hot deployment and Tomcat. After a few of them the VM OOMs. Probably we are doing something wrong or triggering some Tomcat bug, haven't dug deep enough yet.
SBT also does hot deployment for Java and Scala projects [1]. Just start the server with the directive:
$> sbt container:start "~compile"
"~compile" tells it to scan your project directories every .5s (configurable) for saved changes and recompile only the changed files. It's pretty sweet, and unlike Jrebel, fFOSS.
I'm sorry, but as a Java developer seeing Oracle pick it (anything Java) up like a dead fish and try to see who they can smack big money out of is horrifying.
It goes against the culture of Java that I'm familiar with. I've been learning other languages on the JVM for the express purpose of being ready to jump ship if I need to with those other languages. (Jython can jump to Python, JRuby to Ruby, Java to C#/C++, and Scala can be mapped to something I'm sure).
Don't forget IBM. (Not that they might seem any better than Oracle...)
They own a large chunk of the enterprise Java space with WebSphere. And they're also are a large driving force for Eclipse (was also their original code).
I've got to say, I'm wary of supporting technologies that are linked to disagreeable behaviour like that - for a time I was considering phasing out MySQL for a similar reason. I saw Sun as one of the good guys.
Came here to post that. Oracle are known for being major assholes, over and over. I wouldn't want to work with anything they spawned. I'm not sure why you got downvoted. Believing in the tools that you work with is as important as what those tools can do.
It IS used extensively for modern web application development just not by a lot of startups. In the enterprise space you really only see Java and .Net used for the core pieces.
One reason that Java is becoming less popular is that you don't need to use Java (the language) to be a part of Java (the ecosystem). You can use Groovy, Scala, Python, Ruby etc which are often less verbose and have more exotic features. So developers can try new languages out but don't need to abandon their existing libraries. Best of both worlds.
This is the approach that companies like Twitter and Etsy have taken.
Part of it is a framework issue. Struts is horrible...absolutely, stunningly horrible. Your controller is an XML file (seriously). Freemarker (the main templating language) makes ColdFusion look awesome.
Play is better, but it seems built for the way websites were created in mid-2000. JSON is still a second-class citizen. Static actions are a weird choice given IoC is achieved via DI in a static language.
Edit: I should add that there's also the persistence story. Anyone who's done [n]Hibernate knows that it's, at best, a mixed blessing. Even Java's NoSQL drivers are verbose compared to their dynamic brothers (first-class hash support is a big issue here, for some drivers in particular). I'm not sure something like Sequel would even be possible to write, and the AR implementations are, again, limited by the compiled-time nature of the language and the inability of bend the syntax into a nice DSL.
Java also lacks lambdas, and generic support is weak. And what's up with int vs Integer...the list goes on and on.