I’m a Java/Scala/Groovy guy, that’s not a mystery. Some people, especially the youngsters, roll their eyes when they learn about it. Old fashioned, ineffective when compared to modern languages, and doomed — that’s basically what I hear all the time. But is that really the case?
Yes, the base constructs and constraints that Java offers are old fashioned and rely on how code was written 20 years ago. Programming languages are not created in a sterilized bubble. Developers’ habits and needs are central to language design, and while inventors try to infuse innovation into it, it’d be dumb to ignore how people will actually use it. The first milestone for Java dates back in 1995, and while some of its foundational blocks looked visionary for at least 10 years, it is pretty obvious that
24 years later… not so much.
It’s not just a matter of time though. In the last 10 years, a lot has changed. Some of these things may seem unrelated to this topic, but they’re actually central to the discussion. For example, the greater availability of cheap memory played a central role in the mass re-adoption of functional programming in production software. This is then related to the adoption of the reactive programming manifesto.
Accessible and manageable cloud computing eased the conceptualization of the microservices model, which found its production role when containers became real.
The microservices model then gave dignity to programming languages that are exceptionally suitable for certain tasks, but less brilliant for others.
It doesn’t end there. The new challenges imposed by big data lead to the invention of new task-optimized database systems, capable of ingesting a humongous amount of data, which then had to be analyzed. This actually didn’t cause the birth of new languages, but a second-thought on existing languages that proved to be perfectly suitable for this task.
Not to mention the second youth of artificial intelligence scrambled everything again.
But wait a minute…
Python is now sort of the golden standard for machine learning, but if you have a quick look at its Wikipedia page, you will soon realize it’s older than Java and dates back in 1990!
What about R, a common choice for data analysis? 1993.
Why are these languages not considered old fashioned but Java is?
Because we changed, and with us, so did our challenges.
Python, for example, has always been a fantastic scripting language for utilities and data processing programs, but it is generally considered unsuitable for fat enterprise applications. But microservices are — generally — small programs and data pipelines are made up of small, well defined, mostly functional steps.
To conclude, the reason why Java is considered old-fashioned is that it is well suited to build fat, mostly monolithic applications, with millions of lines of code, requiring a lot of planning and rigorous order, which Java requires by design.
I often use this metaphor to explain Java:
If you need to build a matchbox, you first take 10 tons of lumber, build a log, and then whack it down to a matchbox.
As Java imposes a formal, rigorous approach that encourages the creation of proper class hierarchies, it is unavoidable to end up working like an idiot to set everything up in the proper way, even for a very tiny task.
And that’s the thing. Given what we said in the previous chapter, no easy task stays easy in Java.
Note that by easy, I don’t mean easy to implement, but easy in terms of architecture. Writing intricate algorithms is a hard task, and I find it easier to do in Python.
It’s quite obvious, at this point, that we’re iterating over the same concept: the right tool for the job.
Java is (and has been) a very general purpose programming language and has been used to solve all types of problems, in all kinds of scenarios, but as time progresses and challenges change, it seems more and more obvious that Java is not immune to specialization anymore — not because it has evolved into a specialized language, but because of the great suitability of other languages in specific tasks.
If you’re building a large scale enterprise platform (or at least the central node of it) with lots of internal orchestration, huge codebase, crazy parallelism, etc. Java is still a beast. Wait, is it…?
Java Is Doomed
Sort of, as explained in this dark motivational quote: “Don’t be afraid of the future, you won’t experience much of it.” You should be LOL-ing at this point…
Java is pretty much like a developer as he’s aging. You’re not as clear-headed as you were 10 years ago, but, in exchange, you are wiser, more stable, and reliable. Sure, you can still learn Rust, but it will never feel as right as it feels for a person 10 years younger than you. In the very same way, the race to modernize Java is constantly running behind, and when the new features come out, you have the impression they are becoming reality years after the proper timing. When they first introduced lambdas, for example, the reaction was not “Yay! Let’s party!” but more “For God’s sake, what took you so long?”
On the other hand, people fail to realize that the greatest achievement of Java is not the language itself.
An Exceptionally Good Ecosystem
What still brings me back to Java when planning large-scale software is the ecosystem. Java offers superb and quality libraries for anything you can dream of all over the Internet.
Think about Spring, Akka, Tomcat — I could name hundreds — these are not garage projects but extraordinary achievements. I don’t mean this cannot be done in other languages, but the way the big business propelled Java created the preconditions for such software to come to life. It took years to get here, and the time factor is also very important as 20 years on the edge is a long time for the ecosystem to mature.
You can find exceptional libraries for many languages, but you quickly realize whether they exist or not depends a lot on whether a large company endorsed the project.
You Actually Mean the JVM
The biggest achievement of Java, other than its huge ecosystem we previously mentioned, is the JVM. While the language may suffer due to age, the JVM looks healthy based on what us regular humans can understand.
Now, some may say that containerization killed the need for a JVM, and in some sense, that is the case. The original need for the JVM was, in fact, to allow a program to be executed on any OS, but containers changed everything in that regard, as a container provides a simulacrum of an OS that can be executed anywhere (on paper).
But the JVM has become more than that. Memory management and garbage collection, security, fundamental programming libraries, and debugging and inspection capabilities — all these items made the JVM a very safe, comfortable place.
“But the JVM is so HEAVY and SLOW!” This is a classic pushback I receive, and while this is partly true in its memory footprint and bootstrap times (which makes it quite unsuitable for task-oriented programs), from the performance point of view, a few things happened in the last 20 years or so.
Here are a few benchmark comparisons using popular algorithms:
While this kind of benchmark doesn’t do justice to the involved languages because algorithms are just part of the story, you can clearly tell that the JVM is definitely not a sick elephant dragging itself to the graveyard.
I sort of agree that, while the JVM is alive and well, Java is struggling to keep its spot under the sun. Oracle knows that and is trying to push hard on the gas to make Java great again and while this is delivering some exceptional results, no one really thinks that will halt the aging process. And it’s not a bad thing.
The JVM served as a platform for the creation of more modern, effective languages. Not many, to be fair, but some very successful ones.
And that’s the point. The king is not dying, but that cough also doesn’t sound good. However, its offspring is here to pass on its legacy.
- Scala. My second love. A very powerful language that is statically-typed, object-oriented, and functional. While still not widely adopted, it is currently one of the most economically rewarding skills to master. Often enriched by the Akka actor model implementation, it’s the language powering the Play Framework;
- Clojure. A very well accepted dialect of the Lisp language and renowned for its spectacular capabilities in concurrent computing, it is often used to crunch huge data sets.
- Groovy. A dynamic programming and scripting language I generally refer to as a Java dialect (but I’m sure the creators do not agree). Widely adopted for scripting purposes, Groovy is also the language that powers the Grails framework.
- Kotlin. Last but not least, the statically-typed, object-oriented, and functional language by JetBrains is now the go-to tool for Google Android development.
And we’re not talking about mere extensions of Java. These are brand new programming languages that certainly borrow something from Java, but most of all, they make good use of the JVM and the Java ecosystem.
The Java programming language is not going anywhere anytime soon.
Not only because of the humongous amount of software that has been built with it, but also because whether you agree or not, with all its defects, it’s still a very suitable, battle-proven option for new projects.
Its role changed, for sure. From The-Only-Thing-You-Need, it is now one piece of the picture, but a solid one.
Even considering my fatal attraction to Scala, it must be said that Oracle and the community are doing a decent job in improving Java, and we’re all enjoying the advantages of such advancements. The quality of the new features can very well fix the aftertaste of them being a little late on our imaginary schedule.
After all, slow advancements in the evolution of a programming language can either be a sign of abandonment, or a sign of success. Breaking changes are to be taken seriously when your language is being used in such a huge scale. Every step you make will need to consider what the impact will be, and how that influences backward compatibility. Not something to be taken lightly.
I have the presumption to believe I’ve been in this field long enough to understand some of its idiosyncrasies. The evolution of this space has accelerated in the last 10 years for sure, but progress comes mostly in lumps.
And when that happens, you may have the feeling everything is about to change. These lumps of progress come with their crew of over-excited ideologists who stump and yell. But when the dust they kicked up settles, that is the moment where you can clearly see the true nature of the achievements and rationally make the best out of them.
Java is not going anywhere, as I said, but its struggle to make the best out of these achievements is far from being won, in my honest opinion.
My suggestion to all of you, young and old, Java lovers or haters, is:Enjoy the variety that this wonderful technology era has to offer!