Java is not Dying (Yet)
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 compared to modern languages, doomed, that’s basically what I hear all the time. But is it really the case?
Old fashioned
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 in 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, lots of things changed drastically in this field. 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. Which 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.
JavaScript? Curiously, 1995, just like Java.
Erlang? 1986…
Why are these languages not considered old fashioned but Java is?
Because we changed, and with us, our challenges.
Python, for example, has always been a fantastic scripting language for utilities and data processing programs but 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.
JavaScript has always been the sole solution to make web pages dynamic, but with the proliferation of complex web applications, it was reasonable to bring it on the server side as well.
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.
Try to do the same with JavaScript, and you will quickly realize that “death is not the end, but only a transition” (cit.).
Ineffective
Relatable.
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, 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 LOLling at this point…
Java is pretty much like a developer as he’s ageing. You’re not as clear-headed as you were 10 years ago, but 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 big sized software is the ecosystem. Superb quality libraries for anything you can dream of all over the Internet.
Think about Spring, Akka, Tomcat, and 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.
For example, it’s super easy to find good machine learning libraries for Python, and you can’t say Google didn’t play a role in it, you can develop brilliant web applications with React.js (Javascript) thanks to Facebook.
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 its age, the JVM looks well and healthy for 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, debugging and inspection capabilities. All these items made the JVM a very safe, comfortable place to be.
“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.
However…
I sort of agree that, while the JVM is good and alive, 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 ageing 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 doesn’t sound good. However, its offspring is here and healthy.
- Scala. My second love. A very powerful language both 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 Play Framework;
- Clojure. A very well accepted dialect of the Lisp language. 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, both statically-typed object-oriented and functional language by JetBrains, 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 which certainly borrow something from Java, but most of all, they make good use of the JVM and the Java ecosystem.
But realistically…
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 as well.
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 quite 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 extremely 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.
Conclusion
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 goes back down, that is the moment 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: