top | item 7680338

An Opinionated Guide to Modern Java Development, Part 1

553 points| pron | 12 years ago |blog.paralleluniverse.co

396 comments

order
[+] cpprototypes|12 years ago|reply
I like the changes in Java 8, but I'm concerned about Java fragmentation between Oracle/OpenJDK and Android. It seems Android is stuck on Java 1.6 (since Dalvik is not "true Java" and is more like a VM that happens to implement a language very similar to Java 1.6). There's now a huge gap between 1.6 and 1.8. It's not just syntax like lambda and default methods. It's also the supporting API changes in collections (streams) and others. Dalvik was based on Apache Harmony which is a dead project and will never get the Java 8 API changes implemented. Does anyone know if Google is going to do something about Java 8 and Android?
[+] spullara|12 years ago|reply
There is a good reason that Sun didn't want this to happen and tried to stop it in court — successful against Microsoft, failed against Google. If I remember right, most everyone on here was rooting for Google to win and continue to fragment the language.
[+] bsaul|12 years ago|reply
I'm back to java after having an unsatisfying experience 2 years ago with Spring MVC, (this time i use the "play framework"), and it seems to confirm my intuition that the language itself is really just fine. The problem lies more in bloated frameworks and corporate culture where everything needs to be standardized, regulated, and the purpose of a mandatory non-free training session.

Add to that the fact that every single topic is covered by at least 3 or 4 libraries, and you get a more complete view of the situation.

[+] Consultant32452|12 years ago|reply
I kind of like that things are standardized/regulated in the Java space. If you're using anything close to industry standard tools and methodologies I can come in and be an effective member of your team faster. I know it can sometimes be more exciting to build something in a way no one else has ever built it before, but it's usually a bad business decision to do so.

This is one of the reasons why I still lament javascript. It seems like everyone and their mother is using a different framework to accomplish essentially the same task. The flavor of the week last exactly that long: a week.

[+] twistedpair|12 years ago|reply
How's Play! compare to Spring? I'm working on a bloated Spring whale (1.5M LoC, 485 Spring XML config files) and wondering if something like Play! can do it better, or if complexity is simply a beast that will inevitably turn any project into a turgid mass.

I ask since friends at Google will laugh at a bar if you even say "Spring," but I'm curious what else can do it all (Guice/Gin?). Perhaps nothing can and the trick is to simply have small, cohesive projects linked by common REST (et al) API's and to merely skirt complexity entirely. However, for workflow and state management, you'll inevitably need some common integration point.

[+] turar|12 years ago|reply
I was just recently trying to decide between "new" Spring MVC, Dropwizard, and Play.

Spring now has a bunch of slick-looking guides and tutorials. But then I looked at the actual contents of their tutorial project, and it just turned me off. For an "example" REST project, they had over 50 classes not including tests: https://github.com/spring-guides/tut-rest/tree/master/6/comp... , with many being "event" classes of some sort. I mean, WTF, is this really the "idiomatic" way to build Spring REST/MVC projects nowadays? I'm trying Dropwizard for now.

[+] userbinator|12 years ago|reply
I think that to a certain extent, the standard library also encourages this culture, since that's the most prominent and arguably widely used piece of software that's written in Java and it will be used as an example of "good" code.

The continuing notion that CS classes teach objects first (I've heard recommendations that it be before even conditionals and loops, shockingly enough) I think is also a contributing factor: "When all you have are classes, everything turns into an object."

But as things like Java4K suggest, the bloat may not be inherent in the language itself; it's certainly possible to write concise, efficient Java code.

[+] yawz|12 years ago|reply
> The problem lies more in bloated frameworks...

How ironic... I was an early adopter of Spring, when it was all about simple "enterprise development without J2EE". So, given enough time, does bloat follow success and does it become inevitable?

[+] kodablah|12 years ago|reply
One of my opinions these days on javadoc is that you should be minimalist. Have nothing to say about the return type? Don't add @return. Same for @param. Just a sentence about the method/field/class? Just a single line /* * ... */ is fine. Have nothing of value to say on a method/field/class (e.g. a getter), don't add javadoc at all. I'm growing weary of large files with tons of redundant javadoc lines to make some checkstyle/pmd rule happy.
[+] benjaminpv|12 years ago|reply
Seconded.

I always bristle when I see javadocs that include things like 'returns an object of [x] type that...' You're dealing with strong types, the signature provides all this information already. That, combined with good variable names, should do a lot of the documentation for you.

If you wanna document a method, document what problem it solves. Document any gotchas (or better yet, redesign them out o_~). Don't just repeat what reading the method's signature already tells me.

[+] nollidge|12 years ago|reply
Yeah, I'm of the opinion that if you need a class/method comment to explain what it takes in or spits out, you probably named it badly.
[+] tieTYT|12 years ago|reply
> But the modern Java developer uses Gradle

I'm a little skeptical of this. More like the developer in the future uses Gradle. Usually when I go to a project's home page, I see documentation on how to include the Maven dependency, not the Gradle dependency. It's pretty obvious how to convert one format to the other, but my point is I think most people are using Maven.

[+] pswenson|12 years ago|reply
I'd say Gradle is the least awful of the 3 major build systems. Ant degrades into an unmaintainable mess as soon as any complexity enters the system. XML is a horrible scripting language, simple imperative constructs are very awkward (loops/variables/conditionals).

Maven also suffers from XML hell, but at least it has dependency management.

I've used gradle extensively and it is quite difficult to figure out what is going on. Using a debugger would be nice, but it simply doesn't work. Gradle is terribly slow on a big project, the update checks are the main culprit. They should be done automatically in the background to alleviate this pain.

Since gradle is compiled rather than interpreted, calling code in the project being built is difficult and convoluted. For example, if I want to call a DBUtil.cleanDB() method in my java code I can't reference DBUtil in my gradle script as it hasn't been built yet and the Gradle script won't compile. If gradle was interpreted this problem wouldn't exist....

I find the DSL unintuitive and the inability to specify the order of tasks execution is always a sore point.

On the positive, at least it's a language, not XML. I have never understood the java world's obsession with XML and forcing it in directions never intended. This XML obsession has led to java being a major laggard in automation tech. Java devs do many things manually that a Ruby/Python dev would be horrified at....

[+] pron|12 years ago|reply
Specifying the dependency in Maven XML has become sort of a standard that even Gradle people use. Obviously, Maven has been around much, much longer, and a lot more people are still using it, but more and more are switching to Gradle. At the very least Gradle has come to a point that you don't have to worry about it not being maintained, or that there won't be people to ask if you've got a question.
[+] smrtinsert|12 years ago|reply
There are no winners in the build war despite the overwhelming online support for Gradle. Personally I'm not a fan of it. I find it on the slow side even compared to maven. I'd rather have declarative builds like Ant but therefore support better tooling than super freeform tools like Gradle that force you to drop into a language with about as much type safety as Javascript. Multi-project builds are also annoying, as Gradle has to parse and validate all the connected projects before proceeding with one single task on the build you're invoking due to its design. Very annoying stuff.
[+] pjmlp|12 years ago|reply
Gradle is mainly being pushed by Grails and Android development.

I don't know of any other project using it. We are always doing Maven or Ant.

If Gradle is the future I hope it gets improved, I gave up on Android Studio given its dependency on Gradle and how it drags my dual core with 8 GB to its knees when compiling.

[+] jayd16|12 years ago|reply
You should be skeptical. Many Android projects don't use Gradle. Gradle itself might be stable but Gradle issues are at the top of every single Android Studio release notes.

When that stops happening I'll start thinking about Gradle.

[+] java-lang|12 years ago|reply
> I'm a little skeptical of this.

The title did warn that it is an opinionated guide.

I think most projects that used Maven before Gradle don't have enough incentive to migrate. A lot of the new projects, however, start out with gradle: Vert.x, Crate.io, RxJava.

[+] bananas|12 years ago|reply
This. I can't see myself using Gradle any time soon. Literally everything I've touched is maven only and I don't want to learn another DSL on top of yet another language.
[+] EdwardDiego|12 years ago|reply
Yep, Maven is the defacto AFAICT. But so is Java 6 currently.
[+] lmm|12 years ago|reply
The #1 thing you need to make Java usable is to abandon the JavaBean conventions. When every field requires 8 lines of boilerplate it's no wonder the code looks ugly (YAGNI, and if you do need it it's two keystrokes in your IDE to "encapsulate field"). public final fields are fine, and can get your data classes something close to readable.

I'd stick with maven for the build rather than Gradle; it's completely declarative and all the tools understand it. Learning a new language just to configure your build tool seems excessive.

[+] emsy|12 years ago|reply
For starters, you can see Groovy as "Java without semicolons". I went from Maven to Gradle and never looked back. It's superior in most ways. The tooling could be better though.
[+] levosmetalo|12 years ago|reply
I used Project Lombok back in the days to get read of Javabeans boilerplate. Just declare your private fields and put @Data annotation on class, and it would generate at compile time all your getters, setters, equals, toString, constructor and hashCode methods. Really helps to keep the code lean and small. Don't know does it work with Java 8 though or it didn't yet catch up.
[+] exabrial|12 years ago|reply
Couldn't agree more. Use public, protected, private fields as they were meant to be used. I only dip into JavaBean anymore if I need a readable but non-writable field.
[+] umut|12 years ago|reply
Couldn't agree more.. But this comes with the most cliche discussion with a smartass looking at your code. Dude, I know what getters and setters are, I just don't agree
[+] zwieback|12 years ago|reply
I'm using Java for the first time because of Android. I had played with Java when it first came out but have stayed with C/C++/C# for almost everything.

I have to say that my Java experience isn't as unpleasant as I thought it would be. I always thought C# is what Java should have been but after learning a little idiomatic Java the reality is quite okay, really.

[+] nmjohn|12 years ago|reply
The way you phrased that sounds to me like you've been programming for a significant amount of time. If that is the case, the Java of today offers so much that a younger Java did not, and I suspect you would have had a more unpleasant with the java of 10 years ago.
[+] kasey_junk|12 years ago|reply
In a lot of ways C# is still a much superior language than Java, but the JVM (I'm thinking HotSpot) is tremendously better than the CLR.
[+] peterashford|12 years ago|reply
Anyone looking at where "enterprise" Java went - the whole J2EE monstrosity - would have run screaming. But the basic language is actually quite good and has been for a long time.
[+] tieTYT|12 years ago|reply
That pluggable type system looks amazing. One thing that's weird to me is how java included a new Optional type (seems similar to Haskell's Maybe), but the compiler (afaik) doesn't prevent you from setting an Optional field to null. Something about that doesn't feel right. (Side Note: Optional isn't serializeable. Also... what's the best practice for using Optional when I'm using JPA? Can it be used in my Entities?)

I believe Jetbrains/Intellij-IDEA has created annotations for @NotNull/@Nullable, but afaik these just create warnings in the IDE. Maybe you can configure IDEA to mark these as compiler errors, but I don't know if my peers using netbeans/sublime/whatever would be able to notice when they write code that IDEA will refuse to compile.

I want compilation to FAIL in these cases.

[+] ryanobjc|12 years ago|reply
A lot of people love to hate on Java, but it's a surprisingly dynamic language and there is a ton of great testing, networking, and many other libraries available.

One of the things I appreciate about Java is the ability to take large teams and just have their stuff work together, without having unhuman discipline around super subtle rules (eg: C++)

Also, IntelliJ is a must have!

[+] cwufbt08|12 years ago|reply
In what way is Java a "dynamic language" ?
[+] a8da6b0c91d|12 years ago|reply
> super subtle rules (eg: C++)

C++11/14 is in practice not that much more difficult to write well than Java. It's not 1998 anymore.

The language is larger and more complex than Java, but it's also a lot more expressive and powerful, not to mention faster.

[+] leorocky|12 years ago|reply
I love Java, especially Java 8. But as the article points out, what frustrates me is threading. You can't do much without quickly running into threading issues. I played audio files in a game I made and it created up to 2,000 threads and crashed. Once I wrapped audio in an explicitly created thread this issue magically went away. Any kind of UI, timers, file I/O and network activity also involves threads.

The really horrible thing about these threads in Java is how hard it is to not share memory across them, because if you do terrible things happen. In other platforms you don't have to involve threads unless you want to, and you definitely aren't boxed into a situation where it becomes easy to accidentally share memory across theads.

I like Go's way of handling this. node.js is single threaded but the event loop makes it possible to do non-blocking IO without crazy Jave thread issues. Using synchronized, atomic properties and locks is not the right way to do these things as your code gets really complicated when trying to do basic things.

That gets me to my other pet peeve with Java. Just how much boiler plate there is to do basic things like opening up encrypted TLS TCP connections. Tons of cruft.

Anyway, having said that, I love Java and use it, but these things need addressing. I like Scala's Akka, I hope Java comes around and improves the horrible thread situation. I will have to check out Quasar. I know I just need to become more familiar with threading in Java in general. I'm actually pretty new to Java.

[+] jebblue|12 years ago|reply
Good article, lots of opinions but the title forewarns. For me, Eclipse is still very good and if anything, more stable than in earlier years. I've tried NetBeans and the free IntelliJ but though those are fine, Eclipse is better for me. The real trick is to _not_ store your code in the workspace (which is ironically where the project wizards default to unless you change it). Store your code in as an example, svn for Subversion, git for Git, etc. Use the workspace as just a shell to manage Eclipse preferences and such.
[+] agibsonccc|12 years ago|reply
I finally switched off of eclipse for intellij. It's light years ahead of eclipse in terms of speed and response times.

One of the things I liked was how easy it made things by allowing eclipse keybindings to be used. Ever since I enabled those, things have worked exactly the way I would expect.

I also like the work flow with git. A common example I like is the prompt for adding files to your repo automatically upon creation, this way I don't have to think too much about it.

Just my 2c as an eclipse user converted.

[+] bradleyjg|12 years ago|reply
As an eclipse user this suggestion intrigues me, but I'm not sure what the workflow would actually look like. Do you have a pointer to an article or something? Thanks.
[+] smrtinsert|12 years ago|reply
I do this, or have started to since I've been using git more. I also do it with large projects. Only my truly disposable projects are in the workspace.
[+] eranation|12 years ago|reply
The biggest take I have from this post is that apparently they have created go-like lightweight threads for the JVM with Quasar (http://docs.paralleluniverse.co/quasar/) which is really interesting.

If I understand correctly, Quasar uses bytecode instrumentation to enable user-mode threads for the JVM, and they claim they did benchmarks that show X6 to X12 better performance than native JVM threads: http://blog.paralleluniverse.co/2014/02/06/fibers-threads-st...

This is really something that caught my attention.

[+] Terr_|12 years ago|reply
Something that really resonates with me from the linked PDF ("Blue-collar language") published in 1997:

> What I found most interesting in watching people use Java was that they used it in a way similar to rapid prototyping languages. They just whacked something together. I was initially surprised by that, because Java is a very strongly typed system, and dynamic typing is often considered one of the real requirements of a rapid prototyping environment. [...] you find out fast when something goes wrong.

Despite working in JS and Python, sometimes I feel more comfortable hacking something up in Java, because every missing method or undefined variable is an unavoidable short-term TODO.

[+] pnathan|12 years ago|reply
I appreciate the modern Java style espoused here, it's much further away from the horrible overdesigned & pointless configuration style I often see with Java.

However, the author doesn't really understand why C++ and dismisses it quickly. The short answer is C++ gives control and abstraction on demand, an unusual combination. Java trades control in exchange for GC.

[+] benjaminpv|12 years ago|reply
Ironically the Java ecosystem could stand to use some garbage collection of its own: there's a ton of old, outdated info out there that both colors people's impressions of the language and teaches new players a whole manner of bad habits. I appreciate what this article's going for and hope there'll be follow-ups.

I use Java daily and though there's undoubtedly room for improvement (I'm looking forward to when tooling better supports stuff added in Java 8), I think a lot of the negativity that surrounds it is undeserved. There's definitely bloated XML-infested frameworks out there but the core's a real workhorse.

[+] spopejoy|12 years ago|reply
> In this example, Java is rather annoying, especially when it comes to testing the type of a message with instanceof and casting objects from one type to another.

Using instanceof is an antipattern 99% of the time, easily avoided with proper API design. In this case a simple enum type would help with appropriate getType() method on the event; or a polymorphic event API with dedicated method types for each event (LifecycleEvent marker interface with ExitEvent subtype containing onExitEvent(ExitMessage m), etc), or ... or ...

Writing an intro to Java + touting your company's API + blaming Java for yourco's API problems: seems like bad form.

Which reminds me: can someone explain how actors is any different than using messages and queues for concurrent programming? Unless it also implies "magic translation of messages to method calls" which makes me uncomfortable (bad memories of CORBA/Web services)

[+] agibsonccc|12 years ago|reply
It's ironic, I'm slowly trying to move my development over to scala. I'll likely integrate gradle in to my stack (still use maven =/ mainly because I know all of its weird quirks)

What have people's experiences with gradle been? I'm not a huge fan of groovy hence why I stayed away from it.

[+] DennisP|12 years ago|reply
The position of things like Netty and Undertow at the top of the techempower benchmarks has me a little intrigued. How much hassle is it to write websites with servlets like that?
[+] ninjazee124|12 years ago|reply
I went from Java to Scala and am back to Java 8, and couldn't be happier with my choice. We are also using the latest Spring 4 framework which plays well with Java 8.

A lot of the Spring + Java haters haven't really looked at all the improvements have happened to both Spring and Java recently, either that or they just like to bounce off what they read online without any actual experience.

It's a solid stack for a backend, and I have built the whole platform on in without a hitch.

[+] netcraft|12 years ago|reply
What about dependency injection in modern java - is Guice or spring still the de facto standard?
[+] monkmartinez|12 years ago|reply
I have come full circle in a way. I started learning Java in school and built a few, small things for Android and the desktop. Then I was "all like;" I am going to learn the hotness which was(is?) Node. Node is what it is and I didn't really care for it. Then I moved on to Python and I really like it. Python is awesome for many, many things but GUI applications are not one of them. I have since returned to some Android development and I am diving into a CRUD web app in Java. Simple stuff, but it needs to be fast.

Looking forward to part 2 and more!