Hacker News new | ask | show | jobs
by mark242 4412 days ago
It's funny. An "Introduction to Modern Java Web Development" sounds like a primer for the Play Framework, Scala, and Akka. Each of the examples looks like the starter documentation for Play, in that you've got your json manipulation, routing, connecting to a database, DI, actors, etc.

Java devs-- you seriously owe it to yourself to spend the time investigating and ramping up onto Scala and Play. This is where the future of Java web app development is being driven from, by Typesafe and the Play / Spray /Akka open source developers. You do yourself a great disservice by sticking with Spring, Hibernate, JBoss, and the old standbys.

14 comments

First of all, your attitude is off putting and condescending. You don't convince people by telling them "You guys are living in the past, look how I do things, you should do the same".

Please enough of that, especially coming from the Scala community. Let's act as professionals and judge tools on their merits instead of instigating flame wars.

Second, I'm doing both (web Java at work, web Scala on my spare time) and in my experience, there is really no clear winner. What's especially interesting is that I can find about the same number of positive things to say about the Scala tool stack (Scala/Typesafe platform/Akka/Play) as I can say negative things about each of them. Every time I'm happy about something in the Scala world, I find something I'm not happy with that counter balances it (tooling, slowness of template recompilation, unprovedness of the actor model, Play's arguable step backward in the v2 compared to v1, etc...).

Java is impossibly verbose and has a very limited type system compared to Scala but man... do I develop things quickly with it. There is close to zero friction to get from nothing to something workable, maintainable and fast. And the tooling is top notch, the environment and compilers are super stable, and Java 8 is numbing a lot of the pain I used to feel. In contrast, I feel that I'm often fighting against the Scala compiler whenever I write Scala code. It feels nice in the end to see how concise and neat the code looks compared to Java, but I'm never really convinced the pain was worth it.

So, back to your original point: I've tried (and continue to experiment with) all these "new" technologies that Scala is claiming to bring to the table, and so far, I'm unconvinced that they are a clear improvement over what we currently use in the Java world.

And given that Scala continues to be a marginal language on the JVM, I don't think I'm the only one doubting that Scala represents the future.

Don't take my comment as "quit living in the past". Take it as "here's how exciting the future is". I'm not telling you your startac phone is crap, I'm telling you there's this great new thing called the iPhone/Android/smartphone.

The real benefits of Play and Akka become apparent when a third-party service you send API calls to starts acting flaky. Or when your web service that you offer to clients is suddenly being hit by an iPhone game that just got purchased by a million people. Or when that nasty little bug that winds up throwing an exception from time to time rears its head all of a sudden. Play and Akka give you a resilience that is very hard to come by in the Java world.

Typesafe's home page has, in giant type, "Applications are becoming Reactive" and they are absolutely spot f'ing on. Writing blocking code, waiting on threads, assuming you're running on one JVM, these things are great and all, and very easy to do because all of those templates are built into IntelliJ and you just have to click a few buttons to get all that, but wow, the performance difference once you get into the Play world is just frighteningly good.

I don't find mark242's comment off putting or condescending at all. He's just telling is like it is.

Of course there are Java developers who can kick ass with Spring, Hibernate, Servlet containers, and war deployments, but all of these tools are huge, bloated, and starting to show their age. Modern frameworks like Play make things simpler for those of us who don't have +7 year JEE experience with Spring and Hibernate.

The comment is off topic since the article is not about Spring or JBoss and it recommends against using Hibernate. The article is about a modern lightweight stack (JAX-RS, Jetty, Dagger, JDBI).
Not it's not, rebutting another poster who is commenting about Play (a modern java web development framework) in a article that is about modern java web development frameworks. Your comment is counter productive to this conversation, and the purpose of Hackernews in general.
He's just telling like he thinks it is.

There, fixed that for ya.

I agree with the Java vs Scala poster. And unlike him, I have a 30,000 line scala production project under my belt. Everything he says is true, and then some. Ever split up a file into chunks because intellij can't edit it effectively?

Yeah, didn't think so. (Just telling like it is)

> And unlike him, I have a 30,000 line scala production project under my belt. Everything he says is true, and then some. Ever split up a file into chunks because intellij can't edit it effectively?

I have a 20k line Scala project in production and editing it has certainly never been an issue. Why does Intellij have problems with large files?

I've written several large Scala projects and never had Intellij choke on large files.
Incrementally compiling a 3000 line file in 2011 as you edited it.

I'm sure the Jetbrains folks have fixed that right up, but at the time, breaking it into 500 line chunks was required, due to the exponential nature of the slowdown we accomplished.

The basic reality is Scala compiles are slow. Syntax and red-line highlighting isn't cheap, and no amount of brilliant russian IDE developers can totally fix everything.

Same here, we have multiple large Scala systems, never had issues editing files in IntelliJ.
> ... Java 8 is numbing a lot of the pain I used to feel.

Interestingly, the biggest thing I wish I had when writing Java is algebraic data types and pattern matching. A few years ago I would have said it was lambda, but having sum types would make expressing many things so much easier.

Been there, done that. In the previous company I worked at, some new projects were done in Play. The result: frequent API changes in Play, bad Maven integration, illogical APIs from the Java perspective (an artefact of Play being written in Scala), little documentation, and I don't know how it is now, but back then it was very had to make a minimal REST application without pulling a lot of baggage in.

We rewrote these applications using JAX-RS (RESTEasy) and they were much simpler, easier to maintain, without API breakage in new framework versions. It just a bunch of methods with annotations. XML and JSON serialization is automatic (via JAXB and Jackson). And you can use the same lightweight ORM as Play (Ebean), since it's an external project.

Well-thought out, mature technology is often better for getting work done than the hype of the day.

I've just started using play for the last two weeks, but so far i really don't understand the critics on java vs scala or the documentation. True, so far i've only dealt with json. / db / file upload & download , but even that covers quite a vast area, and it was pretty obvious that every time play had both a simple and documented way of doing those , even in java.
I don't know. I loved Play Framework 1. Simple, lean, and lightning fast development. Play 2 came out and it looked strange, with various Scala things mixed in. It's a lot more complicate and bloated, and more buggy. The core piece is in Scala. The build is now sbt, yet another different thing to maintain. The template is Scala, slow to develop and slow to compile. The much-touted async feature is a meh. Most web apps don't have a high scalable requirement that async would help. If I really need high performance async support, I would go with Vert.x.

Play 1 was almost perfect. Really hope someone would fork Play 1 and continue with it.

Personally I have become quite fond of Ninja Framework ( http://www.ninjaframework.org/ ); as simple as Play, but pure-Java (Java 8 too!). Even has a similar hot-reload mechanism as Play!
Author here. As I explain in the article, I cannot recommend any framework that encourages asynchronous code. It's simply the wrong approach, no matter what functional tricks are used to make it more palatable. And the blocking Play APIs both feel foreign to Java, and provide no benefit over the standard, and widely implemented, JAX-RS.
Blocking in Play should be foreign. On modern hardware architectures, writing code that blocks is the equivalent of throwing up your hands and saying "I can't trust myself to write efficient code so I'll just scale out my hardware and hope for the best". This is how Amazon winds up making so much money off Java developers who get constrained by thread pools and wind up spinning up a million instances of m3.medium machines.

This is, imho, what makes Play so fantastic. That you can have def index = Action { hardComputation() } for blocking code, and change it to def index = Action.async { Future { hardComputation() } } and you have magically changed your application to be asynchronous through the request-as-actor paradigm of Play. Play makes it easy to write async code. Play makes it way easier to control configuration for things like thread pools, dispatchers, and the like vs. Jetty. The performance of the nonblocking async code is incredible, and winds up saving a ton of money and developer time.

Doing a 'hardComputation' async provides no advantage. The cpu is limited to how much computation it can do and if you have enough of those 'hardComputations' running simultaneously whether sync or async you will hit the limit of the cpu.

Async is only beneficial in terms of IO.

Preemptive multitasking makes this much more valuable than you portray it. Play also makes it really easy and you don't have to seriously think about it.
You should read the end of the post, then. The asynchronous, non-blocking approach, is always wrong. Regardless of your hardware architecture.
"The asynchronous, non-blocking approach, is always wrong."

http://en.wikipedia.org/wiki/Fallacies_of_Distributed_Comput...

If you have a method that relies upon a DNS query, and your DNS server starts to respond to requests very slowly, your blocking application will run out of threads very quickly, and you'll be spending time poring over thread dumps trying desperately to see why all of your threads are waiting when the load average on your app server is basically zero. Your monitors will be going off like crazy because it appears that your application is flapping, sometimes able to handle a request and sometimes not. You will be tearing your hair out (and Java devs have all done this, though maybe not because of DNS).

If you have a non-blocking application, you will get an alarm that one of your pages may be acting a little slower than normal (even though the rest of your app is running normally). You'll look into the controller source, see that it's performing a DNS query, and poof, your debugging is done and you're off to restart bind.

I think this is an argument for timeouts, fail over, and load shedding not asychrony.

If you have a sufficiently slow DNS you will chew through all the memory available to your non-blocking application in an amount of time that isn't functionally different from how long it will take you to exhaust your threadpool.

The whole point of the lightweight thread approach with shrinking stacks is that you will use the same amount of memory for both and they will fail at roughly the same point.

You won't run out of (lightweight) threads because you can have millions of them. Blocking code on top of lightweight threads give you exactly the same scaling characteristics of nonblocking code.
I know what you mean by the post and your current assertion that non-blocking is "always" wrong regardless of architecture, but I think there are a few caveats that you really need to apply here.

You are talking about a problem domain where concurrency is what you are scaling and where the things that would block are orders of magnitude slower than processor time.

If you were working in a problem domain where latency is what you are scaling and the blocking calls are on the same order as processor time, non-blocking approaches can be best as the blocking mechanism can still carry overhead even with light weight threads.

Maximizing throughput is another beast entirely as well.

Would you mind substantiating why asynchronous code, successful in plenty of places and pretty much every new environment you're likely to run into, is so dogmatically the wrong approach?
> You do yourself a great disservice by sticking with Spring, Hibernate, JBoss, and the old standbys.

Given the amount of money you get with them, doing consulting in Germany, I think they will stay around for quite a while.

I'm curious if this is comparable to Rails rates.
For UK market, check out jobserve.co.uk. From what I've seen there, the rates for a typical strong dev are about the same in the Java and the web scripting languages worlds (js/node, ruby). However, for rare and/or exceptional experience, pay in the Java world can skyrocket. Also, finance is hiring mostly Java/.net/c++ guys, and their rates are much higher than what everybody else is willing to pay.
You can get into projects doing 60K € working for others, freelancing is higher.
No, it isn't. I was a Scala enthusiast but experience has taught me to like Java and its maturity and dislike Scala's unstable complexity (maybe it's more stable now than back when I was onboard) but the language by design embraces abstraction building that is nice-looking superficially but deeply hard-to-understand when different features interplay, which also makes the tooling harder to get right.

Also, Spring is not that bad, though sometimes I have hard time to understand some of the initialization/runtime problems. Hibernate and JBoss I rather skip, and use Tomcat and Dalesbred for relational data access.

My favorite - write Scala (or even Kotlin) with Spring (the new versions of Spring) or - Java EE 6/7 with non standardized Jersey MVC (hope they'll add it in Java EE 8)

I think Play / Spray and Akka are great but let's differentiate between the language and the framework.

You can write Play / Akka with Java (they added Java 8 support recently) and you can write Spring / Java EE with Scala (I do that all the time and it's working great)

More than that, I have mixed Java / Scala projects and it works like a charm (once you configure maven / gradle correctly that is)

The "new" Spring versions are nothing like it used to be. Also the new Java EE ones. no XML configuration files, all convention over configuration. And I sometimes prefer a @GET + @Path or @RequestMapping annotation over concatenating routes with ~ like they have in Spray.

It's just a matter of preference and personal taste, but let's separate the language discussion with the framework / ecosystem discussion, they are not the same.

> you can write Spring / Java EE with Scala

It'd be nice if we could also write Gradle with Scala, or some other decent JVM language.

The article doesn't even recommend Spring, Hibernate, or JBoss; in fact, it specifically recommends against Hibernate. Instead, it recommends Dropwizard, JDBI, and Dagger among others.
I put my money on Spring, Hibernate, JBoss lasting longer than Scala, Akka etc.

Those technologies have stayed on, while other trends have come and and go.

Actually, it is basically Pivotal versus TypeSafe, not just Spring versus Akka or anything like that.

I put my money on TypeSafe.

Pivotal still (05/2014) doesn't have Java8 support for some of it's frameworks (grails https://jira.grails.org/browse/GRAILS-11063 ). TypeSafe pre-released versions of Play that take full advantage of Java8 features.

Given that if you need to run a Java 1.4.2 app on top of JBoss (or Glassfish!) then the types of technologies that these two companies are pushing are solving problems in a different domain.

And arguably the PermGen change in Java8 would benefit Grails/Groovy the most.

Grails 2.4 will support Java8, and RC2 was released today!
Been there, done that. I switched from Java to Scala and Play. Back to Java 8 and Spring MVC and couldn't be happier to be back.
> in that you've got your json manipulation, routing, connecting to a database, DI, actors,

While I agree with you about the others 'json manipulation' is not an area that Play can even be compared to Jersey (Jackson). Jersey transparently converts the request body to the required input type whereas with Play you still have to un-marshal the body while taking care of errors (admiddently that can be 'hidden' away using Action composition but still is work that the developer has to worry about). With Jersey its magic that just works.

Well, he doesn't recommend any of Spring, Hibernate or JBoss, if you read the article. And I think his point was modern _Java_ development.
Agreed, Java, JDBC, HTML/CSS/JavaScript - this is my preferred stack, simple, linear, understandable, maintainable.
Scala, Lisp, Haskell, Smalltalk do not register in my puny brain. C, C++, C# (which I don't EVER do any more), Java, those resonate and make sense to me. Bash and Python too for scripting.
I'd rather put my money on Spring learning lessons from Play / Scala / Akka. If they don't, the writing may indeed be on the wall.
I don't feel like Spring can fix the core problems here, unfortunately--they're Java Problems, and Java Problems grow more and more acute as time goes on (though Java 8 is a good step in the right direction).

The pleasant, compositional interaction borne of Scala's syntactical flexibility is why Play's wonderful to use (and Akka as the backend is largely behind-the-scenes). I used to be a detractor early in Play2 because of some large-scale-unfriendly decisions, but they've pretty much all been fixed.