Some kayakers that I know have a death wish. They bomb down Class V runs with reckless abandon. It seems like a matter of time before they run that waterfall that has trapped deadwood underneath it. Such an obstacle would trap the boat, and the force of the river would pin the boater underwater. They're like ostriches, ignoring the danger with their head in the sand.
There's another kind of boater, though. When I first started kayaking, I scouted everything. I would stop at the most casual Class II+ (beginner) ripple to look it over and set up safety ropes for 45 minutes before making the run. Often, I'd run out of time on a river, and be forced to bomb down a bottom section to complete it before nightfall. Now, I rarely get out of my boat to scout most minor rapids. In certain places, it's just not practical. Instead, I use chase boating techniques, invented in the narrow, steep rivers of the Southeast, to improve my chances. I don't boat this way because I like danger. In fact, I've honed my instincts to understand where danger is most likely to be. I boat this way because it lets me focus my scouting time where I need it most. These boaters are the owls.
It comes down to this. I'll often ignore risks involving minor consequences or low frequencies because dealing with the risk is not wise. Managing the risks properly may take too much effort, money, or time, opening me up to additional risk, which brings me back to owls and ostriches
. Normally, there's a huge difference between the two, but occasionally, owls will get overconfident or make minor errors in risk assessment, and convince themselves to run something dangerous without scouting. That's happened to me. I've run the same creek hundreds of times, and something changes like higher river levels or the creek bed after a flood. There's a fine line between owls and ostriches. Sometimes, it's even tough to tell the difference between the two. As a kayaker, even if I've decided to ignore certain kinds of risks on certain rivers and conditions, I've sometimes got to step back and reassess the risk. That's the subject of this book.
Additional content appearing in this section has been removed. Purchase this book now or read it online at Safari to get the whole thing!
In many ways, kayaking is like programming. I've learned an incredible trick. I can be surprisingly productive by simply ignoring most problems. With a little luck, the problems often just go away. Such an attitude can work for you or against you. Many post office clerks and minimum-wage fast food employees have learned that the same technique actually works for their problems, also known as customers. These are ostriches. If you look closely, you can find some selective, wise application of ignorance—the owl's trademark. I actually find that most "problems" in programming are merely potential problems. If you've read any of my books, you know that I preach against the dangers of premature optimization, and echo the popular agile principle of YAGNI
: "You ain't gonna need it." I usually ignore bloated frameworks that promise to save me time, trusting my instincts to simpler solutions.
More to the point, I've found that Java does everything that I need, so I haven't looked beyond these borders for a very long time. Ignorance is bliss. I know some languages are more dynamic, and possibly more productive in spurts, but in the end, it seems like Java will always win. It's got tens of thousands of frameworks to do anything from running systems for nuclear reactors to programming an embedded controller on a power toenail clipper. Many of the best frameworks are even free. I can always find a Java developer to do what I need. I know that people have made it work to solve massive problems. And I know that my customers will feel safe and secure. In short, the community and breadth of Java have always trumped anything that the alternatives have to offer. So I quit looking. And I'm glad that I did, because it allowed me to focus on building a consulting business and satisfying my customers instead of doing exhausting research for every new problem.
When a dominant language or technology is in its prime, there's a blissful ignorance stage, when ignoring alternatives works in your favor. Figure 1-1 shows what I mean. When a new language arrives with the power and dominance of a Java or C++, you can afford to ignore alternatives for a while. But if you don't accurately identify the end of the cycle, you can get steamrolled. Suddenly, your competition has the jump on you, with much better productivity leading to better quality, improved productivity, and more customers. When you enter the transition time, you'd better start paying attention.
Additional content appearing in this section has been removed. Purchase this book now or read it online at Safari to get the whole thing!
Let's look at it still another way. You've doubtlessly heard that if you put a frog in hot water, it will leap out, but if you slowly bring tepid water to a boil, the frog will die contentedly. And of course, that's the debate that I hope to trigger in this book. Are the waters around us warming? Notice at the end of my introduction, the owl and the ostrich are exactly the same when it comes to consequences. They may not recognize it, but motivations don't matter one little bit. If the water starts to boil, if the conditions on the river change, they'll both die.
This past year, I decided to wake up to my surroundings to test the water around me. I learned both Ruby and aspect-oriented programming (AOP)
. After checking the temperature, I think the water is actually heating up. It's not boiling yet, and I don't know if it will ever boil. But I do know that I'm going to keep a close eye on the temperature for a while, and I hope to convince you to do the same. Let me tell you why.
A large number of the applications that we write put a web-based frontend over a database, sometimes with additional business rules and sometimes without. Yet, after more than five years of solving this problem over and over, we still can't solve it very quickly in the Java space. Further, most Java framework developers are making incremental changes that won't truly revolutionize web development. Building a new team to solve this problem in the right way is a demanding job. Building a team from, say, COBOL programmers, is nearly impossible. The language is too alien, the frameworks too extensive, and the landscape too unstable. Even with seasoned developers, it takes a surprising amount of code to get even simple applications off the ground.
Author of Java Servlet Programming
Additional content appearing in this section has been removed. Purchase this book now or read it online at Safari to get the whole thing!
Keep in mind that I'm a cynic at heart. When it comes to technologies, it takes a whole lot of effort to get me excited. I still have never written a web service, at least with the massive IBM and Microsoft stacks, and I didn't write my first EJB until 2003. I've never written an EJB entity bean unless it was to build a case against them, and never will. I've instead preferred simpler architectures, like REST, POJO programming, transparent persistence, and Spring. Even then, I was late to those parties.
It's even tougher to get me to play with a new language. Dave Thomas, a highly respected programmer and a gifted teacher, is fond of saying that you should learn a new programming language every couple of months. I've probably averaged one every five years, and I rarely do more than dabble. But recently, in my dabbling, I've found a couple of startling innovations. These frameworks had ideas that just about reached out and ripped me out of my chair this year.
I've taken a little more time than usual to survey the interesting innovations around new programming languages. When it comes to building web pages and application servers, two ideas have my undivided attention: metaprogramming
(like Ruby on Rails) and continuation servers
(like Seaside on Smalltalk). Neither of these two innovations is happening with much impact in Java. You'll get a deeper treatment in Chapters 7 and 8, but it's enough to say for now that they are both many times more productive than their Java alternatives.
Java is a language with many compromises
. Many of the features of Java are appropriate for building operating system extensions and middleware, but limit application development. Consider this Ruby fragment:
something = "Owls and Ostriches"
4.times {puts something}
These simple little lines of code print Owls and Ostriches four times. Look at the power in this language:
You don't have to worry about details like typing, if you don't want to. If it walks like a duck and quacks like a duck, Ruby will type it as a duck. This saves more time than you think.
Additional content appearing in this section has been removed. Purchase this book now or read it online at Safari to get the whole thing!
I don't mean to say that Smalltalk or Ruby will take over the world tomorrow. I don't even mean to say that anything will ever achieve the success that Java has, again. But I don't believe that Java is permanent. For five years, it's been a good strategy to ignore the borders beyond Java, but no language will keep its leadership position forever. By now, the premise of this book should be taking shape for you:
Java is moving away from its base. Hard-core enterprise problems may be easier to solve, but the simplest problems are getting harder to solve. And...
Java is showing signs of wear, and interesting innovations are beginning to appear outside of Java. So...
It's time to start paying attention again.
Pick up your eyes. Start by picking up this book. You'll be glad you did.
Additional content appearing in this section has been removed. Purchase this book now or read it online at Safari to get the whole thing!
The power and the fury of the storm caught us off guard. El Niño, a weather pattern famous for producing a continuous stream of storms in Texas, seemed to misfire over and over. The core of the Austin kayaking community, dependent on storms to fuel our unfortunate addiction, sat frustrated around an ancient TV with a snowy signal, watching storm after storm split up and float completely around us. Around 11:00, everything changed. Like every day leading up to this day, a line of storms lay spread out before us like kids at a Harry Potter movie on opening day. Only this time, they punched Austin, hard.
El Niño, the split jet stream, filtered across the ocean and brought warm, moist air right across Texas. It collided with the cooler air of a cold front. The pressure system in the South fed a rotation, and locked the cool front in place. The warm air exploded into the cold and produced a perfect storm. We opened the topological maps and found a stream that had never been run. It had the steepness and geographical features that we were looking for. It simply had not had enough water. As we planned the trip, the mighty storm hurled a string of consecutive lightning bolts right near a hilltop, less than a mile away. Distracted, we stared into the night, alternately black and blinding.
To know where Java is going, you've got to know where it came from. You need to remember the conditions that caused us to leave the existing dominant languages in droves. You must understand the economic forces that drove the revolution. And you cannot forget the sentiment of the time that pried so many of us away from C++, and other programming languages for the Internet.
In 1995, Java was working its way through the labs of Sun Microsystems, unborn. Sun garnered attention as a champion of standards, and for bringing Unix out of the academic ghetto, but it was not a major player in development environments or programming languages. Frustrations, driven by economics but stemming from inadequacies in programming languages and programming models, rippled through the community in another kind of gathering storm.
Additional content appearing in this section has been removed. Purchase this book now or read it online at Safari to get the whole thing!
To know where Java is going, you've got to know where it came from. You need to remember the conditions that caused us to leave the existing dominant languages in droves. You must understand the economic forces that drove the revolution. And you cannot forget the sentiment of the time that pried so many of us away from C++, and other programming languages for the Internet.
In 1995, Java was working its way through the labs of Sun Microsystems, unborn. Sun garnered attention as a champion of standards, and for bringing Unix out of the academic ghetto, but it was not a major player in development environments or programming languages. Frustrations, driven by economics but stemming from inadequacies in programming languages and programming models, rippled through the community in another kind of gathering storm.
Frustration with long development cycles and inadequate user interfaces drove many companies to move off of mainframe computers. At first, the movement amounted to nothing more than a trickle. As the cost-cutting financial offices measured the software and hardware costs of IBM versus Microsoft on Intel, the trickle became a flood.
But the wave of migrating customers did not consider all the costs. The rapid movements from mainframes to Intel servers drove the first tsunami of chaos because the client-server movement hid significant costs:
Management costs skyrocketed. It was too difficult to deploy tiny changes to hundreds of fat clients. Technologists could not figure out how to maintain the many desktop applications and frameworks necessary to make the architecture go.
Many customers became increasingly wary of a gathering Microsoft monopoly.
The tools of the day made it easy to get started, but did not handle complexity well. Typical customers simply could not make them scale.
Additional content appearing in this section has been removed. Purchase this book now or read it online at Safari to get the whole thing!
As programmers wrestled with OOP, they also dealt with issues related to their chosen language
. Visual Basic developers began to understand that the language and environment may be simple, but it is prone to poor performance and poor designs, leaving customers stranded with slow applications that they could not extend or maintain.
In C++, server-side developers found performance, but discovered another challenge. They did application development using a systems programming language. New terminology like memory-stompers
and DLL Hell
gave testament to the frustration of the masses. Simple problems dogged them.
With C++, a pointer could point to any block of memory, regardless of whether it was the intention of the programmer. For example, consider the simple program in Example 2-1. It moves a block of memory from one location to another, and inverts it. Unfortunately, the example is off by 1. The code touches memory one byte beyond the from block. You would probably not see the error right away. You'd see it later, when you tried to manage the memory of this block, or another one. C and C++ compilers often manage memory with a linked list, and the pointers to the next block in the list sit just outside the allocated blocks! These types of errors hurt systems developers, and absolutely murdered applications developers, who didn't have the background to effectively troubleshoot these types of problems. Reliability also suffered.
Example 2-1. Move and invert a block of memory
// move and invert from_block into to_block with size size
int i;
for(i=0; i<size; i++) {
to_block[size-i] = from_block[i]; // off by one!
}
One of my most vivid and frustrating memories from working with IBM came from porting a C++ application that had include files nested 37 layers deep. It can be a very difficult problem to manage, especially for inexperienced developers.
Additional content appearing in this section has been removed. Purchase this book now or read it online at Safari to get the whole thing!
The sound and fury of the Java storm caught many of us off-guard. And why not? It came from an unlikely source, was delivered in an unconventional vehicle, and defied conventional wisdom regarding performance of interpreted languages. Other than the language, nothing about Java was conventional at all, including the size of the explosion. In retrospect, you can look back and see just how well it filled a void. Figure 2-3 shows the many ingredients that come together to form the perfect storm.
Figure 2-3: Many forces formed the combined ingredients that led to a perfect storm
The jet stream that powered this storm emerged from a series of standards: TCP/IP, HTTP, URI, and HTML. The Internet gathered steam, and Sun took full advantage with Java. The Internet was everywhere. Java was cool. The Java developers quickly built the API set that would allow developers to code for the Internet, including TCP/IP APIs for communication, and applets for building user interfaces that you could embed in a browser. JDBC allowed database access.
The perfect combination formed by the relationship between Netscape Navigator
and
Java drove each company to new heights. Through Netscape, Sun was able to put Java in front of an incredible number of developers, nearly instantaneously. Through Java, Netscape could showcase smart applications that looked cool, and were simultaneously practical. The Navigator/Java combination seemingly solved the most critical problems of client-server computing: management and distribution. If you could install a browser, you could then automatically distribute any application that you wanted through the browser. Java had the perfect economic conditions for success. Java found an important ally in the bean counters that liked the manageability of the green screen, but the productivity and usability of the fat client.
Customers wanted solutions, and Sun realized that Java would give them what they wanted. Sun immediately saw the opportunity it faced. With the open standards around the Internet and the Java language powering it, Solaris on Sun servers would be a compelling, and even hip, alternative. Above all, Java made Sun safe. Because its virtual machine ran in a browser and on many different operating systems, some hard decisions didn't seem so hard. You could try out a deployment scenario. If you didn't like it, you could just move on.
Additional content appearing in this section has been removed. Purchase this book now or read it online at Safari to get the whole thing!
Applets captured the imagination of programmers everywhere. They solved the deployment problem, they were cool, and they were easy to build. We're only now finding a set of technologies, based on the ugly and often objectionable JavaScript
language, that can build rich content for the Web as well as Java did. Still, applets
started to wane.
Even today, I think that applets represent a powerful idea, but they fizzled out for many reasons. The Netscape browser's JVM was buggy and unpredictable. Further, with such a rapidly evolving language, applets presented many of the same problems that client-server computing did. You may not have to maintain applications, but you still had to maintain the browser. After you'd deployed a few Java applets, you had to worry about keeping the right version of the browser on the desktop. As the size of the JVM grew, it became less and less likely that you could install a JVM remotely. Even if you could, Java versions came out often enough, and were different enough, that new applications frequently needed to materialize. But a few mad scientists at Sun were up to the challenge again.
Author of The Rise of Java
James Duncan Davidson is a freelance computer programmer, photographer, author, and speaker. He invented both Ant and Tomcat, two of the most successful Java open source projects ever. His persistent efforts at Sun led to open sourcing both projects. He is now one of the best-selling authors of Apple operating system books.
What do you like best about Java?
JDD: At the time, it seemed like a really good idea. Mostly, for what Java was designed for, they got it right. Of course, it's a strongly typed language, which for some purposes is great, and other purposes not.
Additional content appearing in this section has been removed. Purchase this book now or read it online at Safari to get the whole thing!
I believe that Java is now the most successful programming language ever. It redefined the way we package and deliver software. It changed the way we feel about interpreted languages, and the way we build Internet applications. Java changed the very economics of application development by bringing deployment and management into the overall equation. It built a new affinity for libraries, with strong web-based support. Java ushered in a massive wave of important standards that now form the very foundation of enterprise software development. Java has changed the rules of the game—Java completely rewrote the rulebook defining what it takes to be a commercially successful programming language.
In some ways, Java's new rulebook will serve us well. To achieve similar success, a new language will need to be portable and encourage a vibrant open source community. It will need broad appeal, across low-level programmers and architects. It will need to embrace compelling standards.
But technology is only part of the problem. For a new language to succeed, you'll also need a compelling business reason to switch. In some ways, Java held us back by discouraging competition. You may be tempted to use Java, even if it's the wrong tool for the job. You may work harder than you have to, because you're not free to explore alternatives. And this situation may lure us into a false sense of security, just as so many Java developers feel so comfortable wholly inside Java's cocoon.
Additional content appearing in this section has been removed. Purchase this book now or read it online at Safari to get the whole thing!
We may never again see a perfect storm like the one that ushered in Java. You shouldn't look for one. Instead, you should learn from the success of Java, and start to understand the factors that led to its success. Minimally, I believe the next commercially successful programming language will need to satisfy four major criteria:
It will need to establish a significant community. You won't see broad adoption unless the adopter can achieve relative safety.
It will need to be portable. Java's virtual machine has raised the bar for languages that follow.
Some economic incentive must justify the movement. Currently, productivity to me looks like the logical economic force, but others may be lurking out there, like wireless computing or data search.
It will need demonstrable technical advantages. This is actually the least important of the major criteria.
I don't think most of us can possibly thoroughly understand the success of Java. It's easy to overestimate the role of the language and to underestimate the importance of the JVM and the community. In the next chapter, we'll continue to look at the crown jewels of Java in more detail, or the foundation for the most successful programming language ever.
Additional content appearing in this section has been removed. Purchase this book now or read it online at Safari to get the whole thing!
After the sixth drop in 40 minutes, I looked back up the river, and reflected. I was colder than I'd ever been. I hadn't eaten in six hours. My head and back hurt, and I was afraid—in short, pure bliss. Despite the painfully long hikes with a boat cutting into my shoulder, and the fear of facing a wall of water barely covering rocks that have maimed or even killed before, and the ubiquitous smell of wet neoprene every evening, I can't get enough. Kayaking delivers me to places that nothing else can reach. The immediate feedback tells me exactly how I'm doing. Others can't do it for me, but others can tell me how to do it for myself. And the feeling of conquering a tiny piece of river is incredible.
Java was once like that for me. I get enormous productivity jolts out of Java's incredible community, and countless open source projects. The open standards and the JVM mean that my knowledge, and my applications, can move from place to place. Java's been tremendously successful. You've seen my views about why it was popular. If you're to understand what might possibly come after Java, you need to ask questions about Java's continued success:
What makes Java hip, and draw such a wide variety of people?
How has the open source community thrived, in times, despite Sun and the power vendors?
What are the indispensable technical underpinnings that make Java successful?
What makes Java so adaptable that programmers can build everything from web sites to databases?
Answers to these questions go well beyond one single brain. To provide a better answer, I interviewed dozens of the top Java developers and asked them what made Java so successful. Table 3-1 shows some of the interesting answers.
Table 3-1:
Reasons for Java's success according to top Java consultants
Consultant
Additional content appearing in this section has been removed. Purchase this book now or read it online at Safari to get the whole thing!
In 1996, the JVM represented a significant departure from traditional thinking. Overwhelmingly, organizations exclusively used high-performance compiled languages on the server side. Developers patched on security instead of baking it in from the beginning. And vendors attempted to achieve portability
by building extensive libraries at a very high level. Instead of driving on this well-traveled road, they reached for the steering wheel with both hands and threw all of their momentum to the side, swerving aggressively into unpaved, uncharted territory.
In the early and mid-1990s, many in the industry were just starting to think about portability. In particular, I vividly remember working on object-oriented technologies at IBM. The project, called System Object Model (SOM)
, emerged from a research project that formed the foundation for OS/2's groundbreaking object-oriented desktop, and some experimental technologies that never made it out of the lab. The goals of SOM were ambitious: we wanted to build a common object model underneath as many object-oriented languages as possible. Then, we could develop a common suite of libraries that developers could use across languages and operating systems. Over time, we discovered the difficulties of porting a technology across many operating systems and programming languages. Of course, the technical challenges were daunting, but the political challenges turned out to be insurmountable. We immediately discarded the Smalltalk-like integrated development machine and the virtual machine, concepts introduced by Smalltalk and Lisp, because a VM couldn't possibly be fast enough. We weren't alone in our approach. Many C++-driven companies tried to build programming libraries across many languages. Few succeeded.
The Java approach, shown in Figure 3-1, is fundamentally different. Java's virtual machine simply redefines the machine, providing a lower-level, firmer foundation for portability. Java designers bet that they could overcome performance concerns. It was not a new idea; nor was it a popular one. Over time, they proved to be right—just-in-time compilers improved performance so that the overhead of the JVM became acceptable, and even rivaled compiled languages. The virtual machine, built into Netscape Navigator, proved to be a fantastic launching pad for the Java platform. It's enabled Java to extend into the realm of mobile devices, application servers, and countless software products. When all is said and done, popularizing the idea of the VM may be the most important technical contribution of Java.
Additional content appearing in this section has been removed. Purchase this book now or read it online at Safari to get the whole thing!
C evolved from a systems language built to create operating systems. It's a systems programming language. C, and the C++ follow-up language, didn't creep into the enterprise until later. Unlike C++, a very early target for Java was mobile computing, and it evolved very quickly to encompass Internet applications
for the enterprise. You can easily see Sun's intentions in four primary places:
Java included convenience features to make applications programming easier. Java added garbage collection and memory management, so application developers wouldn't have to deal with these issues. Java included first-class strings, so the platform, rather than the programmer, could deal with moving the individual bytes around. A systems language might want more control.
Java's vision for enterprise computing
was centered on the Internet. Java built in several libraries that greatly simplified enterprise computing and the growing language always kept the Internet as a central focus. Early APIs enabled everything from communications protocols like TCP/IP sockets to the applet framework that allowed embedded applications in a browser.
Java's fathers keenly moved to improve simplicity, at the price of low-level flexibility. For example, though C++ could touch any byte in the system, they knew that the C++ applications community struggled with pointer arithmetic.
Very early, Java was targeted at mobile applications
, but Sun saw an opportunity to topple Microsoft. Sun took the opportunity, extending the primary focus of Java into the Internet.
Remember this: client/server computing
made it very difficult to deploy applications. Thousands of Windows clients, and a distributed network of hundreds of servers to power them, were cheaper than mainframes to buy, but they were horrendously expensive to manage. In the late 1990s, corporate visions changed from client/server computing to networks of applications built with Internet standards, called intranets, existing entirely inside corporate boundaries. When Sun embedded Java into the first version of Netscape Navigator, this vision looked quite possible.
Additional content appearing in this section has been removed. Purchase this book now or read it online at Safari to get the whole thing!
As the emphasis in Java shifted from the client to the server (Figure 3-2), enterprise integration
became more important. Here, the partnership of IBM, Oracle, BEA, Borland, Sun, and others paid huge dividends. They enabled Java connectivity to databases, transaction engines, messaging systems, and any other enterprise system that required a Java connection. The combination of vendor cooperation and support drove cooperation in standards and proliferation of useful connectors that we've never seen before. Java proved to be a good integration platform. Because of the backing of all the heavyweights, Java also became a very safe solution.
Figure 3-2: Java's focus shifted from the client to the server over time
Java remains a good language for enterprise integration projects, because of the high number of frameworks that solve so many of the critical problems, like distributed transaction processing. Static typing is much more important for problems on a massive scale, since such problems are harder to test, bugs become more expensive. Relative to C++, in this space, the speed of authoring is more important than the speed of execution, because most execution time is spent inside of the various enterprise transaction, database, and networking libraries.
Today, Java can talk to just about any enterprise system that's important to you. Beyond integration, Java now provides excellent facilities for mapping object-oriented models to relational databases. You can do distributed coordination of transactions, and manage massive messaging systems with first-class rules engines and workflow. You can reach beyond Java into C++ using a native wrapper called the Java Native Interface (JNI), or using coarse-grained strategies like web services. You've got dozens of remoting strategies available, from the 1990s standard CORBA to the Java-only RMI. Or, you might decide to use many of the lightweight HTTP strategies for remoting and web services. Different standards and free frameworks will help you manage the services for your business objects, do text-based searches, write games, or even write mobile applications.
Additional content appearing in this section has been removed. Purchase this book now or read it online at Safari to get the whole thing!
The most critical crown jewel for Java is the community. Said another way, Java's market share makes it the 500-lb. gorilla who can sleep anywhere he chooses. Java's community is as massive as it is diverse:
Vendors across the industry support Java. Though Sun is the inventor, IBM is perhaps the most important Java supporter.
Enterprise developers use Java to do almost everything. Java is at once a mobile computing platform, a web-based applications language, a systems language for enterprise-plumbing code called middleware
, and everything in between.
Hobby programmers flock in droves toward open source projects. Once the black sheep of the open source community, Java has now become the dominant player.
Standards also play a significant role in enterprise computing. From the beginning, the core Java vendors have collaborated to establish standards. Servlets, EJB, and JSP were three of the most influential standards of this decade. To fend off the image that Java was growing increasingly proprietary, they established a community process.
Java has characteristics that many of us take for granted. You can find good Java developers everywhere. No one ever gets fired for choosing Java. It's mature and ready for outsourcing. You can get education. You can buy components. You can often choose between many implementations of a standard. You can do many things for free. I could go on, but the point is clear. Java's community makes enterprise development safe.
Everyone wants to build a monopoly for the inevitable benefits of market domination, but the power behind Java's community goes well beyond riding the coattails of market leadership. And one piece of the community, open source software, increasingly defines the Java experience.
Additional content appearing in this section has been removed. Purchase this book now or read it online at Safari to get the whole thing!
As with all technologies that rise so quickly and become so prominent, it's tempting to worship Java. In fact, many media Java proponents use Java's overwhelming success to defend everything from EJBs to static typing. They make a leap of faith to suggest that Java had to be perfect for it to achieve such widespread success. That's dangerous. In fact, many of the following myths may eventually help lead to Java's demise.
Java is indeed in a comfortable position of market dominance. But storms can come quickly. They can destroy the existing landscape, leaving behind a new legacy. Disruptive technologies occur more frequently than you might think:
Consider the recording industry. Records died, and it looks like CDs may die soon, too. Walkmans rose quickly, and are falling just as fast. A combination of an iPod and a Bose Wave Radio can easily replace a whole stereo in many households.
Some emerging Third World countries skipped traditional phone systems, in favor of wireless technologies.
Digital photography has relegated film to a niche product.
You can't find a 51/4-inch floppy disk anymore, and it's getting harder to find a 31/2-inch disk.
Closer to home, Visual Basic may be nearing the end of its run. Movement to .NET has proven to be disastrous for Microsoft, for the Visual Basic community.
In fact, Microsoft's .NET environment threatens Java now. Some emerging programming languages draw the attention of some of Java's brightest independent consultants, and frustrating limitations drive away others. All other programming languages have had a limited period of leadership. In the end, this will be true of Java as well.
Additional content appearing in this section has been removed. Purchase this book now or read it online at Safari to get the whole thing!
I don't know for sure when I decided that the kayakers behind us were in trouble. Our minds were occupied by the chaos around us, and the situation kind of snuck up on us. Barton Creek was in flood, and it was pounding furiously. We'd left with 10 paddlers, but needed to keep a safe distance. We divided into groups of three so that each group could keep an eye on the others. The day had already started badly; a fireman in an unrelated party had died on this same stretch of creek. An expert boater had been foolishly paddling alone. Now, we had problems of our own.
After we'd paddled for about an hour, we pulled over into a huge eddy to get the group together and plan our assault on the next dangerous stretch of river. In truth, the banks were very dangerous, with trees that could trap you like a kitchen strainer while the water piled up and poured over you, but the main lines were pretty straightforward. I'd flipped once, but rolled back up easily. But we'd passed a few places that could have given you trouble, had you been unlucky enough to blunder into them, or too cocky to skirt the danger. The last party of three was missing, and we had no way of getting back up the river. We waited for two hours, but the last group of three failed to join us. We waited until there was little daylight left, and then we headed down the river. Eventually, we discovered that one in the trailing party had tried to punch a hole that none of us was brave or stupid enough to run, and had to be rescued by helicopter. I've never run Barton Creek again with water that high.
I've developed a good instinct for trouble on the river, and at work. In this profession, I generally know when a technology smells wrong, or dangerous, and I guide my customers away. I'm sensing that danger around Java right now. It's getting too difficult to manage, and both evolutionary and revolutionary steps to remedy the problem are failing us. In this chapter, I'll introduce some of the basic problems.
So far, I've tried to make the case that Java's always been a generalized programming language, with the syntax and core community coming from the C++ systems language. Also, I've suggested that most early Java applications focused on the user interface. You could download Java and get something running very quickly.
Additional content appearing in this section has been removed. Purchase this book now or read it online at Safari to get the whole thing!
So far, I've tried to make the case that Java's always been a generalized programming language, with the syntax and core community coming from the C++ systems language. Also, I've suggested that most early Java applications focused on the user interface. You could download Java and get something running very quickly.
Once Java moved to the server side, it became the core server-side development language. Java carries an increasing load in enterprise development, from object-relational mapping with distributed transactions to messaging with XML
binding for service-oriented architectures. So the job that we use Java to do is ever changing. The language is remarkably flexible, so it's lived up to the challenge so far.
But all of the extra power comes with added complexity. Where does that leave people who need to learn a language quickly, or the Java programmer who wants to solve a simple problem, or companies like start-ups that value productivity over all else? As competitive pressures force us to meet shorter and shorter schedules, a generalized Java is just not enough anymore. At some point, Java will prove inadequate. Let's look in detail at what we're asking Java to do.
If Java dies, I think it will be replaced one niche at a time. Java's popular in several niches. It's floundering in some and thriving in others:
Java's become indispensable for writing middleware
, the systems software that fits between an application and an operating system. Java's many libraries, performance, portability, and ubiquity make it a good fit for middleware, and that's likely to continue.
For servlets
and web programming in general, Java needs a faster feedback cycle, and needs to get better at managing strings. PHP
is far more productive for this environment. Java's not the only reason: web programming is a mess for many reasons. But Java just isn't very good for the simplest and most typical applications.
Additional content appearing in this section has been removed. Purchase this book now or read it online at Safari to get the whole thing!
I've painted a picture of the average project. The average team builds or ports applications that will deliver a web-based frontend on a relational database, potentially with other less meaningful services. The team probably uses increasingly agile principles, and likely wants to do unit testing. The team typically works under short schedules and great pressures. And given more dynamic alternatives, Java is not at all the language that I'd usually choose for such a project, in such an environment:
The many frameworks designed to simplify the Java development experience do make experienced Java developers more productive, but make the learning curve too steep for those new to Java.
Compile-time checking of exception and types adds safety, but comes at a cost of additional time and syntax.
Java's inability to express structured data leads to an over-reliance on XML, with the corresponding additional complexity and bloat.
Java's many compromises, like primitives, make Java harder to learn and more complex to write.
Java is more dynamic than C++, but is nowhere near as dynamic as languages like Smalltalk and Ruby. Java developers are finding metaprogramming, but they're not able to execute on those ideas fast enough.
Java's long compile/deploy cycle is much longer than interpreted, dynamic alternatives.
Taken alone, none of these issues hurts enough to matter. Taken together, Java becomes much less productive for most developers.
Language expert and creator of Wyvern
Steve Yegge, a graduate of the University of Washington, spent five years as an Assembly-language programmer at Geoworks and more than six years as a software development manager at
Additional content appearing in this section has been removed. Purchase this book now or read it online at Safari to get the whole thing!
One of the most fiercely debated topics in programming languages is the benefit of strong, static typing
strategies. Java's strategy opts for as much compile-time checking as possible. Let's take a quick overview of programming language design, in layman's terms. Then, you can put Java into context. When building a language, a designer needs to answer two typing questions relatively early in the design process.
Strong versus weak typing decides how a type is enforced, or interpreted. In a weakly typed language (like C), variables can be coerced easily, or interpreted as something else. A strongly typed language strictly enforces compatible types across operations. It probably doesn't surprise you that Java is a strongly typed language.
Ruby, Smalltalk, and Python also enforce strong typing, which might surprise you. Many developers believe Smalltalk, Python, and Ruby are so productive because they are weakly typed. They are misinformed. Consider this brief Ruby example:
irb(main):003:0> i=1
=> 1
irb(main):004:0> puts "Value of i:" + i
TypeError: cannot convert Fixnum into String
from (irb):4:in '+'
from (irb):4
In the first line, the undeclared variable i takes on the value of 1. At this time, Ruby decides that i is a Fixnum. When Ruby interprets the third line, it sees the + operator after the string, and tries to concatenate i. Of course, Ruby doesn't know how to concatenate an integer to a string, so it throws an error. That's clearly an example of strong typing. (Actually, I've oversimplified things a little. You can dynamically change the definition of Ruby classes and objects at runtime, and this weakens the typing somewhat. Still, on a continuum from strong to weak typing, Ruby would lean slightly to the strong side.)
In a similar situation, a language with weaker typing may instead coerce types to a compatible form, as in C. Consider this example:
int a = 5;
float b = a;
Additional content appearing in this section has been removed. Purchase this book now or read it online at Safari to get the whole thing!
From the very beginning, Java designers consciously made decisions to attract the C++ community, and favor performance over other considerations. The biggest compromise was the inclusion of primitive types. This addition means Java is not fully object-oriented, and presents several significant challenges. Those who came from the C++ community don't always see a problem, but developers from other programming languages often see primitives
as an ugly kludge. Primitive types do not descend from Object, so Java is more of a hybrid language than a true object-oriented language. But that's all academic. There's a real cost associated with the theory.
Java primitives limit you because they don't descend from a common Java object. One of the nice things about most object-oriented languages is polymorphism: you can deal with specific objects in a general way. In Java, that's not quite true, because primitives do not descend from Object. You can't, for example, say 6.clone(), or 6.getClass().
If you've ever built an XML emitter or an object relational mapper, you know about the headaches related to primitive support. In Java, you can't treat all types the same, and you don't have the benefit of natural methods on the primitive types. You have to build in explicit support for objects, primitives, and arrays.
Since most of us don't build XML emitters or persistence frameworks, we shouldn't care about those costs, right? It's not that easy. You still have to deal with complications in the language, such as inconsistent APIs and added breadth of the frameworks that you do support. Reflection is probably the worst. To get the value of a field, you first have to determine the type. You then get the value, with one of get, getBoolean, getByte, getChar, getDouble, getFloat, getInt, getLong, or getShort. Of course, if it's an array, all bets are off. Arrays can contain primitives or objects, so they can't even treat their contents generically. You basically have to go through the whole process again.
Additional content appearing in this section has been removed. Purchase this book now or read it online at Safari to get the whole thing!
Of course, you could write a whole book about the strengths and weaknesses of Java alone. I don't think that's productive. I won't rehash the "EJBs stink" message that's been presented prominently in my last three books. I also don't want to launch into a debate about the meaning of whitespace, Java's commenting styles, or the relative benefits or evils of byte code enhancement. Still, there are more things to cover. Exceptions and strings play a huge role in most Java applications.
Sun is not the company that it once was, placing Java's future in doubt. I'm not saying that Java will disappear, but Sun might. It has lots of cash in the bank, but where is it going to make money? It's being squeezed on the low end by companies like Intel, Dell, and AMD. IBM is squeezing Sun from above. Sun's software and services businesses have never really taken off. I think Sun is a ripe acquisition target.
If Sun does have major problems, what happens to Java? I fear that an IBM acquisition would put too much emphasis on the hardest enterprise problems, moving Java further away from its base. Open sourcing Java could effectively splinter the language. Other potential suitors, like Oracle and BEA, could lead to a conflict of interest that could stymie new standards.
IBM may be getting nervous. It has begun to hedge its Java position in several ways:
IBM is aligning closely with BEA on standards like SDO, and it is increasingly at odds with the JCP. IBM may well be positioning itself to challenge the JCP, or establish standards outside of the JCP.
IBM looks like it may embrace PHP
more closely, to take advantage of that swelling marketplace. PHP would be an effective hedge for smaller and intermediate businesses.
IBM continues to invest in XML technologies with Microsoft.
In any event, Sun's ultimate health, or lack thereof, casts doubt on the shape of Java's future. If you're trying to maintain market dominance, uncertainty is not the best place to start.
Additional content appearing in this section has been removed. Purchase this book now or read it online at Safari to get the whole thing!
You might argue that we need to fix Java, not scrap it. That would be easy if you could pinpoint the problems. If you thought the problems were in the language itself, you could just do some major surgery and offer a new version of Java. That's easier said than done. Sun has been very careful to preserve backward compatibility at all costs. If you look at the lack of commercial acceptance for Visual Basic .NET, it's easier to respect Sun's point of view. Microsoft made some radical changes to the language and libraries
, and they weren't well received. Regardless of whether it's a good idea, Sun will continue to be conservative to protect customers.
Still, even if you look at relatively aggressive changes, most experts that I interviewed tend to think Sun is even now moving in the wrong direction. Instead of making Java more nimble and dynamic at the foundation, the changes, for the most part, amount to additional type safety—syntactic sugar hacks built into the syntax rather than the JVM that often lead to inconsistent behavior.
It's clear that libraries are problems, too. Sun has launched several belated simplification movements. So, if it's Java's libraries that are broken, and not the language itself, couldn't we just scrap a few libraries and start over on a more simplified foundation? That's the approach we suggested in Better, Faster, Lighter Java. For Java's most important and basic job, a web-based user interface on a relational database, I don't think Java's frameworks are moving in a healthy direction at all. Most frameworks are moving to add more compelling features rapidly, instead of simplifying what's already out there.
One bad library might point to a few local mistakes. Java's problems are more global. They target very complex problems at the expense of the easy problems that most Java developers need to solve. The problem is clear. The Java leadership is abandoning its base willingly and rapidly. It's a cultural problem, inherent in the Java community, vendors, programmers, and leadership. Java has become strictly a language for hard-core enterprise development of large-scale problems.
Additional content appearing in this section has been removed. Purchase this book now or read it online at Safari to get the whole thing!
In 10 years of relatively heavy kayaking, a few scary rapids stand out. The Chatooga River had many such rapids. Bull Sluice on the Chatooga had a waterfall pouring through a hole in the riverbed. It was large enough on one end to admit a kayaker, but not big enough to let him back out. Cork Screw had a violent approach and a keeper hydraulic. Woodall Shoals was a placid-looking drop that masked a near perfect hydraulic that I considered unrunnable in my peak paddling years. On such rapids, the margin of error was frighteningly small. You walked around, hit your intended line, or risked getting hurt or dying. Those were the rules of the game.
Let's assume for a moment that you agree with the premise I laid out at the beginning of the book: conditions are ripe for an alternative applications programming language to emerge, because Java is abandoning its base. I'm not going to pretend to know what's next. Hopefully, I'll lay out some interesting languages and frameworks that have promise. I'll also rule out some languages right off the bat, based on the rules of the game.
If you think about it, you instinctively know that some programming languages will definitely not be the next big one. Lisp
is productive, but the average Joe can't understand it. Perl
is rich and powerful, but it's subtly inconsistent, and is prone to produce unmaintainable code. With a little vision and experience, you can apply a similar kind of reasoning to understand the types of languages that might follow Java. I suggest that we define success loosely: the language should be recognized widely and adopted broadly among developers who now use Java. This chapter, then, suggests the characteristics that the language should have to have broad commercial success.
Each new language is subject to the rules of its time. If you think about new inventions in the world of music, you'll see the same principle in play. Early in the recording industry, a record label would sign an artist to a specified contract, manufacture records, promote them on the radio, and distribute them in stores. You find some of those features today, like many of the roles in the production cycle and the importance of airtime (on radio, and now TV and the Internet). Changes in standards force the industry to retool. Some are relatively minor—changes in record speeds simply forced manufacturers to add capability to record players and recording equipment. Others will almost certainly be more radical. These changes require a critical mass to take hold—CDs achieved a critical mass, but eight-tracks did not. Sometimes, disruptive changes completely redefine the organization and very fiber of an industry. Our kids are redefining the way music is distributed through services like Napster and iTunes. Some artists are distributing their music entirely over the Internet, and they are cutting the publishing industry out of the equation altogether.
Additional content appearing in this section has been removed. Purchase this book now or read it online at Safari to get the whole thing!
Each new language is subject to the rules of its time. If you think about new inventions in the world of music, you'll see the same principle in play. Early in the recording industry, a record label would sign an artist to a specified contract, manufacture records, promote them on the radio, and distribute them in stores. You find some of those features today, like many of the roles in the production cycle and the importance of airtime (on radio, and now TV and the Internet). Changes in standards force the industry to retool. Some are relatively minor—changes in record speeds simply forced manufacturers to add capability to record players and recording equipment. Others will almost certainly be more radical. These changes require a critical mass to take hold—CDs achieved a critical mass, but eight-tracks did not. Sometimes, disruptive changes completely redefine the organization and very fiber of an industry. Our kids are redefining the way music is distributed through services like Napster and iTunes. Some artists are distributing their music entirely over the Internet, and they are cutting the publishing industry out of the equation altogether.
New programming languages work in much the same way. Every language leaves behind a legacy. Sometimes, changing languages embrace the legacy. For example, you compiled your C programs into a DLL or an executable. You could take advantage of your C code from C++
by buying a new compiler. You could even use C++ to write procedural code or object-oriented code. C++ changed the way we think, but it did not change much of the machinery. The C programming language
was also disruptive in many ways. Java, too, was disruptive, redefining the rules of the game.
Kids like to be able to download songs like "Macarena" instantly, so the old music stores aren't cutting it anymore, and they are closing their doors. Don't even try to open one, unless you plan to bankroll it with your own money. By the same token, we like the convenience of the JVM, the massive open source community, and the focus on the Internet, leaving a higher standard for the next major applications language.
Additional content appearing in this section has been removed. Purchase this book now or read it online at Safari to get the whole thing!
In some ways, C redefined enterprise integration, by allowing strong database connectivity across an open API (ODBC for Microsoft applications) and providing transaction monitors like Tuxedo and Encina. C was disruptive—it introduced enterprise programming beyond mainframes. Java continued this legacy with frameworks for transactions, rich database integration, messaging, and many other forms of plumbing code called middleware.
I don't think the next major applications language will initially have to have the full enterprise capabilities of C or Java to succeed. Visual Basic certainly achieved tremendous success without these capabilities by leveraging the services provided by other frameworks written in lower-level languages like C. We've already determined that the next language should interoperate with other Java programs, hopefully within the same virtual machine. It should also interoperate through a coarse-grained service layer. That said, some enterprise capabilities will be very important.
Minimally, a new language should access relational databases in a natural, productive way. I don't think any particular application style is important—you can see wildly successful environments with different strategies:
Microsoft builds a framework that leverages the power of SQL
, row sets, and relational databases. The center of the Microsoft universe, from a data perspective, is the relational database. The strategy can scale very well and is surprisingly productive.
Java, instead, seems to be moving toward ORM. The center of Java's data universe is an object-oriented, persistent model. Other Java applications leverage JDBC
with helper frameworks quite successfully.
Ruby on Rails
takes an intermediate approach. Rails wraps a database table with objects that discover the structure of the database dynamically.
Additional content appearing in this section has been removed. Purchase this book now or read it online at Safari to get the whole thing!
Many languages have trumped Java technically, but they still failed. Betamax, too, was technically better than VHS. The biggest factor of the equation is social. Without a credible community, there can be no success. To a programmer, a language is an investment in a future, and even an identity. Call it marketing, or buzz, or even hype. If it's hip, or at least interesting, a language stands a fighting chance. If not, there's no chance at all. In some ways, Java helped pave the way for the next language:
Communities like TheServerSide and Slashdot provide a forum for new ideas to spread quickly through the Java and non-Java programming communities. It's much easier for smaller projects to create a big buzz.
The increased emphasis on open source software, partially driven by Java, makes it easier to wrestle control away from larger companies. Also, those same companies find open source technologies easier and less threatening to adopt.
Many Java standards like Web Services
(and lightweight HTTP alternatives) make it much easier to interoperate between languages.
The JVM will run other languages. A new language on the JVM is a much easier sell than a new language in a new environment.
Still, the challenges of establishing a community are daunting. Microsoft has spent millions of dollars promoting the .NET environment, and the adoption on the server side is still nowhere near Java's adoption, though many of the features and capabilities are similar or superior to Java. Sun, for all of its success with the Java platform, has not been able to capitalize on it in the software realm. Adoption of Sun application servers and management software has been spotty at best. IBM lost the battle of the operating system because it couldn't market a technically superior OS/2.
Programmers are a schizophrenic lot. One moment, we're the ultimate skeptics, ditching the safety of the Microsoft Windows environment for unpredictable Linux systems on our desktops. The next, we're lemmings, adopting hideous architectures like EJB without the slightest bit of proof. You also have many different niches within the programming community. Java's been successful for enterprise developers, but hard-core hackers in the Perl and Python communities frown on Java. And Microsoft developers form cultures all their own, with subcultures in it that favor C++ or Visual Basic.
Additional content appearing in this section has been removed. Purchase this book now or read it online at Safari to get the whole thing!
It's strange to be more than halfway through the characteristics of the next great programming language without even talking about the major features of that language. When you look at the history of programming languages, it makes more sense. The features of a language are important characteristics for success, but only rarely are they the most important characteristics. Said another way, market share and mindshare matter more than how you interpret whitespace.
Java purists defend strong, static typing with the fervor of English soccer fans. To be sure, static typing does have its advantages:
Static typing enforces typing rules at compile time, when they are least expensive to fix.
Static interfaces make it easier to enforce a protocol across important boundaries. For example, systems designers may want to force certain types for C interfaces, or certain remote procedure calls.
Static typing catches some types of subtle errors at compile time, like the misspelling of a variable name.
Still, as you learned in Chapter 4, there's a related cost, usually in productivity
. Java developers often make the comment that you can pay now or pay later. That's strange, because Smalltalk and Ruby programmers rarely make lasting errors related to incorrect typing. Further, disciplined automated unit tests easily catch most type mismatch problems. You've got to unit test your code whether you want to or not, because no compiler can completely guess your intent.
Most Java developers who tout the benefits of strong, static
typing
fail also to count the cost. When you're learning or playing with a language, the cost is excessive, because you have to declare everything, including a wrapping class, and learn a whole new level of detail. Here's a "Hello, World" example in Ruby:
Additional content appearing in this section has been removed. Purchase this book now or read it online at Safari to get the whole thing!
Now that you've seen what the industry has to offer, let's take a quick review of some programming languages and identify some possible candidates. You'll see a more comprehensive treatment of the contenders in Chapter 9. If you buy what I've been selling so far, you understand that for certain jobs, other languages may be better suited. I encourage you to try one of these languages every month or so.
If you've not been exposed to languages outside of C++, Basic, and Java, I've got to warn you that the experience can be unsettling. You'll be surprised at how much of your knowledge commutes, and how quickly you can grasp the essence that makes a given language so productive. You'll also be surprised at the fury that you can generate around the office just by peeking at alternatives—you may want to leave the nice car in the driveway and take the old Family Truckster to work for a while.
Perl is a scripting language, with a quirky syntax and a turbulent past. Here's a quick example that prints "Hi, Bruce":
my $name = "Bruce";
print "Hi, ", $x, "\n";
Section 5.5.1.1: What I like
If raw productivity is your goal, perhaps Perl is a possible answer. It's dynamically typed, is highly productive, and has a small community established. It also has a fanatical following.
Section 5.5.1.2: What I don't like
Perl does have a big downside. To this point, Perl's got a reputation of a write-only language: with its cryptic syntax, you can easily produce code that's very difficult to understand and maintain. Perl's OOP syntax, as with C++, is bolted on and awkward. As something more than a scripting language, Perl's reputation is probably a bit much to overcome.
As dynamic programming languages go, Python has been one of the most successful. It's very close to Ruby in syntax and power, and it supports the language features that you'd want. Here's a brief snippet of Python code that counts to 10:
Additional content appearing in this section has been removed. Purchase this book now or read it online at Safari to get the whole thing!
I stood on the bank of the Watauga River, looking at the 16-foot, Class V monster known as State Line Falls. It had five boulders in the current with four chutes running through them. Three of the slots were all but impassable, especially at this water level. The fourth was violent and intense. And yet, the approach was pretty easy, and I thought I could hit the line. Run this monster, or walk it. I had to choose.
Over the years, I've experienced a few moments like that one. Sometimes, I'd put my kayak on my shoulder and walk around. Other times, I decided that the line was good and my skills were up to the challenge, so I made the run. But this time, I simply stood, indecisive, with the wind and the spray from the falls washing over me.
I'm looking at a similar situation now. I do think that Java's leadership run, at least for applications, might be drawing to an end. But the stakes are unbelievably high should I decide to move. How can I know if the timing is right? Can I pick the right language? What do I risk?
I don't want this book to be an exhaustive review of programming languages. I'd like to point out one language and two frameworks (one in Ruby
and one in Smalltalk) that have something special to offer. In this chapter, I introduce one possible alternative language, Ruby. I want to show you that some languages can improve on Java, but that doesn't mean that Ruby will succeed, or that it's the best possible alternative. The best that I can do, for now, is to show you one possible alternative, so you can see if the case makes sense.
Ruby is a dynamic, fully object-oriented language that's usually grouped with scripting languages. The scripting term, for languages like Ruby, Smalltalk, and Python, is a little too limited, so I'll use the term applications language
. If you've used nothing but compiled languages like Java and C, get ready to have some fun. Ruby will turn you loose. I suggest that you install it (just go to https://ruby-lang.org
), and type along. It comes with a primitive IDE, but the command line works well. Fire up a Ruby shell by typing
Additional content appearing in this section has been removed. Purchase this book now or read it online at Safari to get the whole thing!
Ruby is a dynamic, fully object-oriented language that's usually grouped with scripting languages. The scripting term, for languages like Ruby, Smalltalk, and Python, is a little too limited, so I'll use the term applications language
. If you've used nothing but compiled languages like Java and C, get ready to have some fun. Ruby will turn you loose. I suggest that you install it (just go to https://ruby-lang.org
), and type along. It comes with a primitive IDE, but the command line works well. Fire up a Ruby shell by typing
irb. You'll get a shell prompt:
irb(main):001:0>
From here, you can evaluate Ruby statements. You'll frequently use irb to answer those tiny questions that come up often in programming. In Ruby, everything is an object, and if you type one alone, Ruby will return that object. Type 4 and press Enter:
irb(main):001:0> 4
=> 4
Unlike Java, numbers are objects
, not primitives. For example, you can do this:
irb(main):008:0> 4.4765.round
=> 4
Even nil is a class, standing for nothing:
irb(main):009:0> nil.class
=> NilClass
You don't have to worry about primitives or wrappers at all. More importantly, you don't have to deal with those cases in an API. Ruby's reflection, persistence engines, and XML frameworks are all much simpler, because you don't have to deal with all the edge cases related to primitives and arrays of primitives.
Both Ruby and Java are object-oriented languages. Both support object models with single inheritance. Still, you're going to see some differences between Ruby and Java:
Figure 6-1: Java programmers refactor the inside of a loop; code blocks let Ruby developers refactor the outside of a loop, too
In Java, the smallest application is a class. In Ruby, everything is an object, so you can evaluate primitives, expressions, code blocks, and scripts. They all are objects, and all are valid Ruby.
In Java, class definitions are static. In Ruby, you can modify your classes on the fly. When you see a class definition, if the class already exists, the new definition will modify the class that's already there.
Ruby supports mixins and Java does not. Think of a mixin as an interface, plus an implementation, that you can attach to a class.
In Ruby, everything returns some value, and that value is typed dynamically, so you won't see a return in the method definition.
In Ruby, method parameters and instance variables are not typed; but the instances themselves are typed.
For the most part, you can still use your OO design skills in Ruby as you did in Java. You'll also see some common design patterns, like model-view-controller.
Creator of Ruby on Rails
David Heinemeier Hansson is the programmer of Basecamp, Backpack, and Ta-da List under the commercial banner of 37signals, but he's also an avid open source contributor through the Rails web development framework and Instiki—one of the most popular Ruby applications. He's intensely focused on doing something about the sorry state of programmer productivity, be it through software, like Rails, or through practices, like Less Software
Additional content appearing in this section has been removed. Purchase this book now or read it online at Safari to get the whole thing!
That's a 30-minute tour through Ruby. I'm not saying that Ruby is the next great language, but rather, that Ruby makes some of the hard things in Java easy. More and more of the top independent consultants are looking for ways to make more money working in Ruby, or other languages that are more dynamic. The Java community is spending an amazing amount of money and brainpower on making Java more dynamic. Dependency injection and aspect-oriented programming are groundbreaking ideas for Java, and they are only now getting serious commercial traction. For Java developers, these ideas represent better transparency and simpler application development.
My playtime in Ruby makes another, more powerful idea, clearer. As we stretch Java in increasingly unnatural directions, there's a cost. AOP and dependency injection are near-trivial exercises in Ruby, but they force Java developers to learn new programming models, deal with XML, and introduce increasingly complex syntax. With each new metaprogramming concept that we bake into Java, it's looking more and more like all of that complexity is trying to drive us somewhere. The net effect is to push Java further and further into the enterprise niche, and make it less and less accessible to the average Joe. Contrast that situation with Ruby, where dependency injection and AOP don't consume your focus; you're free to apply those ideas in spots right where you need them.
I do think that Ruby, with Rails, is a near-ideal solution for that sweet spot that we've pushed: a web-based frontend for a relational database. I've already said that I'm using Ruby in a commercial application. My customer demanded productivity and a price point that I couldn't achieve in any other way. I also still recommend Java to many of my clients. They need complex frameworks that Ruby does not yet support, or they depend on a core set of developers that have already been trained, or they have so much legacy code in Java that change would be impractical.
In the next chapter, I'll make these arguments real. I'll show you how to build a web-based application, from scratch, to access a relational database with a web application. Then, I'll show you what another killer app might be, for another language.
Additional content appearing in this section has been removed. Purchase this book now or read it online at Safari to get the whole thing!
As I screamed uphill toward the 3-foot ledge, the voice inside my head said "Don't fight it. Go for it." Knowledgeable mountain bikers called the move the lunge, but I had neither named nor internalized it yet. My brain rebelled against the completely unintuitive idea that a moving biker could thrust his bike forward near the top of such a ledge and accomplish anything other than a spectacular crash, but I'd seen it work. I hit the ledge with speed and thrust the bike forward by simply pushing on the handlebars, and the bike was over the ledge. On some level, I didn't understand that success was a possibility. Though I was safely on top, I stepped off my pedals anyway—I'd been sure that I would fail. The idea seemed too much like flying by pulling hard enough on your shoestrings. Learning this mysterious lunge would take a while.
Like the lunge, metaprogramming also seems a little unnatural to me. Then again, I've been coding in Java and C for most of my professional career. If you want to experience the power of a framework that uses metaprogramming extensively, Rails is the gold standard.
As a fairly content Java programmer, I really didn't go searching for an alternative. In some ways, Rails found me. Dave Thomas and I speak at the same conference. I taught several sessions on the Spring framework with Hibernate, and I was very happy with my productivity. Of course, compared with EJB, I was very productive. Dave pointed out that even in Hibernate with Spring, you tend to repeat yourself on a fairly regular basis.
I reflected on David's comments. To make a persistent domain model, you need to specify a database table with its fields and indexes, specify an object domain model with a class (repeating yourself) and a field as an attribute (repeating yourself), and add accessors for that field (repeating again and again). Then, you need to build a mapping with the database table (repeating again) and the class name (and yet again). Finally, your mapping must specify each database column and the corresponding database field (repeating each column twice more). Of course, most sane Java developers do not do all of that repeating. They let the tools do most of it for them, but now your programming model dictates your tool set, your development experience, and generates more lines of code to maintain. I came to the conclusion that ORM makes sense when the domain model and object model are sufficiently different, and I decided I'd take the slight productivity hit and be compensated with better performance and the possibilities of better mapping.
Additional content appearing in this section has been removed. Purchase this book now or read it online at Safari to get the whole thing!
As a fairly content Java programmer, I really didn't go searching for an alternative. In some ways, Rails found me. Dave Thomas and I speak at the same conference. I taught several sessions on the Spring framework with Hibernate, and I was very happy with my productivity. Of course, compared with EJB, I was very productive. Dave pointed out that even in Hibernate with Spring, you tend to repeat yourself on a fairly regular basis.
I reflected on David's comments. To make a persistent domain model, you need to specify a database table with its fields and indexes, specify an object domain model with a class (repeating yourself) and a field as an attribute (repeating yourself), and add accessors for that field (repeating again and again). Then, you need to build a mapping with the database table (repeating again) and the class name (and yet again). Finally, your mapping must specify each database column and the corresponding database field (repeating each column twice more). Of course, most sane Java developers do not do all of that repeating. They let the tools do most of it for them, but now your programming model dictates your tool set, your development experience, and generates more lines of code to maintain. I came to the conclusion that ORM makes sense when the domain model and object model are sufficiently different, and I decided I'd take the slight productivity hit and be compensated with better performance and the possibilities of better mapping.
As I've said, I worked with a company that builds safety software for a manufacturing plant. We effectively build a web user interface to manage a complex domain model. We decided to build this application with a lightweight Java stack of Spring, Hibernate, and Web Work. We moved pretty quickly, and were pleased with our progress. We were proud of our accomplishments, because we'd rewritten a one-year Microsoft application in four months with Java. Naturally, as we accumulated a bigger code base, coding began to take longer.
Additional content appearing in this section has been removed. Purchase this book now or read it online at Safari to get the whole thing!
The best way to understand Rails is to see it in action. Go to https://rubyforge.org
and download Ruby and RubyGems
. (If you use the Windows one-click installer, you'll get RubyGems with that distribution.) If you don't already have one, download a relational database manager, too. I used MySQL. You'll begin to get the Rails experience at install time. RubyGems lets you install Ruby applications and their dependencies. At the command line, type:
gem install rails -v 0.12.1
Ruby will start the installation process. It goes up to RubyForge (rubyforge.org) and pulls down an index including the appropriate version of Rails and its dependencies. If you were to omit the version number, Ruby would get you the latest stable version. RubyGems will then prompt you for each dependency. Answer "Y," or answer "a" once for all dependencies:
Attempting remote installation of 'rails'
Updating Gem source index for: https://gems.rubyforge.org
Install required dependency rake? [Yn] Y
Install required dependency activesupport? [Yn] Y
Install required dependency activerecord? [Yn] Y
Install required dependency actionpack? [Yn] Y
Install required dependency actionmailer? [Yn] Y
Install required dependency actionwebservice? [Yn] Y
Successfully installed rails, version 0.12.1
You'll notice that RubyGems will then attempt to build the documentation for each of the subcomponents and Rails. And that's it. Rails is installed. You're already getting hints about the approachability of Rails.
You can now generate a Rails project. Go to your working directory and ask Rails to generate a project called trails:
rails trails
Ruby creates a full directory structure that will contain your application. There's no guesswork, and all Rails projects will have a consistent format. I'll point out a few important directories:
Additional content appearing in this section has been removed. Purchase this book now or read it online at Safari to get the whole thing!
As you've seen, the Rails framework is also made up of several existing frameworks, including Active Record, Action Pack, and a few others. Active Record handles relational database access. Action Pack processes requests, and manages the model/view/controller separation. Rails provides the integration and the rest.
Active Record implements the Active Record design pattern by Martin Fowler in Patterns of Enterprise Application Architecture (Addison Wesley). It's effectively a wrapper around a database table, with domain logic built into the wrapper. The Rails implementation adds two important innovations: you can do inheritance and manage relationships. These are some of the major features.
Section 7.3.1.1: Automatic properties
Active Record automatically adds properties, with accessors, to model objects. It also adds methods for simple CRUD database methods automatically. For example, in the view you just wrote, the view accesses the name property in Trail, though the root model was empty:
class Trail < ActiveRecord::Base
end
Section 7.3.1.2: Association management
Rails uses methods to add methods that manage associations, automatically. You saw this example where a location has many trails:
class Location < ActiveRecord::Base
has_many :trails
end
As you have seen, has_many is a method, and :trails is a symbol, in this case, for the Ruby class Trails.
Section 7.3.1.3: Composition
You can use Active Record to compose objects from multiple tables, like this:
class Location < ActiveRecord::Base
composed_of :street, :class_name => "Street",
:mapping => %w(street name)
end
Section 7.3.1.4: Inheritance
Inheritance works, putting all subclasses in a single table with the parents:
Additional content appearing in this section has been removed. Purchase this book now or read it online at Safari to get the whole thing!
So, Rails is not a toy, and it's not a gimmick. In my opinion, Rails represents a significant advance in the state of the art. You've probably seen frameworks like this one solve the database-with-UI problem in several different ways:
Object-oriented development frameworks are flexible and robust. They're usually at a lower abstraction level, so they may not be as productive. You can use them to create flexible, robust, and powerful applications, but you're going to pay for it with productivity.
Quick compromise frameworks trade conventional wisdom and sound design for implementation speed. PHP and Visual Basic, for example, compromise by trading design wisdom (frameworks should encourage separation of model and view logic) for development speed.
Code generation frameworks generate most of the code for such an application at compile time. They trade the feedback cycle, easy maintenance, and often, customization, for speed.
Customization point frameworks take a few parameters, like database tables or models, and build default implementations with a few well-defined anticipated customization points. These frameworks break down when the inventor's imagination doesn't anticipate important hook points.
Rails is none of these. It uses macros to help you quickly generate code based on the structure of the database and a few well-placed macros. Since you effectively get generated code at runtime without tangled source code, you don't have to maintain the added code. Rails avoids the trap of customization points through Ruby's extensive hook points. You start with a clean design. You can then extend it through subclassing, changing class definitions, or any of the other metaprogramming techniques we discussed. You can even replace major Rails components like Active Record.
Rails accelerates your development through meaningful conventions and defaults. By guiding your naming strategies in the database, Rails can save you lots of typing, and infer your intent by the consistent names that you provide.
Additional content appearing in this section has been removed. Purchase this book now or read it online at Safari to get the whole thing!
I rarely run rapids on blind faith. If there's any danger, I like to know exactly what the water and rocks could do to me, and I need a plan to deal with any potential trouble. On this day, though the consequences for failure were high, the move was easy. I still don't know exactly how it worked, but I watched boater after boater thrust, brace, and arrive in the turbulent boil below The Elbow, a slotted 20-foot drop that guidebooks describe as a deadly entrapment motel. Sure, I could tell you that the move was called a slot move, and I'd need to apply my brace with perfect timing and angle to avoid hitting the wall on the way down. I knew the timing, because I'd been told. It's just the "why" of it that was a mystery. The experts tried to tell me why it worked. Most really didn't know. No one could really tell me with any kind of certainty how the rocks were configured at the bottom. They just knew that at this river level, the move worked. And so it did.
At different points in my programming life, a few tricks held the same kind of mystery for me: recursion as a college student, my first glimpse at reflection shortly thereafter, and now, continuation servers
. In this chapter, you'll see continuations, and how they're used in a new class of application servers.
Web development, for all its usefulness, often happens with a curious inelegance. It's kind of like making sausage. I like the result, but I don't want to see how it's made. Web programming in Java was better than web programming in alternative languages. It gave you more structure with easier maintenance and, often, better scalability than Visual Basic or Perl-based approaches, and an easier programming model than C++. But for all the benefits, certain problems make it seem clunky and awkward.
Current web application servers might be powerful, but they're not convenient or natural. So, what is convenient and natural? It shouldn't take too much effort to figure that out. What if your controllers looked like this:
Additional content appearing in this section has been removed. Purchase this book now or read it online at Safari to get the whole thing!
Web development, for all its usefulness, often happens with a curious inelegance. It's kind of like making sausage. I like the result, but I don't want to see how it's made. Web programming in Java was better than web programming in alternative languages. It gave you more structure with easier maintenance and, often, better scalability than Visual Basic or Perl-based approaches, and an easier programming model than C++. But for all the benefits, certain problems make it seem clunky and awkward.
Current web application servers might be powerful, but they're not convenient or natural. So, what is convenient and natural? It shouldn't take too much effort to figure that out. What if your controllers looked like this:
if (logon.show() = = true) {
mainPage.show();
}
or this:
if (shoppingCart.verify()) checkout.show();
That's better. What you really want to do is encapsulate the presentation of one or more web screens in a method. Then, more sophisticated page flows would not be a problem. You could simply roll up more and more pages into higher-level components. For example, you could take this code:
public static void showCheckoutWizard() {
checkoutAddress.showForm();
if(checkoutAddress.getSeparateBilling) checkoutBilling.showForm();
creditCardNumber.showForm();
}
so the usage becomes:
cart.showCheckoutWizard();
in its cleaner, refactored form. But you can't code that way, because your web server won't let you. Creators of most web application servers will sell their soul to keep things stateless and scalable.
Think of living without any short-term memory. Normal conversations in day-to-day life would be nearly impossible. Think of the logistics:
Additional content appearing in this section has been removed. Purchase this book now or read it online at Safari to get the whole thing!
You've probably played video games. Think of a continuation as a save game feature. As you're playing your game, you save your current game. You can feel free to take your chances with the monster control center. If you die, you simply restore the game. Said another way, a continuation is a snapshot of a point in time. Continuations let you save the system's state (in the form of an execution stack) in one place, and then return to that state on command.
Since I've already introduced Ruby's syntax, I'll first show you continuations in Ruby, where continuation syntax is clean and precise. Then, I'll show you Seaside, the most popular continuation-based server, in Smalltalk.
In Ruby, a code block defines the universe for the continuation. You'll use a continuation object to hold the execution state, consisting of the execution stack. You'll later invoke a call method on the continuation object to restore the system state, replacing the current execution state, including the call stack, with the one in the continuation object. The call returns execution to the point immediately after the code block. From Ruby's perspective, you're conceptually letting your execution state jump back in time.
In Ruby, you get a continuation by calling the callcc method on Kernel and passing it a code block. This block does nothing with the continuation but print its object identifier:
This passive little program does more than you think it does. The argument called continuation is a powerful little gem that has the whole execution context, with variable values and the entire call stack, at the time that you called callcc. Look at it as a saved game, or a frozen moment in time. You can return to that moment in time. Specifically, Ruby will return to execute the statement immediately after the continuation block by calling the continuation. Here's a trickier continuation example:
Additional content appearing in this section has been removed. Purchase this book now or read it online at Safari to get the whole thing!
You can probably begin to see why continuations might be interesting for web servers. If you want to look at a web application as one continuous application with suspend/resume breaks in between to communicate with the user, it makes more sense. While waiting for user input in the form of an HTTP request, the web server could simply store a state, stash the continuation object away in the HTTP session, and instantly return to that frozen point in time when it's time to process another request. Notice in Figure 8-1 that I've conveniently inverted the control. Instead of thinking of a web app as a series of request/response pairs initiated by the user, I can think of a web app as a series of response/request pairs controlled by the server. My server code gets much simpler.
Figure 8-1: Continuation servers invert control from client to server, simplifying the world view, and the code, of the server
Your web application server is no longer composed of many different independent requests. The server can conveniently look at the world as a bunch of simple end-to-end applications. It processes individual requests by loading the state of each user when it's time to process another request, and suspending the user's application when it's time to communicate with the user again. Voilá! Your application can maintain state, and use it to seamlessly control application flow.
At a lower level, the continuation server becomes a collection of web applications with states frozen at a point in time, in the form of continuations. Each user has a session. The continuation server assigns an ID to each session, and organizes the continuations per session. After each request, the continuation server takes a snapshot of the execution state with a continuation object, and associates that continuation with the session. So, a server has multiple sessions, and each session has one or more continuations representing frozen points in time, as shown in Figure 8-2. You can no longer see individual HTTP requests, because they're buried in the application flow. As they should be!
Additional content appearing in this section has been removed. Purchase this book now or read it online at Safari to get the whole thing!
Seaside is a highly productive web development framework written in Smalltalk. Avi Bryant initially developed Seaside in Ruby, in a framework called Iowa. Early Ruby continuations had a few problems, so the original author of Seaside moved to Smalltalk. Since then, he's been improving the framework and using it to deliver commercial applications. Seaside has a few defining characteristics:
Seaside renders HTML programmatically. Most Java frameworks render HTML with templates. I don't know enough to advocate one method over another, but it's certainly different, and it works well in Seaside's model.
Seaside
has a model for components. A Seaside component manages user interface state and renders itself in HTML. Seaside components are highly reusable, and they let you think in increments smaller than a page.
Seaside makes it easy to manage a link. You can specify a link with a code block, so links don't get out of sync. The framework manages them for you.
Seaside is modal. This is the author's word for a continuation server approach. Seaside lets you express one web page, or multipage web flows, in a single method.
Seaside's debugging is the best I've ever seen. From within the browser, you can open a web-based Smalltalk browser, complete with code. You can also inspect the values of all the objects in the application.
Of course, you also get the advantages of using a highly dynamic language. You get a rapid feedback loop, interactive interpretation as needed, and full access to Smalltalk's excellent environments. I used the Squeak IDE
for examples in this chapter. Squeak is a dialect of Smalltalk popularized by Disney.
Before we get too far, you should know a little Smalltalk syntax. Don't worry. I'm not saying that Smalltalk is the next great language; I just want you to see the power of the best continuations-based server. If you want to follow along, download the Squeak IDE from
Additional content appearing in this section has been removed. Purchase this book now or read it online at Safari to get the whole thing!
Under the /seaside heading, notice the list of apps. One of the examples that you see in the configuration screen is store. Click on it. You'll see SushiNet
, one of the more bizarre examples for web frameworks. In the search window, type the word Tuna. Click on two different tunas to add them to your cart. Now click the Back button and notice that you go back to a previous page, just the way it was. Add another tuna to your cart, and you'll notice that the old tuna item is still in your cart. So, you can override the Back button behavior, as needed.
Notice the three boxes across the top of the screen, in Figure 8-3. Seaside is a component-based architecture
. Each component has independent rendering, and each has a model behind it.
Figure 8-3: This Seaside application has three major components, each with independent rendering and business logic
This component-oriented approach often makes it much easier to design and refactor complex web screens. For example, here's the rendering for the shopping cart:
html divNamed: 'cart' with: [
html small: [html bold: 'Your cart:'].
html table: [
cart countsAndItems do:
[:assoc | self renderRowForCount:
assoc key of: assoc value on: html ].
html spacerRow.
html
tableRowWith: ''
with: ''
with: [html bold: cart totalPrice printStringAsCents].
]
Notice that Seaside components have code that generates HTML. Java people don't tend to like this approach either, but it's very productive in Seaside. The code in bold generates the table. First, you see the table message passed to the html object. This will generate table tags around the code block. Next, you'll see a loop that processes the items in the cart, a spacer row, and a row with the totals.
Additional content appearing in this section has been removed. Purchase this book now or read it online at Safari to get the whole thing!
I'm pretty sure that continuation servers will prove to be important. I'm equally sure that Seaside is not a killer app that will suddenly spring Smalltalk into the mainstream. Smalltalk has 30 years of reputation to overcome. In this time, Smalltalk has rarely been more than an academic language with small forays into commercial development. The Smalltalk community is smart and has technical vision, but I've not yet seen the marketing leadership that will break Smalltalk into the mainstream. After 30 years, that's not likely to change.
Continuation servers do have some minor hurdles to overcome:
So far, the servers require ugly, temporary URLs, because each continuation must have a unique identifier. Users don't like uglier URLs. Like Amazon, Seaside works around this limitation by providing a meaningful piece of the URL, followed by the continuation ID.
Continuation servers will not scale as well, because saving continuations is stateful and expensive, though if you think about it, the problem is not quite as bad as it could be. Most of the continuations in a server will have common code for the framework. Only the last part of the call stack should be different from one continuation to the next. Partial continuations should provide a good performance boost.
So far, the best servers are on academic languages. Lisp, Smalltalk, and Ruby may be holding them back. And of course, continuation servers may help break one of those languages closer to the mainstream.
Still, in the end, continuation servers will play a role, because they're a much more natural and powerful abstraction, and they represent a much more natural way to program. Systems continually get more processing power, and both short-term and long-term storage get cheaper. Productivity eventually trumps all else. In the end, continuation servers are fast enough. Higher abstractions make us more productive. If you held a gun to my head and forced me to make a prediction, I'd guess that continuation servers will evolve and break into the mainstream, but not on Java, or a derivative like C#. Such a language would have to simulate continuations. The concept is cleanest and purest when it is implemented on a more dynamic, higher-level language. I'd guess that continuation servers, in a language like Python or Ruby, may well prove to provide the foundation for all web application servers, in some not-too-distant future.
Additional content appearing in this section has been removed. Purchase this book now or read it online at Safari to get the whole thing!
It was my first Class IV river, and I approached the infamous Five Falls. In the typically tame Ouachita mountain range, the Cassatot—Indian for Skull Crusher—was serious. In all honesty, I wasn't ready for the river. Unseen gremlins sent massive jets and waves of water shooting through the waterfalls and toyed with me, smashing my boat against rocks, turning me around, and flipping me over at will. Yet, my guide seemed in complete harmony with every molecule of the river. He harnessed all the power the rapids threw at him, and danced his boat across the many chutes, waves, and even face of the waterfall known as the Washing Machine.
Throughout the run, every inch of my body hurt as I learned to push off my foot braces to integrate the rarely used leg muscles into every stroke, because on this particular river, I needed all the leverage I could get. At the takeout, exhausted, I slithered out of my boat. My guide hobbled out of his boat, and I couldn't speak. Both of his legs were amputated above his knees. I was stunned. He was able to do everything on the river without the added balance and power that two legs would have given him. Those few seconds completely changed my perception about what was possible in a kayak. More than any other, that moment shaped my paddling. Since I know how far I can come, I've always been looking for ways to use the boat, paddle, body, and river to do more work with less effort.
If nothing else, this book is about changing perceptions. Sure, the Java libraries have legs—libraries and community. But the community can be dysfunctional at times, and the culture is leading to increasingly complex libraries. The JCP seems to be getting in the way, valuing politics and committees more than good libraries hardened in the crucible of experience. There's something to be said for a fresh start on a stronger foundation.
So, don't let Java's built-in advantages always lead you to sell the alternatives short. They've come a long way. In this chapter, I'll touch on the major contenders and some also-rans.
Additional content appearing in this section has been removed. Purchase this book now or read it online at Safari to get the whole thing!
So far, I've taken an in-depth look at one language and two application development models. I just don't have the time or will to do a comprehensive treatment of languages, but this book wouldn't be complete without at least mentioning some of the major alternatives. I'll take a longer look at what I see as the major alternatives. Then, I'll mention a few alternatives that I see as less likely.
I've got a few things working against me. I like short books, so there's not enough time to do a remotely comprehensive treatment. Even if I were inclined to do so, my practical experience is limited to some Ruby
, a little Smalltalk, and a few lines of Lisp in college. I'm just one Java developer, who's prejudging the overall landscape based on my limited experience. In my favor are my broad and diverse network, an excellent set of reviewers, good access to corporate opinions at major vendors and customers, and a strong track record of predicting successful technologies.
Instead of picking a winner, I'd just like to lay out the factors in favor of a language, and those against. In such a short treatment of this problem, I'm not going to be able to do any remotely complete treatments of any given language, but based on Java's history and this community, I should be able to give you a good sense of what's important.
Language expert and creator of Wyvern
Steve Yegge, a graduate of the University of Washington, spent five years as an Assembly-language programmer at Geoworks and more than six years as a software development manager at Amazon.com. Steve somehow managed to find time to design, implement, and maintain a massive multiplayer game called Wyvern (https://www.cabochon.com/), with a half-million lines of Java and Python code.
Additional content appearing in this section has been removed. Purchase this book now or read it online at Safari to get the whole thing!
Now, it's time to put on an asbestos suit and my +4 plate mail. I debated whether to include any sections on Perl, Lisp, PHP, or Smalltalk. They're fantastic languages in their own right. I just don't think they're next.
If you're deeply religious about any of these languages, you can just read these one-sentence summaries, and skip to the next section: Perl's too loose and too messy, PHP is too close to the HTML, Lisp is not accessible, and Smalltalk wasn't Java.
If you already feel slighted and you must read on—if you're a language cultist and I've mentioned your pet language in also-rans, or worse, didn't mention your pet language at all—go ahead and fire up your Gmail client and your thesaurus, and drop me a nasty note. Ted Neward reviewed this book, so I can take a few more euphemisms for the word sucks. Just keep this in mind: I'm not saying that your language isn't good, or popular. I'm just saying 10 years from now, we probably won't look back at any of these languages as the Java killer.
Why won't Perl
replace Java?
SY: Well, I'd say Perl was pretty darn successful, and it's still one of the most popular languages around. Perl had world-class marketing: Larry Wall understands programmers, and he's funny and articulate. Perl filled a desperate niche in the Unix-scripting world, and another with CGI. Perl was successful because it was executed superbly, just as Java was.
I do think it's on the wane, though. Perl used to be more productive than the alternatives, so you could argue it was ugly all you wanted, but people got their jobs done faster. But newer languages, Ruby in particular, are changing the game.
Perl is the all-time king of pointless abstractions, like references and typeglobs, one-off shortcuts, and plain old gross hacks, with extra syntax sprayed on to cover the smell. It was productive, but programmers will take the path of least resistance, and Ruby offers orders of magnitude less friction.
Additional content appearing in this section has been removed. Purchase this book now or read it online at Safari to get the whole thing!
Of course, the whole premise of this book is arrogant beyond belief. I'm making an incredible number of assumptions and drawing some aggressive conclusions based on little more than a couple of dozen interviews, a keen sense of intuition, and a few massive piles of circumstantial evidence.
Java may need nothing more than a little overhaul. Maybe the problem is in the massively complex libraries, and a few rewrites with some tweaks of the language would extend Java's leadership for 10 more years. Maybe the community's culture doesn't help define our libraries. The driving vendors may do an about-face and focus more on simplifying the 80% path instead of building yet another XML-obsessed framework. The JCP could suddenly start supporting the best existing frameworks based on experience instead of standardizing a good idea that was born in a committee.
Maybe Dion Almaer is right, and the big companies that drive this industry are not remotely interested in moving away from Java, and we'll all be saddled with Java for the foreseeable future.
Maybe Jason Hunter is right, and the next big thing won't be a programming language at all. Maybe Java's all we'll ever need, and we'll use that foundation to move up the abstraction ladder. Maybe Glenn and David are both right and there won't be one next big thing, but lots of next little things, and both metaprogramming and continuations will play a significant role.
I don't know the ultimate answers, so I've leaned on my mentors and peers. The interviews in this book are the opinions of some of the people I respect the most. It's been an honor to share these few pages with them. I'm not ready to say that Java's dead, or that Ruby is next, or that continuation servers will reign supreme. I just know:
I'm hurting right now, and my customers are, too. It's getting harder and harder to teach my customers to satisfy themselves with Java.
Certain things, like baby-sitting a relational database with a web-based UI, should be easier in Java, after nearly 10 years of effort, but they're still cumbersome.
Additional content appearing in this section has been removed. Purchase this book now or read it online at Safari to get the whole thing!
Bruce A. Tate is a kayaker, mountain biker, father, author, and Java programmer in Austin, Texas. His five books include the Jolt award-winning Better, Faster, Lighter Java (O'Reilly) and the bestselling Bitter Java (Manning). His 17 years of experience include stints at IBM, two failed startups, and his own independent consulting practice, called J2Life, LLC.
Additional content appearing in this section has been removed. Purchase this book now or read it online at Safari to get the whole thing!