Java with its finger on the pulse
Java and its whole ecosystem face major new challenges from shifts in mobile devices, the volume of data processed and the number of users. Integrating applications built with different technologies goes hand in hand with these changes. The key question is how the Java platform can respond and retain its status as a key technology. This article can't and doesn't aim to answer that question. It will try to describe the main challenges and the paths Java might take.
A step sideways
The first and right question is why all this is happening. One answer lies in a box labeled Business, which programmers have trouble getting to grips with and are all the more likely to ignore. History shows that only a handful of programmers (it doesn't take much effort to guess their names) understood this and managed to turn a technical advantage into commercial success. That's also why most technology companies aren't headed by programmers but by people who have managed to connect the two worlds. Everybody has innovative ideas, whatever their education, job or age. Only a smaller group of people can start putting those ideas into practice. Fewer still can keep working on them and developing them. The smallest group can turn them into success [1].
The first key variable is how long it takes to get an idea to the point where it can make money [2], whether you're an individual or a company. The second is the cost involved, both startup and ongoing. Choosing the right technology and platform is one way to cut time to market substantially. Renting can reduce costs to some extent, in the virtual world as well as the physical one.
Besides time and cost, factors we can't control play a direct role too. According to World Internet Usage statistics, 360,985,492 people used the internet at the end of 2000, rising to 2,095,006,005 by the end of 2011 [3]. Looking at different kinds of activity gives a sense of the volume of data. Flickr, for example, hosted 5,000,000,000 images in 2010. That same year, 25,000,000,000 messages, or tweets, were sent on the social network Twitter [4]. Cisco estimates that 15,000,000,000 devices will be connected in 2015 [5]. Put simply, many users use many devices and produce a lot of data. Another change that's hard to put into numbers is how people use the web. There's been a marked shift from reading static pages to dynamic behavior and web applications. This shift is called Web 2.0.
The figures above go a long way toward explaining the rise of approaches and technologies such as cloud computing, NoSQL databases or HTML 5. In turn, these technologies have brought and continue to bring some changes to application architecture. They also have a direct effect on how applications themselves are developed. In the mid-1990s, two-tier architecture with a so-called thick client predominated. At the start of the new century there was a move to three-tier architecture, which incidentally gave rise to Java EE, and to the concept of the thin client [6]. These days it's hard to speak of a thin client. User interface and application interactivity requirements are moving some logic from the server back to the client. That might sound like a break for the middle tier and the server, but the opposite is true. The server has to scale very efficiently to handle more and more HTTP requests.
The Java ecosystem
When people hear Java, many think only of the language. It's actually a whole ecosystem, also called a platform. It has several key components. At the heart is the Java Virtual Machine, surrounded by the language, development and monitoring tools, and libraries. The standard libraries let you work with things like the file system, and a wealth of open-source libraries covers almost anything you could need.
The language
The language is one place Java can innovate. This mainly means changing and extending its syntax. The changes may be substantial, as with lambda expressions (closures) [7] or they may be syntactic sugar, such as the diamond operator already added in Java 7. Their common problem is that they make the syntax more complex and the source code harder to maintain. Java's simple syntax and a certain conservatism are part of what keeps it popular. Backward compatibility is a much more serious problem. A hidden risk comes from the close ties between the language and the standard library APIs. Introducing lambda expressions only makes sense if APIs change too, for example the standard collection APIs such as Map and List, where lambdas start to make sense. But incompatible changes to those APIs would make it impossible to carry over a great deal of existing code. A similarly large syntax change, generics in Java 5, turned out rather badly.
Another way to innovate at the language level would be to create a completely new language. The original Java would stay as it is and a new language, let's call it Java 2.0, would be created. The problem is that nobody can say what Java 2.0 should look like or what criteria it would have to meet to survive and be at least as successful as Java. Whatever the eventual decision, the Java platform is lucky to have spawned a host of other languages. Some have more in common with Java, like Groovy, some less, like Scala, and some little or none, like Clojure. They can be used for specific tasks.
Standard libraries
One motivation for changing the language is how complicated it is to write code that scales well on the multiprocessor hardware that's widely available today. Unfortunately, threads, the memory model and synchronization primitives are too complicated in Java. Fully understanding them is a difficult hurdle for most programmers, including the author of these lines. The java.util.concurrent package introduced in Java 5 does little to change that. Erlang and other languages show that we need an even higher level of abstraction, of the kind offered by actors [8], dataflow variables [9] or software transactional memory [10]. These constructs could be provided as new standard libraries. Other changes to the standard libraries would also improve throughput, for example by adding asynchronous support to blocking APIs such as JDBC or the HTTP client.
The JVM
Changes to the JVM [11] need to address support for big data. That includes more efficient representations of strings and other data structures [12]. Managing large heaps (>10 GB) and the behavior of the garbage collector also pose problems. A full GC can stop the entire JVM for tens of minutes [13]. Alongside changes to existing behavior, the JVM will need features currently cobbled together by manipulating bytecode. The main example is continuations, freezing and restoring the current stack frame, which let you write applications based on asynchronous calls efficiently.
For deploying the JVM in the cloud, the main issue is support for a modular application deployment system. Today's deployment model won't let you specify the modules and versions the application needs, leaving the target system no way to provide those libraries. As a result, a typical application looks like a huge jumble of JAR files, with no clear way to see what's really needed. This raises memory requirements and slows down application startup, which looks more like a file system stress test because of all the files it reads.
We’re not alone
Java development suffered for a long time from overlooking trends around it. As a result, the enterprise edition, Java EE, is effectively a write-off for developing web applications. That goes double for public cloud providers. Using Java EE exposes you to major problems when developing and deploying this kind of application. The complexity of development and deployment is a major drawback. Unfortunately, most technologies in the Java EE stack are wholly unsuited to the task. Beyond purely technical issues, there are design problems in the individual technologies. Most are designed to be stateful and to shield developers completely from the environment the application runs in. With the volume of data and the need to keep development simple, application architecture is changing. Along with the return of the thick client I mentioned earlier, this means using NoSQL databases as an alternative to relational ones. It's a quiet revolution, like the one Ruby on Rails started around 2007, and it will influence Java development, technologies and libraries. The biggest mistake for Java and its ecosystem would be to underestimate or ignore these trends, as in 2007.
Fragmentation is both one of Java's greatest strengths and one of its greatest weaknesses. There's no single approach and set of libraries for solving certain kinds of problems. At the same time, this lets us adapt to changing conditions and pick the best combination. Let's hope Java keeps “fragmenting” under different influences and that the outdated ones make way for more adaptable ones that let us as developers turn innovative ideas into something real.
A postmortem note
Given the flood of responses to this article, I've decided to clear up a few things. My aim wasn't to disparage Java, but to look at its state today in the context of emerging trends in application architecture and development. If some readers feel that Java comes off badly in that light, that's their interpretation of the lines above. I admit one of my motives in writing the article was to break the cliché that there is one right technology and it's Java. The reason isn't that I doubt Java. It's that I believe there is no such technology and there can't be. I'm convinced that the right course for Java is to innovate in response to the world around it, rather than stand still and pretend all development revolves around it.
The full article is also available on ABC Linuxu. It was published there as part of a campaign by GoodData, where I work as a Java architect. I trust that any kind reader of one of the roughly 850 articles on this blog understands that what I write reflects my personal views and opinions, which I can always put my name to. That's why I'm reproducing the full article here, with this note and the option to comment.
References
1.
Andy Hunt, Pragmatic Thinking and Learning, page 66 — Everone has good ideas.
2. Wikipedia definition of Time To Market.
4. The article Internet 2010 in numbers.
5. BBC News Technology, Cisco's forecast for the number of devices.
6. Wikipedia definition of Client–server model.
7. Project Lambda, JSR 335, dedicated to lambda expressions.
8. Wikipedia definition of the Actor model
9. Wikipedia definition of dataflow variables
10. Wikipedia definition of software transactional memory
11. The JVM changes are overseen by the Da Vinci Machine.
12. The presentation JVM goes big data explains some of the challenges of big data on the JVM.
13. An article explaining BigMemory and how it eliminates GC pauses, BigMemory Explained a bit…
Related articles
Related CZ Podcast episodes
- #261 · Leadership
On leading people and teams. · Czech audio
- #3 · Java 6 SE, Vývoj webových aplikací
Dagi and Filemon discuss Java 6 and web application frameworks. · Czech audio
- #1 · Vývojová prostředí v Javě
The first CZ Podcast episode looks at Java development environments. · Czech audio