
An Opinionated Guide to Modern Java Development, Part 1 - pron
http://blog.paralleluniverse.co/2014/05/01/modern-java/
======
cpprototypes
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
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.

~~~
_pmf_
The question is what Oracle would lose by licensing real Java to Google at
reasonable conditions. Mobile non-Android Java is deader than dead.

~~~
pjmlp
> Mobile non-Android Java is deader than dead.

Lots of embedded devices make use of J2ME, e.g. cars, manufacturing,
electricity monitoring...

~~~
thwarted
How many of those will get Java 8 updates?

------
bsaul
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.

~~~
twistedpair
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.

~~~
andyroid
I did a side project in Play! some time ago. While it was generally OK to use,
Java in Play is definitely a second class citizen compared to Scala. Most
documentation (which btw is sorely lacking) concerns how to do stuff with
Scala and you'll have to figure out how to do the same in Java yourself.

Even worse, breaking backwards compatibility between even minor releases seems
to be standard for this framework. So once you've finally managed to find some
piece of documentation from some random source on the net (as again, the
official documentation is pretty much a joke) you'll find that it doesn't work
at all because it was written with Play! 2.0 in mind which is different from
2.1 which is different from 2.2 and so on.

Once you figure it out, it's a pretty nice framework. It's a shame so little
attention seems to be paid to exposing that in a better fashion.

~~~
anthonye
> Java in Play is definitely a second class citizen compared to Scala

Much agreed. I started a side project with a quick deadline with Java in Play
and switched to Scala (even though I had to learn Scala) just because they
played better together.

------
kodablah
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
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.

~~~
bananas
That pisses me off but the following is much worse. The commit comment that
goes:

"checked in abstract_class.cpp"

Duh!

~~~
lmm
I do that a lot, or rather my commit messages are usually "mumble" or "fixed
this" or "awookga". I feel this is more justified than the javadoc case
because you can always just leave out javadoc, whereas the VCS forces me to
put a commit message.

~~~
lomnakkus
Just a humble suggestion, but perhaps you should enter a message which states
the _intent_ or the _functionality_ of the change more explicitly. (If you're
just doing a topic branch, then sure, just say "wip" or "blah", but please
clean it up with "git rebase -i" before merging.)

~~~
sbilstein
Yes, even something trivial like "fixes whitespace" is better then nothing,
but even better is squashing or amending a previous commit. Some systems
prevent this...at my workplace once you've pushed to origin, there is no
changing the past so saying something like "Added derp.java to fix broken
build from <commit hash>" is very helpful.

------
tieTYT
> 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.

~~~
pjmlp
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.

~~~
vorg
> 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

That could be the slow, dynamically-typed Groovy in Gradle that's dragging
your machine. Gradle needs to bundle another build language. Since the goal of
statically-typed (and hence speedier) Kotlin is to make it easier to write
IntelliJ IDEA [1], on which Android Studio is built, instead of using Java,
the logical choice is Kotlin.

Gradle's developer says they'll happily support any community effort to create
additional build script engines other than Groovy, but it isn't a priority for
them right now [2]. Perhaps the Kotlin team need to kick off a Kotlin build
engine for Gradle (though because one of the Kotlin developers was a victim of
the Groovy++ fiasco, I'd understand if the Kotlin people are hesitant about
having anything more to do with Groovy ecosystem software like Gradle).

[1] [http://blog.lunatech.com/2011/08/24/scala-ceylon-kotlin-
goal...](http://blog.lunatech.com/2011/08/24/scala-ceylon-kotlin-goals)

[2] [http://www.gradle.org/overview](http://www.gradle.org/overview)

~~~
pjmlp
Kotlin was exactly the reason I was thinking to move from Eclipse ADT to
Android Studio.

So far I have been using the Eclipse ADT/CDT for my hobby development, mainly
with C++ (just graphics stuff).

Then I thought to try out Kotlin instead, but could not. It was worse than
waiting for my NDK C++ builds to finish, with the whole computer at 100% CPU
usage.

I ended up filing a ticket, like many other developers already did.

------
lmm
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
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.

~~~
lmm
> For starters, you can see Groovy as "Java without semicolons"

Not if you have to read other people's code, or understand examples you find
on the internet.

> I went from Maven to Gradle and never looked back. It's superior in most
> ways.

What's it better at? I want my build tool to be simple; maven compiles my
source and does my releases, and the main thing I have to configure is just a
list of dependencies (in an admittedly verbose format). I'm actually a scala
programmer, but I use maven rather than SBT because it seems to me that having
lots of logic in the build system could only lead to bad things. So what are
the things you see it helping with?

~~~
emsy
See my reply to vorg regarding Groovy. As a developer the argument "I don't
want to learn something new" is invalid.

Gradle offers the declarative nature of Maven without pushing it down your
throat. You don't have to write a plugin for something that can be expressed
in 3 lines of Groovy (but you can, if you want to!). Instead of adapting your
build to Gradle, Gradle adapts to your needs. That's often a point of
criticism from Maven users, because every Gradle build looks different. But
that's the point: Everyones needs are different. Of course that only applies
if your build is beyond the standard compile/test/release configuration. A
simple configuration looks pretty much like a Maven POM (minus the tag soup).

------
zwieback
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.

~~~
kasey_junk
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.

~~~
pjmlp
I follow Grail and now Truffle development since the days of the Maxime VM.

Looking forward to the day the reference JVM becomes a meta-circular one.

------
tieTYT
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.

~~~
kazagistar
The main issue with non-nullable types in OOP, in my mind, seems to be
defaults. Quite simply, when you don't initialize an primitive, you get a 0,
and when you don't initialize an object, you get a null. Not all fields must
be initialized by the time the constructor ends, so some kind of valid default
exists.

Enforcing non-nullability would involve somehow enforcing that the variable is
always valid before use some other way, like how "final" is enforced in the
constructor, but it should be possible.

Unless you make it default, though, it won't be as "elegant" as the haskell
Maybe, and doing so would net you a very very different language.

~~~
pjmlp
Outside the JVM world, Eiffel does it.

In the JVM world, Kotlin and Ceylon do it as well.

------
ryanobjc
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
In what way is Java a "dynamic language" ?

~~~
shellac
I think "dynamic platform" would be more accurate. Java has typically been a
fairly conservative language sat on a much more interesting VM, a VM which has
rather more features in common with dynamic languages like Smalltalk than
you'd expect.

~~~
ryanobjc
but you can always escape with cglib and rock out.

So even though java the language isnt dynamic, you can do a lot more at
runtime, than with these new-fangled languages like Go and Rust.

------
leorocky
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.

~~~
ww520
Sounds like it's the implementation of the audio library using thread in the
wrong way. Has nothing to do with threading in Java. Nodes could have the
problem of starving the audio playback if other parts of your code hogging too
long of processing time. It's just shifting the problem around.

~~~
leorocky
I'm not using an audio library. I'm just using Clip and AudioInputStream

------
jebblue
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.

~~~
bradleyjg
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.

~~~
jebblue
Sorry no link, co-workers and as "smrtinsert" said, Git or for me having both
Git and Subversion projects makes life easier keeping source separate from the
workspace.

~~~
bradleyjg
Do you use the link source tab of the "Java Build Path" to point to the
project directory in the source control directory?

~~~
jebblue
Nope, never used that. For Git it's straightforward, I have one Git repo per
project I manage with Git. just use Import Project. The code remains where it
is at.

For SVN, I use Checkout and uncheck "Use default workspace location" and
specify the location of the code.

------
eranation
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/](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...](http://blog.paralleluniverse.co/2014/02/06/fibers-threads-
strands/#benchmarking-fibers)

This is really something that caught my attention.

~~~
pjmlp
The initial JVMs already had Go like threads, aka green threads, with red
threads being OS ones.

The language specification does not require a specific implementation and with
time all JVMs moved to red threads.

There are a few JVMs around that still support green threads as threading
model.

------
Terr_
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
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.

~~~
pjmlp
> The short answer is C++ gives control and abstraction on demand, an unusual
> combination.

Ada, Modula-3, the Oberon language family as well.

But they lacked a proper OS vendor support and faded away.

Ada seems to be raising up, thanks to GNAT and continuous security issues with
C and C++. At least from its increasing presence at FOSDEM.

~~~
pnathan
Well, yes. And more than a few other languages that got left in the dustbin of
our history. But as for today...

I actually am personally very keen on seeing where Rust goes here, but it
isn't 1.0 yet (which will be the signal for me to start writing in it
seriously ).

~~~
pjmlp
Me too, alongside D, .NET Native and the Graal/Truffle compilers.

------
benjaminpv
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.

~~~
Terr_
> old, outdated info out there

I'd love it if the JDK had a "learner mode" that _disabled interned string
literals_. Then newbies experimenting with `assert(str1 == str2)` wouldn't
leap to false conclusions.

~~~
lmm
== should never have been used for that method, which is very rarely what you
want. The right thing is probably to deprecate == on nonprimitive types,
replacing it with a longer name that's clearer about what it means.

~~~
cdmckay
Or make == call .equals and add a .referenceEquals method for the case where
you actually want to check for reference equality.

This is what Scala and C# do.

~~~
lmm
That would indeed be nice, but is incompatible with Java's approach to
backwards compatibility.

------
spopejoy
> 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)

~~~
sivanmz
Agree that instanceof is wrong and discredits the article.

I'm not sure if this is what you meant, but here is how polymorphism along
with the double dispatch pattern would work: NaiveActor#handleLifecycleMessage
will need to delegate to the event subclass, which will in turn select the
appropriate method on NaiveActor.

Example of subclass of LifecycleMessage:

    
    
            class ExitMessage implements LifecycleMessage {
                @Override
                void handle(BasicActor actor) {
                   actor.handleExitMessage(this);  
                }
            }
    
    

In NaiveActor:

    
    
            @Override
            protected void handleLifecycleMessage(LifecycleMessage m) {
                m.handle(this);
            }
    
            @Override
            protected void handleExitMessage(ExitMessage m) {
                if (Objects.equals(m.getActor(), myBadActor) {
                    System.out.println("My bad actor has just died of '" + m.getCause() + "'. Restarting.");
                    spawnBadActor();
                }
                return super.handleExitMessage(m);
            }
    
    

It's been my experience that many developers resort to instanceof or enum type
flags because they don't believe polymorphism actually works in real world
situations such as this.

~~~
spopejoy
There's something wrong with this approach, though: it couples ExitMessage and
BasicActor, in that BasicActor would have to have a method for each event
type, resulting in lots of empty methods, etc.

What I'm describing is a marker interface for eventing, with specific subtype
APIs:

    
    
      interface LifecycleListener { }
    
      interface StartListener extends LifecycleListener { 
          void onStart(Foo f); 
      }
    
      interface ExitListener extends LifecycleListener {
          void onEnd(Foo f); 
      }
    

along with a single registration method (perhaps a LifecycleObservable API, or
in a class also offering event-firing methods):

    
    
      Disposable addLifecycleListener(LifecycleListener l) 
    

The benefits to the client code are numerous: clarity (dedicated methods for
events), declarative code ('implements' section documents interactions),
performance (no dispatching in client code).

[Note, Disposable here represents a dispose() function to deregister the
listener, avoiding the classic pair of void register/deregister methods. Often
I find void methods represent a missed opportunity ... wishing Java was more
like Smalltalk here]

The service side has to jump through some hoops to efficiently dispatch, using
class equality or instanceof at registration time to pre-select listeners.
This code could certainly use pattern-matching but personally I think it would
look identical. If anything, I'm glad that pattern-matching isn't available in
this case, to at least alert framework devs to the problem and not push it off
to tons of switching on the client.

------
agibsonccc
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.

~~~
bpodgursky
IMO Gradle has made huge improvements the past couple years (when I first
started using it a few years ago it was incredibly unstable) but if you are a
semi-power user of Maven I think you're going to find yourself frustrated
using gradle still for a couple reasons (I've looked into this for my work
recently, moving away from Ivy). Note I haven't extensively used Gradle, this
is just from research:

\- Intellij has incredible Maven support, and by this point almost all the
bugs have been worked out. Gradle support is improving, but our company has
dozens of modules, a mix of Java / Clojure source code, and depends heavily on
Intellij automatic source linking working correctly, dependency propagation
working 100% successfully, etc, and it's really easy for small bugs to become
blockers. Last I checked there were still a number of pretty frustrating bugs
related to this

\- The Jenkins maven plugin is great, and the Gradle one is mediocre. For
example, it does not even handle automatic triggering of downstream builds
(this is absolutely critical for us [https://issues.jenkins-
ci.org/browse/JENKINS-19941](https://issues.jenkins-
ci.org/browse/JENKINS-19941))

\- Gradle pretty decent plugin support by now, but is not yet as exhaustive as
what you'll find with Maven (there's a maven plugin for basically everything
now)

\- This may have been resolved, but I had issues configuring getting Gradle to
update snapshot dependencies, which was really important to us.

In the end I decided to migrate to Maven to avoid these headaches. I think I
will try to use Gradle for personal projects, but I don't feel comfortable
migrating our company stack there yet.

~~~
agibsonccc
Really appreciate the insight, this is what I have found as well. Especially
using intellij, it's still hard to beat. I'm always on the look out to use new
stuff, but I'd rather wait a bit..

If I go hybrid JVM, I will likely just use SBT instead.. I think I'll keep an
eye on gradle and see if it matures though.

One of the reasons I still use maven is like what you mentioned: the tooling,
I don't find myself using xml most of the time (despite knowing it like the
back of my hand anyways)

------
DennisP
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?

~~~
pron
A bit of a hassle, but Comsat will make it dead-easy (right now Comsat runs on
top of any servlet container, but it will also run directly on top of
Netty/Undertow). Take a look at our Comsat web actors:
[http://blog.paralleluniverse.co/2014/01/28/web-
actors-1/](http://blog.paralleluniverse.co/2014/01/28/web-actors-1/)

------
ninjazee124
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
What about dependency injection in modern java - is Guice or spring still the
de facto standard?

~~~
jebblue
I try to avoid it as much as possible. It's confusing at least to me and makes
maintaining code over a long haul an arduous dull process. I'm getting to the
point where I prefer straight JDBC over Hibernate too. It takes longer to code
but I've seen speed increases of several times over Hibernate in those
situations. JDBC code is just linear but I feel it's easier to maintain in the
long run.

~~~
EdwardDiego
I agree. Hibernate has become a downright liability at times in our codebase.
These days I only use it in new code for query parameterization and result row
transforms into models.

Speaking of which, if anyone knows of a good library for query
parameterization alone, let me know...

~~~
ZitchDog
JDBI is quite good: [http://jdbi.org/](http://jdbi.org/)

~~~
umut
We use JDBI @Truecaller together with Metrics library. Not only it is clean
and tidy, it also gives you immediate profiling around your database calls.
This is priceless in a big service oriented environment. With it, you can
exactly see the rate of happening (mean/last 1/5/15 minutes average) and
latency (mean/avg/std-dev/75/95/98/99/99,9percentiles) for each database
query. I wouldn't want to go back to manual logging and optimization hell.
JDBI+Metrics opens a totally new dimension to your
monitoring/profiling/optimization!

------
monkmartinez
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!

------
kyberias
Why do people seem to think "opinionated" is a virtue these days?

~~~
lmm
Because, particularly in Java-land, if you're not opinionated you end up
providing a FactoryFactoryFactory. A beginner is in no position to weigh up
the pros and cons of the different build tools available, so it's better for a
guide to simply make a recommendation and explain that one than to give the
beginner a confusing choice.

------
wil421
>But the modern Java developer uses Gradle...there are quite a few things that
are quite, though not very, common, but still require dropping down to
imperative Groovy.

This is the first time I have heard of Gradle, but why would I use a build
tool that requires me to learn Groovy. If I already know Java I wont be
learning something new just to build a Java project.

I find a lot of development tools/frameworks make me learn B just to get
started with A, its really frustrating for someone with limited experience
IMHO.

~~~
nsxwolf
I wouldn't say you need to actually learn Groovy to get going with Gradle. The
example build.gradle files are fairly self-documenting, and you'll be
modifying them more than writing them from scratch.

Easier to read than a pom.xml, for sure.

~~~
wil421
>Easier to read than a pom.xml, for sure.

In that case I will have to check in out on a side project. My current
projects at work are using Ant or Maven and I dont really like sorting through
the pom.xml especially if someone else set it up.

------
nvarsj
I have to agree with the first comment on the blog. Gradle is strictly worse
than Maven - it's basically Ant reinvented with Groovy. It leads itself to
poorly maintained, complex build files, and the only good parts are the bits
that use Maven under the hood (so just use maven ;-)). It's also slow.

Also, if you seriously want to use an Actor framework in Java, you should use
Akka - the lead devs really know their stuff, and are active in Java
concurrency circles (JSR-166).

------
pswenson
I'd like to hear thoughts on CheckedExceptions in part 2. IMO, they are a
disaster - most projects degrade into all methods having a "throws Exception"
clause. But I'm not sure if there is any consensus on how the CheckedException
haters like myself work around them. I use Runtime exceptions everywhere, but
it's a pain/boilerplate to convert them.

~~~
zmmmmm
I think some of the additions in Java7/8 will make them a little easier to
work with. The worst thing used to be the necessity to nest multiple try/catch
blocks, or repeat identical code between separate catch blocks because
different components throw different errors. This is now dramatically helped
by the multi-catch and other additions.

Like you, I use a lot of RuntimeExceptions, but I think in it's important not
to overlook the benefit of checked exceptions: if you're trying to write
reliable software looking up and understanding every possible failure mode of
every API you are calling is an almost unbearably tedious and impossibly
boring task. In principle, having the compiler check and tell you "Hey,
there's this error that could occur and you haven't defined how your code is
dealing with that" is a tremendously useful thing. Our human tendency to focus
only on the successful path through our code and then ignore all the possible
failures is terrible bias if you're trying to make code that behaves the right
way under ANY circumstance. So I support checked exceptions, and I hope the
new improvements in Java make them more workable and accepted. There probably
need to be more improvements, something long the lines of STM type features
before we'll get there though, I think.

~~~
pswenson
1) try introducing a Checked Exception in a commonly used method. Soon you'll
be updating 100s or 1000s or methods.

2) checked exceptions don't play well with interfaces (APIs) for similar
reasons. any interface user must change their code simply because some new
checked exception bubbles up now

3) checked exceptions lead to terrible error handling and hiding bugs/system
problems. instead of letting exceptions bubble up - java coders almost always
write code that either swallows or simply logs the exception and continues
along as if nothing happened. If my bank deposit fails, I don't want the
failure to just end up in a log file - I want to know it! Exceptions were
designed to usually bubble up and be exposed/handled in a standard way at the
top level thread. They are usually not recoverable.

4) they lead to bugs. I very rarely see anyone handle the statement/resultset
handling of JDBC code correctly.

5) if they are such a good idea, why does no other language ever created has
them?

~~~
zmmmmm
> 1) try introducing a Checked Exception in a commonly used method. Soon
> you'll be updating 100s or 1000s or methods.

Try doing that in a code base without checked exceptions. You just created
100s or 1000s of unrecognised errors in other code without realising it. The
problem is not the checked exception. The problem is you changed something
100s or 1000s of things are relying on to add a new failure mode.

> Checked exceptions lead to terrible error handling and hiding bugs/system
> problems. instead of letting exceptions bubble up - java coders almost
> always write code that either swallows or simply logs ....

Well, I agree up to a point. But that is much to do with how tedious and
verbose the error handling itself is which is more about the language than the
concept of checked exceptions.

> they lead to bugs. I very rarely see anyone handle the statement/resultset
> handling of JDBC code correctly.

see above

> 5) if they are such a good idea, why does no other language ever created has
> them?

Well, you can also say, if they are such a bad idea, how come one of the
world's most popular and used language builds them into all its core APIs?
They can't be _that_ terrible or Java would never have got so popular ....

~~~
pswenson
I think you are falling into the trap of thinking you can usually recover from
an exception. Exceptions are usually caused by one of two things:

1) system error (no more DB connections, hard drive full, etc)

2) a bug

neither of these are recoverable, you just need to stop the task at hand and
notify someone that the situation needs to be fixed. Trying to handle it and
recover is usually a fools errand that results in hiding the problem

There are cases that you do want to handle exceptions. In these cases, yes
catch the exception and handle it. But these cases are the 10% case, hence the
default behavior of making the caller handle the exception isn't desirable.

This link from 2003 articulates the point better than I can:
[http://www.artima.com/intv/handcuffs.html](http://www.artima.com/intv/handcuffs.html)

~~~
zmmmmm
If Java forced you to handle the exception that would be convincing, but it
doesn't. It merely says, if you don't want to handle it, add to your signature
that you throw an exception so that at least someone upstream has a chance to
know that the error might occur. I'm not arguing at all btw that the way Java
does it is good. Merely that there's a case for checked exceptions, especially
if you are actually trying to write "reliable" software.

------
laureny
Not a single mention of Guice or even dependency injection?

Seems like a gaping omission in a guide that claims to be about "modern" Java.

~~~
venomsnake
Dependency injection and any othee type of code indirection is evil imo.
Anything that breaks the ability to find your way in a codebase with something
other than grep brings more pain in the long run than it saves.

~~~
rat87
grep is a that good even for for c++ or dynamic mojo. Java is statically typed
and has many ides and tools that understand code structure.

~~~
rat87
isn't that good

------
lightblade
> ...simplicity of Maven...

Did I read that right?

------
pit
Does anyone here do Java development sans IDE -- like, say, with Emacs?

~~~
darylteo
When I taught programming I made my students do all their programming in
notepad++/sublime text.

------
AmrMostafa
If you have come to this post expecting to read something related to modern
Java for the web, and have come back unsatisfied, then here is something to
make up for that: yeoman's jhipster generator:
[http://jhipster.github.io/](http://jhipster.github.io/)

Presentation:
[http://jhipster.github.io/presentation/](http://jhipster.github.io/presentation/)

------
elchief
What did the Eclipse team do so wrong to fall so fast?

Also, what are Maven's fatal flaws? I don't consider XML a flaw.

------
hugofirth
Another great Java resource (though admittedly the current edition is focused
on Java 7) is "The Well-Grounded Java Developer" by Evans & Verburg [1].

[1]: [http://www.manning.com/evans/](http://www.manning.com/evans/)

------
loup-vaillant
> _depending on the exact usage, a large Java program can be slightly slower,
> as fast, or a little faster than a comparable C++ codebase_

This is probably true but…

Does anyone here have any data to back that up?

------
ivan_gammel
Oddly, this resource is blocked in Russia, so I was not able to read the
article from my ipad. WTF with this country. Anyone knows if I can penetrate
Great Russian Firewall on ios?

------
eranation
> But enough writing Go in Java. Let’s try Erlang.

Nice

------
cs02rm0
_Quasar is an open-source library made by us_

Quite enjoyed the article until that got jammed in there.

~~~
anthonye
Modern Guide to Java... using our tools.

------
hyp0
+1 for markdown inline docs.

A simple, obvious, useful idea I hadn't seen before.

------
0800899g
modern java

------
jg03
You always know to expect a dreary, look-my-language-is-modern-too article
when "opinionated" features in the title. This one didn't disappoint.

