I believe that J2EE is the best platform available for enterprise software development today. It combines the proven merits of the Java coding language with the lessons of enterprise software development in the last decade. Yet this promise is not always fulfilled. The return on investment in many J2EE projects is disappointing. Delivered systems are too often slow and unduly complex. Development time is often disproportionate to the complexity of business requirements. Why? Not so much because of shortcomings in J2EE as because J2EE is often used badly. This often results from approaches to architecture and development that ignore real world problems. A major contributing factor is the emphasis in many J2EE publications on the J2EE specifications rather than the real world problems people use them to address. Many issues that commonly arise in real apps are simply ignored. When reading J2EE discussion forums, I'm struck by how little guidance and direction many developers find, and how much time and effort they waste as a result. In many cases, these developers have years of IT experience, and yet are finding it hard to come to grips with J2EE. The problem is not a lack of information about J2EE components. Many tutorials and web sites do a good job describing servlets, EJBs etc. Enabling technologies such as JNDI, RMI, and JMS are equally well served. The problem is in getting to the next level - taking these construction materials and using them to build apps that meet real business requirements in a reasonable period of time. Here, I feel that much of the existing literature on J2EE is a hindrance rather than help. There is a gulf between the world of J2EE tutorials - the world as it perhaps should be - and the real world of enterprise software projects. This tutorial aims to address this problem and provide clear guidance and direction on using J2EE effectively in practice. I'll help you to solve common problems with J2EE and avoid the expensive mistakes often made in J2EE projects. I will guide you through the complexity of the J2EE services and APIs to enable you to build the simplest possible solution, on time and on budget. I'll take a practical, pragmatic approach, questioning J2EE orthodoxy where it has failed to deliver results in practice and suggesting effective, proven approaches. I feel that no existing tutorial delivers this. The closest is probably Core J2EE Patterns from Prentice Hall (), which generated much excitement on its release. Here at last was a tutorial that addressed how to use J2EE components. Core J2EE Patterns is a good tutorial and a valuable resource for J2EE architects and developers. In particular, the terminology it uses has become widely accepted, but it's a Sun publication, and can't help reflecting the "party line". It also deals purely with the J2EE standards, paying little attention to issues encountered in working with real app servers. It fails to provide clear guidance: too often, it sits on the fence, presenting a variety of very different alternative "patterns". Readers able to choose confidently between them have little to learn from the tutorial. The more I considered the available publications, sample apps, and discussion forums, the more convinced I became that J2EE needed a healthy dose of pragmatism. J2EE is a great platform; unfortunately, many of the architectural practices promoted for it are not, and don't help to solve many common problems. Many J2EE sample apps, such as Sun's Java Pet Store, are disappointing. They don't face real world problems. They perform poorly, and their code often contains sloppy practices, providing a poor model. I was also struck by the difference in outlook between developers new to J2EE and those who had actually used J2EE to build enterprise systems. A former colleague used the wonderfully evocative word "gnarly" to describe developers who've come to grips with practical challenges of working with a technology and bear the scars. While those new to J2EE sounded like J2EE evangelists, the "gnarly" developers told a different story. They had had to jettison some of the ideological baggage of the innocents to implement necessary functionality or achieve adequate performance. Like my colleagues and myself, they'd found that reality intruded harshly on the initial vision. In this tutorial I'll draw on my experience and industry knowledge to help you design and develop solutions that work in practice, without the need for you to go through a painful process of discovering the difference between J2EE theory and reality.

J2EE Myths

I believe that the causes of disappointing outcomes with J2EE can usually be traced to a few common myths, which underpin many explicit and implicit assumptions in development projects:

Let's quickly consider each of these myths in turn. Portability is a great bonus of the J2EE platform. As we'll see, portability can be achieved in real apps, but it's not the point of J2EE. The requirement of the vast majority of projects is to build an app that solves a particular problem well on one target platform. An app that runs badly on one platform will never be ported to other platforms (the app might be ported to another operating system that runs on more powerful hardware to gain adequate performance, but that's not the kind of portability that professional developers aspire to). J2EE orthodoxy holds that an app should be portable across J2EE app servers and must be able to work with different databases. The distinction between these two goals is important, and sometimes missed. Portability between app servers may deliver business value and is usually a realistic goal. Portability between databases is much more fraught, and often provides no business value. Portability is usually taken to mean code portability: the ability to take the app and run it on another platform without any change. I believe that this is an expensive misconception. Naïve emphasis on total code portability often leads to heavy costs in lost productivity and less satisfactory deliverables. Write Once Run Anywhere (WORA), while a reality where Java itself is concerned, is a dangerous slogan to apply to enterprise development, which depends on a range of resources.


I'm not talking about the minority of projects to develop "shrink-wrapped" components (usually EJBs). This appealing concept is still to be proven in the market. Furthermore, I'm yet to see a non-trivial component that aimed for both, app server portability (which makes sense in this situation) and database portability (which will almost certainly be more trouble than it's worth).

I prefer Design Once, Re-implement a Few Interfaces Anywhere (DORAFIA). I accept that this is not so catchy, and that people are unlikely to leave Java One chanting it. This more realistic approach is widely used in other domains, such as windowing systems. The portability myth has led to wide acceptance that J2EE apps can't use the capabilities of today's relational databases, but should use them only as dumb storage. This does great harm in the real world. This is not to say that I don't believe that J2EE apps can or should be portable. I'm just arguing for a more pragmatic and realistic view of portability. We can design J2EE apps to be ported easily; we can't do the same thing with a proprietary technology such as .NET. It's pleasant to imagine that J2EE is the final stage of the evolution of enterprise architecture; that finally, the app of object technology and the Java language has cracked problems the industry has wrestled with for decades. Unfortunately, this is not the reality, although it's implicitly assumed in many approaches to J2EE development. J2EE builds on many of the technologies that preceded it. It's a step forward, but it won't be the last and it doesn't address all the issues of enterprise software development. Exaggerated emphasis on portability, along with this J2EE-centric attitude, has led to the assumption that if something can't be done in standard J2EE, it's a design error to do it. This is even creeping into the EJB specification with the introduction of EJB QL: a portable but immature query language that's more complex but far less powerful than the familiar, mature, and largely standard SQL that is available to the great majority of J2EE apps. I like to think of a J2EE server as the conductor of a group of enterprise resources such as databases. A good conductor is vital to any performance. However, a conductor doesn't attempt to play individual instruments, but leaves this to skilled specialists. Perhaps the most dangerous myth is that J2EE is the easy route to good performance and scalability, and that efficiency is a lesser concern than approved J2EE "patterns". This leads to naïve and inefficient designs. This is unfortunate, as outside the Java community Java has always been dogged by fears of poor performance. Today, the evidence is that the Java language offers good performance, while some popular J2EE "patterns" offer very poor performance. We cannot assume that the app server can take care of performance and scalability. In fact, J2EE gives us all the rope we need to tie up not only our J2EE app server, but the database as well. Had optimal performance been the main goal of software development, we'd have been writing web apps in C or assembly language. However, performance is vital to the business value of real-world apps. We can't rely on Moore's Law to allow us to solve performance problems with faster hardware. It's possible to create problems that prevent adequate performance, regardless of hardware power. The idea that the J2EE server should transparently handle low-level details such as data access is appealing. Sometimes it's achievable, but can be dangerous. Again, let's consider the example of relational databases. Oracle, the leading enterprise-class RDBMS, handles locking in a completely different way compared to any other product. The performance implications of using coarse or fine-grained transactions also vary between databases. This means that "portability" can be illusory, as the same code may behave differently in different RDBMS products. Oracle and other leading products are expensive and have impressive capabilities. Often we'd want (or need) to leverage these capabilities directly. J2EE provides valuable standardization in such infrastructure services as transaction management and connection pooling, but we won't be saying goodbye to those fat RDBMS product manuals any time soon. The "J2EE = EJB" myth can lead to particularly expensive mistakes. EJB is a complex technology that solves some problems well, but adds more complexity than business value in many situations. I feel that most tutorials ignore the very real downside of EJB, and encourage readers to use EJB automatically. In this tutorial, I'll provide a dispassionate view of the strengths and weaknesses of EJB, and clear guidance on when to use EJB. Allowing the technology used (J2EE or any other technology) to determine the approach to a business problem often leads to poor results. Examples of this mistake include determining that business logic should always be implemented in EJBs, or determining that entity beans are the one correct way to implement data access. The truth is that only a small subset of J2EE components - I would include servlets and stateless session EJBs - are central to most J2EE apps. The value of the others varies greatly depending on the problem in hand. I advocate a problem-driven, not technology-driven, approach (Sun's "J2EE Blueprints" have probably done as much harm as good, by suggesting a J2EE technology-driven approach). While we should strive to avoid reinventing the wheel, the orthodoxy that we should never ourselves implement something that the server can (however inefficiently), can be costly. The core J2EE infrastructure to handle transaction management, etc., is a godsend; the same cannot be said for all the services described in the J2EE specifications. Some will argue that all these problems will soon be solved, as J2EE app servers become more sophisticated. For example, ultra-efficient implementations of entity bean Container-Managed Persistence (CMP) will prove faster than RDBMS access using raw SQL. This is naïve and carries unacceptable risk. There is little place for faith in IT. Decisions must be made on what has been proven to work, and faith may be misplaced.

There are strong arguments that some features of J2EE, such as entity beans, can never be as performant in many situations as some alternatives. Furthermore, the Promised Land is still just around the corner. For example, entity beans were soon going to provide brilliant performance when they were first introduced into the EJB specification in 1999. Yet the next two years revealed severe flaws in the original entity bean model. Today, the radical changes in the EJB 2.0 specification are still to be proven, and the EJB 2.1 specification is already trying to address omissions in EJB 2.0.