Among the most fascinating phenomena in software is the enduring prominence of Java. As both a language and a platform, Java has survived radical transformations in the technology landscape, and its own internal structure has altered along with it. How has Java remained at the center of both enterprise and open source for more than two decades? Let’s look at a few factors that stand out.
The Java Community Process
Java began life as an alternative to the conventional way of doing things—an upstart of sorts. Today, despite repeated challenges, it is recognized as a pillar of enterprise software. What explains Java’s continued relevance in the face of such radical change? One essential factor is the passion of the community, which is fostered through governance structures that engage developers to keep Java a living, dynamic force.
Far from a smoothly operating machine, Java’s governance is a confusing amalgam of competing interests and organizations that find their voice in the Java Community Process (JCP) and through Java Specification Requests (JSRs). At the end of the day, the JCP is a venue for contribution and conflict resolution among people who care deeply about Java technology. It is a rather mystifying combination of bureaucracy, policy, and creativity. Something like a functioning democracy, in fact.
As a longtime Java programmer, it was surprising—astonishing, actually—to watch the language successfully incorporating lambdas and closures. Adding functional constructs to an object-oriented programming language was a highly controversial and impressive feat. So was absorbing concepts introduced by technologies like Hibernate and Spring (JSR 317 and JSR 330, respectively) into the official platform. That such a widely used technology can still integrate new ideas is heartening.
Java’s responsiveness helps to ensure the language incorporates useful improvements. it also means that developers know they are working within a living system, one that is being nurtured and cultivated for success in a changing world. Project Loom—an ambitious effort to re-architect Java’s concurrency model—is one example of a project that underscores Java’s commitment to evolving. Several other proposals currently working through the JCP demonstrate a similar willingness to go after significant goals to improve Java technology.
Open source frameworks and tools
Another big driver of Java’s success is the wealth of open source frameworks and tools built up around it. Almost anything you might need has one or more available libraries. If you like a project, there is a good chance it’s open source and you can contribute to it. That’s great for both learning and building community.
Not long ago I had my hands deep in parsing YAML, and discovered the SnakeYAML project. Soon, I was off in the weeds trying to do something exotic with this new project. Not long after that, I was chatting with the project’s owner.
Something similar happened when I needed to do some sophisticated process orchestration close to the metal. First, I discovered the NuProcess project, then I got to contribute a small fix. Exchanges like that make a programmer’s life richer. They’re also how open source projects evolve.
The wealth of projects in the Java ecosystem extends from modest examples like the ones I’ve shared to database drivers and similar technologies, on up to the monumental. There are application servers like Tomcat and Jetty, frameworks like Hibernate, and even the Eclipse IDE. All are open source projects that invite contributors.
Spring dependency injection
No appreciation for Java’s ecosystem would be complete without tipping our hat to Spring. This meta-framework is perhaps the standard to which other meta-frameworks might aspire. Why? Because Spring lets you use the same facility for composing custom code and incorporating third-party code in your programs. Through its implementation of dependency injection and inversion-of-control, Spring not only enables you to make your own internal components more standard, but it extends a similar standardization to how third-party projects and vendors prepare their components. This makes for greater consistency in how you use these components in your programs.
Of course, there are valid critiques of Spring, and it’s not always the right tool. Google Guice is another tool that works similarly to Spring. But Spring, as a framework, introduced a clean and consistent way to provision and compose application components. That was a game changer at the time, and it continues to be vital today.
Everything is an object
If the people behind Java and using Java are the wind that keeps the ship sailing, then Java’s technical aspects are the sails. It is impressive that the initial Java specification sprung Athena-like from a single head (the head of James Gosling) but has remained flexible enough to still be relevant today.
An important feature of Java’s design is that, in Java, everything is an object.
In a development landscape that currently favors functional programming, it’s sometimes fashionable to trash this aspect of Java and object-oriented programming. Java’s stewards have responded by incorporating some functional programming idioms into the language. But they’ve been steadfast in that Java remains a strongly object-oriented language where everything is, indeed, an object.
It’s possible to write code that is awesome or awful in any paradigm. Going into a Java system, you know up front that it’s strongly typed and that everything is contained in classes. The absoluteness of this design decision cuts away complexity and lends cleanness to the language and programs that use it. Well-written Java programs have the mechanical elegance of well-written object-oriented code. The functionality is the result of interacting components, like gears in a machine.
The cost of this approach is confusion in the early stages of learning. Virtually every Java beginner confronts key questions: what is the
public keyword there for, what is a class, and why on earth do I need to write “
public static void main(String args)” just to print “hello world”?
But consider that those learning curves are potent aspects of a large-scale order: The beginner is encountering and absorbing sophisticated concepts that are fundamental to the Java way of doing things. You could say that the strictly class-based structure of Java programs lends itself to good programming-in-the-large. As systems grow in size, the structure, which might seem unwieldy at a smaller scale, becomes more beneficial. In many cases, it vindicates the burden of early-phase learning.
The Java virtual machine is another facet of Java’s construction that meets with occasional critique. At the time of its development, the JVM was a bold technical solution to the diversity of runtime environments. Since then, it has sometimes seemed a burden of excess architecture and a source of performance difficulties. But after years of incessant refinement, the technology has gradually vindicated itself. It has proved rather prescient, as well. The world has lately become enamored of virtual machines; they are everywhere, even forming the lowest strata of cloud computing.
Applied to devops containers and serverless architectures, the JVM offers a clear-cut deployment environment target, with well-defined characteristics and controls. Modern Java virtual machines are also something to behold. They deliver sophisticated automatic memory management with out-of-the-box performance approaching C.
Software development is made up of two powerful currents: the enterprise and the creative. There’s a spirit of creative joy to coding that is the only possible explanation for, say, working on a dungeon simulator for 25 years. That creativity, united with solid business use, is the alchemy that keeps Java alive and well. For long-term success, a software project must make room for both. Java has done that.
WebAssembly and the future of Java
Copyright © 2022 IDG Communications, Inc.