Chapter 3

Java

Most application servers are built on a framework of Java, CORBA, or a combination of the two. This chapter provides a detailed look at many of the components and technologies of Java, particularly those related to distributed objects and server-side technologies, in order to provide a foundation for the chapters that follow.

History and Overview of Java

The term “Java” does not really apply to any single thing or technology. If one asked a room full of people what Java is, one would likely hear all of these responses, and more:

▪  computer language

▪  means of distributing programs over the Internet

▪  set of application programming interfaces (APIs)

▪  runtime environment

▪  distributed object framework

▪  development kit

▪  platform for computing

▪  compliance program

▪  the coolest logo that the computer industry has seen in a long time

▪  an attempt by Sun and many other vendors to diminish the dominance of Microsoft

The reality is that Java is all of the things listed. Java has been evolving since it first was introduced by Sun in 1995. Initially, Java was only a new language, albeit an exciting new language that garnered a lot of attention. It was designed for the Web, designed to be platform independent, and based on C++. Over the last few years, Java has grown and evolved into a complex set of related technologies based on a core of the Java language. Although Sun once considered handing the responsibility for Java to standards committees, Java remains managed and controlled by Sun today, although it provides a mechanism for the vendor community to provide input and direction. Nonetheless, Java has gained the support of many key players, including IBM, Oracle, and many others. Once more hype than reality, Java has matured and become an established cornerstone of many development tools and production products.

During the first year of Java’s existence, Sun made great progress in attracting and keeping widespread attention focused on Java. Netscape added Java support in version 2.x of its browser and Sun’s own HotJava browser was released. Sun formed JavaSoft as a separate division and tasked it with proliferating Java throughout the industry. Major licensees, including Microsoft, IBM, Apple, and SCO, signed up to support Java. The first version of the Java Development Kit (JDK) was released and included a compiler, an interpreter, class libraries, and a debugger. A database interface was created (Java Database Connectivity, JDBC) and a means of invoking Java methods remotely was introduced (Remote Method Invocation, RMI). The major tool vendors, including Borland and Symantec, announced that they would create tools for Java application development. An avalanche of technical books began to appear, and downloads of early Java specs and the JDK exceeded 40,000 per month. The JavaOne Conference, an annual user conference centered around Java and held in the San Francisco area of California, was launched.

By 1997, downloads of the Java JDK had increased to 300,000 per month. Java was evolving into a distributed component model with the 1996 introduction of JavaBeans and the 1997 introduction of Enterprise JavaBeans. Java was also gaining a growing number of APIs, including those for naming and directory services, richer security, multimedia content, and transaction services. The Java Foundation Classes (JFC) framework was enabling easier creation of GUI-based Java applications. Sun introduced the 100% Pure Java certification program to allow independent software vendors to certify their implementation of Java in their application. The third major release of the JDK, 1.2, was released in late 1997 and Java implementations were moving from the PC client to the server and small handheld devices such as smart cards.

During 1998 and 1999, Java continued to gain momentum both in terms of the number of active Java programmers and the number of commercially available Java products. In 1999, the Java 2 platform was announced, which marked a true point of technical maturity for Java technologies. With Java 2, developers have a complete computing platform upon which they can build. The Java 2 platform is available in a few different packages (micro, standard, and enterprise), allowing the developer to select the packaging of technologies appropriate for that particular application environment. The Java 2 platform, beyond packaging of various Java technologies, provides advances in the areas of security, deployment, performance, and interoperability.

The Java Language(s)

Java is a single computer language that was developed at Sun Microsystems. As already noted, the Java language is based on C/C++. It is compiled into byte-codes that are either interpreted at runtime or just-in-time compiled and then run. Java is a full-fledged computer language that offers strong type checking and other powerful features typical in compiled computer languages.

JavaScript is a scripting language that is, at least from a positioning standpoint, a cousin of Java. However, JavaScript was developed independently from Java at Netscape and was originally called LiveScript. JavaScript is often embedded within an HTML page and executed on-the-fly by the browser. Like many scripting languages, JavaScript is positioned as a simple language for non-programmers to use, in this case to easily enhance Web pages by adding dynamic elements.

Java

According to Sun, Java is “[a] simple, object-oriented, network-savvy, interpreted, robust, secure, architecture-neutral, portable, high-performance, multithreaded, dynamic language.”11 Whew! That is quite a mouthful. Each of the adjectives is examined in turn.

Simple

Java is similar in syntax to C++, a computer language used by thousands of computer programmers and students worldwide. However, Java is missing some capabilities of C++ that its creators believed were esoteric, confusing, and error-prone. Java’s advocates thus claim that Java is a simpler language to learn and to use. The absence of certain C++ capabilities, such as the use of pointers, also makes Java a “safer” language in that it does not allow a programmer to accidentally (or intentionally) corrupt memory.

One capability built into Java and lacking in many other languages is the automatic allocation and deallocation of memory. Programmers do not have to explicitly allocate memory for use in their programs and then worry about freeing up the memory; the system occasionally performs what is known as garbage collection to retrieve unused chunks of memory. This makes the programs easier to code but also less prone to bugs because memory reference errors are a common source of bugs in other languages such as C++.

One capability that is intentionally lacking in Java and present in other languages is the use of pointers. In languages such as C and C++, a pointer to a variable can be passed between subroutines and programs rather than the variable itself. Arithmetic operations can also be performed on the pointer. Pointers offer flexibility but are a very common source of bugs that are often very difficult to find and fix. Java eliminated pointers, thus simplifying the language and eliminating a common problem in other languages.

Java also eliminates the concept of a header file. The header file, in C and C++, is the place that the programmer places definitions of classes and data structures. The executable source files then reference the header files used in that particular program, method, or subroutine. However, if a header file changes, then all source files that refer to that header file must be recompiled, relinked, and retested. This can sap programmer productivity and makes the entire development process more unwieldy.

Also missing from Java, and present in C++, is the concept of multiple inheritance. In C++, one class can inherit characteristics from two different classes. There has long been a debate over the utility of multiple inheritance. Its relative usefulness must be balanced by the fact that multiple inheritance adds considerably to the complexity of the program and of the compiler. Java allows a class to inherit from only a single other class.

Having made all of these points about the simplicity of Java, it should be noted that Java remains a complex, high-level computer programming language. One should not expect a non-programmer, such as a Web author, to be able to pick up a book and learn to program in Java over a weekend (despite the claims that the books make). Its simplicity is relative to other high-level programming languages such as C, C++, and Smalltalk.

Object Oriented

Java was designed from the start to be an object-oriented language. The concept of object orientation was described in Chapter 1. Quite simply, in object-oriented programming, one defines objects and methods. The objects are the nouns and the methods are the verbs. Therefore, one programmer can create an object called a customer with certain allowable methods that can be applied to the customer object: change address, add transaction, credit payment, etc. The actual details of how the customer is implemented are hidden from other programmers and programs, but others can utilize the object class. This enhances reuse of code and adds greatly to overall productivity.

Java supports two characteristics of strongly object-oriented programming languages: inheritance and polymorphism. Inheritance, as described in Chapter 1, allows one class to inherit the characteristics of another class, creating a tree-like structure of inheritance. Thus, the class book can inherit all of the characteristics of the class product. The creator of the class book then only needs to design the unique characteristics of that class and inherit the common characteristics of all products (e.g., price, size, weight, order lead-time). Polymorphism refers to the ability to process things differently, depending on the particular class. For example, the class product can have a method salestax that calculates the state sales tax on an item. However, the sales tax might depend on the type of product. Clothing and food items may have no tax; most other products may have 6 percent tax, and luxury items may have 10 percent tax. Polymorphism allows the derived classes (book, clothing, food, etc.) to redefine the salestax method so that it is always correctly calculated for all products.

The promise of a vast marketplace of Java objects is becoming fulfilled. Third-party developers are offering Java components for sale that will vastly simplify and speed the deployment of new applications. For example, classes and components are available in the marketplace for an online shopping cart, an online catalog, credit card processing, etc. Organizations that wish to deploy a new E-commerce application can purchase the various components and focus on adding the unique characteristics of the application.

Network Savvy

Java was created with the Internet in mind. As such, it has native support for TCP/IP and higher-level related protocols such as File Transfer Protocol (FTP) and HTTP. Java allows programmers to open URLs and access objects across the network as easily as they can access files on the local file system. Java includes Remote Method Invocation (RMI), which allows remote, network-connected objects to be easily invoked. RMI handles the details of setting up the communication link between the two systems and passing data back and forth.

Interpreted

Java is an interpreted language. When a programmer creates a Java program, it is (usually) compiled into a byte-code stream. In a traditional compile-and-link process such as used with C++, the output of the compile-and-link stage is object code that is specific to the particular platform for which it was compiled. With Java, on the other hand, the byte-code that results from the compilation stage is machine independent. It is when the Java program is run that the byte-code is interpreted into machine-specific instructions. For example, a Java applet is downloaded from a Web server in Java byte-code format. When the applet is executed on the client’s machine, the virtual machine on the client system interprets the byte-code into machine-specific instructions that are executed on-the-fly.

The downside of an interpreted program compared to a compiled program is in execution speed. The processor must read the byte-code and transform it into machine-dependent code before it can actually execute the code and do the work. This is done for each byte-code instruction, so the processor ends up doing much more work than if the code were all ready to execute in native machine language. Early critics of Java (such as some at Microsoft) often cited this performance problem as a reason why Java would not replace traditional, compiled programming approaches. Since then, however, the emergence of just-in-time (JIT) compilers has virtually eliminated the Java performance hit. With a JIT compiler, the entire byte-code stream is compiled into native machine code before the application is initiated. With this approach, the only performance hit is taken at the very beginning, when the application is first initiated. JIT compilers have brought the performance of Java applications almost to parity with applications written in C++. Some JIT compilers can even take in Java source code and directly create machine code without the explicit intervening step of byte-code, thus even eliminating the up-front hit.

Robust

A robust language is one that prevents problems from occurring and detects problems before they are able to corrupt or crash the system. In other words, a robust language avoids and detects bugs before they become a problem.

As already detailed in the discussion on Java’s simplicity, there are several error-prone and bug-inducing features of C++ and other languages that are omitted in Java in order to enhance Java’s robustness. Java provides automatic allocation of memory when required and periodically performs garbage collection to return memory that is no longer being referenced to the pool of available memory. This prevents memory depletion problems, in which a system’s memory is depleted because memory is allocated but never freed, and memory corruption problems, in which memory is freed but a reference to it remains and is used in the future. The other important omission from C++ to enhance robustness is the lack of pointers. Because pointers in C++ can be arithmetically manipulated, it is a simple task for a programmer to inadvertently modify a pointer to legitimate data. By manipulating the pointer, it now points to a completely unintended and arbitrary place in memory. If the application begins to write to that memory, the results can be catastrophic. Worse, pointer reference errors are very difficult to troubleshoot and fix. By eliminating these two common causes of errors, Java can claim to be a more robust language.

Java is a strongly typed language. This means that the compiler enforces explicit data type declarations so errors can be detected at compile time rather than at runtime. Although C and C++ are also strongly typed, they do allow a number of compile-time loopholes that are closed in Java. Java also performs array bounds checking during runtime so that programmers cannot inadvertently wander outside the bounds of an array and corrupt memory in that way.

Secure

Because Java was designed to operate in a networked environment, great care has always been taken to ensure that Java offers security mechanisms that prevent the destruction of a client system through the download of malicious code. The original security model, implemented in the first version of the Java Development Kit (JDK), is known as the sandbox model. In this model, code that is downloaded has very limited and restricted access to the local system. A downloaded applet is presumed to be untrustworthy and can therefore not access the local file system and other key local system resources. Code that originates locally, however, (i.e., loaded from the local file system) has full access rights to all system resources because it is presumed to be safe.

The sandbox model is very effective in preventing harm to the local system from malicious code. However, it severely restricts the flexibility of applications in a networked environment. Therefore, the model has evolved and become less restrictive in subsequent versions of the JDK. The first step in loosening the sandbox restriction was taken in JDK 1.1 with the introduction of the concept of a signed applet. Using public key/private key cryptography technology, a signed applet from a trusted source is treated like local code and has all of the access rights given to local code. Signed applets are delivered in signed Java ARchive (JAR) files. Applets that are not signed by a trusted source are subject to the sandbox restrictions.

This all-or-nothing approach to local system access evolved in JDK 1.2 to allow all applets and applications to be subject to a security policy. With this approach, the system administrator or the individual user can configure various levels of permission for applets from various signers or locations. The two extremes of access control — no local access versus complete local access — remain options. However, the administrator or user can define a variety of different domains, each given varying degrees of local access. Exhibit 3.1 illustrates the evolution of Java security.

Architecture Neutral

Java is neutral to computing architecture, which is another way of saying that it is a platform-independent language. This is largely due to the fact that Java is interpreted, and the code that is generated is the machine-independent Java byte-code. This allows the same applet or servlet code to run on a handheld device, a Microsoft Windows-based PC, an Apple Macintosh, a UNIX or Linux server, or any other platform that supports the Java virtual machine and runtime environment.

Image

Exhibit 3.1 Evolution of the Java Security Model

Portable

Portability is related to platform independence. Java is portable because the Java byte-code is the same, no matter what the target platform. However, there is another element to portability. C and C++ contain certain implementation-dependent aspects, such as the size and representation of integers and floating point numbers. These languages were created a number of years ago while there was a wide diversity of different platforms with varying computing power. Since then, with the advancement in chip capacities, a certain common denominator of computing power can be assumed. Thus, Java has defined an “int” as always being a signed two’s complement 32-bit integer, and a “float” as a 32-bit IEEE 754 floating point number.

Other aspects of portability include the Java libraries and the Java system itself. The libraries define portable interfaces, and there are implementations of the libraries available for all common operating environments. The Java system itself is highly portable. The compiler is written in Java and the machine-dependent runtime is written in ANSI C with a clean portability layer.

High Performance

Sun claims that Java is high performance, while others (e.g., some Microsoft types) claim that Java cannot have high performance compared to code that is compiled specifically for a certain platform. As already stated in the discussion on the interpreted nature of Java, the byte-code-to-machine-language step is normally performed on-the-fly as the program is executing. This extra processing necessarily means that the processor must do more work and can therefore execute fewer instructions per period of time than a language that is already compiled to its native machine-dependent code. As already detailed, the presence of JIT compilers tends to erase the performance gap of Java, assuming that the JIT compiler is relatively efficient and optimized for the target platform.

Multithreaded

Java has built-in support for multithreading. Programs written in a traditional language such as C are single-threaded. Each program is initiated through the execution of the program named main (), which maintains control throughout the execution cycle except when it temporarily passes control to subroutines. In a multithreaded environment, on the other hand, a program is broken into separate pieces known as threads. The threads communicate with one another but otherwise are somewhat autonomous units of computing. A thread is the lowest level of work that is scheduled and initiated by the CPU.

A programmer can create a multithreaded environment using a traditional single-threaded language such as C, but the onus for all of the control of the threads and the interaction is on the application programmer. Java incorporates a set of sophisticated synchronization primitives that allows programmers to much more easily incorporate multithreading into their programs. By incorporating these elements into the language itself, the resulting program can be more robust because the language and system take care of the details of the multithreading implementation on behalf of the programmer.

Dynamic

A side effect of Java’s interpreted design is that interconnections between various modules and components is made later in the cycle, typically at runtime. This has enormous benefits in making Java very dynamic. In a traditional compile-and-link programming environment, a single object module is created at compile time. All external references are resolved and different modules are linked together. If one module changes later on, the entire program may need to be recompiled and relinked before the changes can take effect.

This can create a serious problem for application developers, particularly if different groups or even different third-party software companies provide the various pieces and components of the overall product. The release of a new version of one piece of the overall product could cause a recompile of all programs that use that piece. Worse still, the interface to that piece may have changed, meaning that all other code that accesses the code may break and need to be updated as well.

In a Java environment, programmers or third-party software providers can freely add to their libraries of methods and variables without impacting existing software that utilizes the objects defined within. This means that the development paths of the various components that comprise an overall solution can proceed independently and without coordination, recompilation, or broken interfaces.

In summary, Java advocates make claims that make Java sound very compelling indeed. There are detractors, of course, and others who delight in pointing out the “problems” of Java. Some of the problems are not unique to Java but rather stem from the fact that yet another language is proliferating that requires its unique development tools and compilers and creates another programmer learning curve. True; but if Java solves real problems, then this is a small price to pay in the long term. Some of the problems of Java often cited (i.e., lack of access to system resources, performance) have been addressed over the five or so years of Java’s existence. Java’s remaining real “problem” appears to be over the question of the relevance of platform independence (i.e., Sun’s Write Once, Run Anywhere) versus platform-specific but language-neutral programs that are efficient and fully utilize the power of the local operating environment (i.e., Microsoft’s ActiveX). An organization’s collective attitude toward Java may depend on where it stands on this somewhat political and religious issue.

JavaScript

JavaScript was created at Netscape as a means to add dynamic content to Web pages. Before JavaScript, Web pages were either static or they were made dynamic through the use of server-side scripts using the Common Gateway Interface (CGI) standard. With JavaScript, Web pages are made dynamic through the inclusion of script commands embedded and intermingled with HTML and, like HTML, are interpreted and acted upon by the browser rather than the server. Although the Netscape team responsible for developing JavaScript may have modeled some of the syntax of this scripting language after Java, the two languages were developed independently because they each served different purposes. The initial internal name for the scripting language was LiveScript, but the name was changed to JavaScript before its release to leverage the growing popularity of Sun’s Java.

The JavaScript code is embedded within a Web page and is interpreted and acted upon by the browser. JavaScripts are delimited by the HTML tags <script> and </script> within a Web page. The script code that is placed between these tags can perform any number of dynamic and interactive functions, for example, change the appearance of a button when the mouse rolls over it, pop up a question box or questionnaire that users need to fill in before they proceed, or expand a list of site navigation options when the mouse rolls over a particular navigation category. The primary advantages of placing these dynamic and interactive functions within the HTML code rather than on a server script is that the responsiveness to the user can be much better, there is no impact to the server in terms of processing and CPU utilization, and the impact on the network is much lower.

While the Java language and JavaScript share certain syntactical similarities, in most environments the people who use the two languages will differ. Java is a full and complex programming language and development environment. Web programmers who are creating new business logic based on Java and its related APIs, components, and platforms will use Java. Programmers who are building new applications using the new generation of Java-based application servers will also use Java. JavaScript, on the other hand, is a relatively simple scripting language that does not meet Java’s complexity or its power. As a tool to enliven Web pages, JavaScript will be used by Web site designers and Web page authors.

The Execution Environment

The execution environment is the set of components required, either on a client system or a server system, to execute Java programs, applets, or servlets. The execution environment includes the virtual machine, class libraries required in any Java environment, and possibly JIT compilers and other components. Note that the execution environment is only required for Java programs, not JavaScripts. Support for the JavaScript language is built into the browser, which knows how to correctly interpret and execute the JavaScript statements.

Image

Exhibit 3.2 Basic Components of the Java Virtual Machine

Java Virtual Machine

The Java virtual machine (JVM) is the heart of a Java system. The virtual machine (VM) is the runtime environment that interprets Java byte-code into machine-specific language and executes that code. The VM includes the interpreter for programs that are run as they are interpreted, and it may include a JIT compiler for programs that are compiled when loaded before they are run. The VM is also responsible for implementing and enforcing the Java security model and for providing basic runtime services for Java programs. Exhibit 3.2 illustrates the basic components of a JVM.

Initially, VMs were primarily distributed as a component of a browser. In this model, the VM is implemented within the browser program and it executes Java applets. Exhibit 3.3 illustrates a typical client system with a browser and a VM executing Java applets. Since the early days, VMs have been implemented on most server and client operating systems. Any system with a JVM can execute Java programs, applets, and servlets. A VM can also be packaged with Java applications to ensure that the target platform has the requisite VM support, such as might be the case in a specialized Internet appliance.

Image

Exhibit 3.3 Client with Browser and JVM

Java byte-code is stored in a particular type of file called a class file format. When one hears about Java class files or class libraries, these are simply individual files or sets of files that contain Java byte-code in a given binary format that is independent of underlying hardware system or operating system. All JVMs must be able to correctly read, interpret, and act upon the code stored in class files. A VM must also be able to manage memory, perform garbage collection on the memory, implement Java security, etc. But in its most basic description, a VM is an entity that reads and executes class files.

The Java language and virtual machine are inherently multithreaded. This means that a JVM must be able to manage multiple threads and the interaction between threads. To do this, the VM manages common data areas and thread-specific data areas during runtime operation. The shared areas of memory include a heap (the common pool of storage from which storage for variables and arrays are allocated) and the method area (a common area that is logically a part of the heap that stores per-class structures that may be referenced by multiple threads). Each time a thread is initiated, a JVM stack for that thread is created. This is a stack that stores local variables and partial results, much like the push-and-pop stacks commonly used in other environments. There are many different types of memory structures managed by the virtual machine.

The JVM dynamically creates, loads, links, and initializes classes and interfaces. Creation of a class or interface is triggered by its reference by another existing class or interface (except the initial class, void main (String [ ]), which is initiated at VM start-up). The class or interface is loaded by locating the representation of that class (i.e., the corresponding class file) and creating an instance of the class in memory. Linking is the process of combining the class with the state of the runtime environment so that the class can be executed. Finally, initialization is the process in which the initialization method for the class or interface is executed.

The Java byte-code executed by the VM consists of an opcode specifying the operation to be performed, followed by zero or more operands specifying values or variables that the opcode will act upon. For more information on the Java opcodes and operands, refer to The Java Language Specification, published by Sun Microsystems.

The VM, as already stated, must also implement memory management, garbage collection, and Java security methodologies. Sun Microsystems does not specify how these are to be implemented — only how they must appear to classes, interfaces, and users. Therefore, these elements of the VM are implementation dependent.

Java Runtime Environment

The Java Runtime Environment (JRE) is a package of elements that allows a platform to support Java programs, applets, and servlets. The current version of the JRE consists of the JVM, core Java classes, and supporting files. The JRE is also packaged with a plug-in that allows common browser platforms to execute Java applets. The JRE does not include development tools such as the Java compiler.

The JRE is licensed by Sun Microsystems and downloadable from the Sun Web site. The JRE license allows third-party developers to package the JRE with their application at no charge so that customers of that software application are guaranteed to have the correct version of the virtual machine and related files. The license agreement indicates that the JRE must be distributed in full, with the exception of certain files that may be excluded if not required for a particular application (e.g., localization files). The JRE can be combined with the application files in a Java ARchive (JAR) file. The advantage of JAR file bundling is that JAR files can be compressed, minimizing the time to download the application if it is distributed over a network.

Java Development Kit

The Java Development Kit (JDK) has been recently renamed the Software Development Kit (SDK) with the introduction of the Java 2 platforms. Whether called a JDK or SDK, this kit is targeted to software developers who are creating Java programs, applets, or servlets. The JDK/SDK includes the components of the JRE (the virtual machine, core Java classes, supporting files) in addition to elements required by Java programmers — specifically, the compiler, the debugger, an applet viewer, all classes and APIs that may be required to create a Java program, and other developer-oriented tools and files.

Although the JDK/SDK is available without charge from Sun Microsystems, the license does not allow organizations to redistribute the JDK/SDK with their application software. This is what the JRE is for. Third-party software providers should use the JDK/SDK internally in the creation of their Java application, and then bundle the application with the appropriate JRE for distribution to their end customers.

Java Components and APIs

The Java language was designed from the start to be object oriented. However, it was a year or more before a component model was added to Java with the 1996 introduction of JavaBeans. A year later, Enterprise JavaBeans was introduced, which extended the object model to the server. A variety of enterprise APIs have also been added over time to allow Java programs and components to communicate with a wide variety of other systems in the enterprise.

JavaBeans

JavaBeans is the original component model for Java. It predates Enterprise JavaBeans, an extension to the component model for server-side components, and the Java 2 platform framework. Support for JavaBeans is available in JDK 1.1 and later versions.

Having said that JavaBeans is a component model, what exactly is a component? A component is a pre-built piece of software that has well-defined boundaries. It can be viewed as a “black box” implemented in software. That is, it has specific and defined inputs, and outputs that are predictable based on the inputs. However, the inner workings of the black box are hidden from the rest of the world. A component is a mechanism by which independent objects can be created and then leveraged as a whole by other programs. That is, a new program can be stitched together using off-the-shelf components, with the programmer focusing on stitching the components together and providing new and unique business logic.

This definition of a component is similar to the description of the benefits of object-oriented models. Thus, a key question is: is any object-oriented model equivalent to a component model? The answer is: no, not necessarily. Object orientation can be viewed as a necessary but not sufficient attribute of a component model. However, object-oriented frameworks do not necessarily lead to reusable code. One of the reasons for this is the very powerful notion of inheritance. Very large frameworks of classes can be built using inheritance. If one of the base classes changes in any substantial way, the effect can be propagated to all subclasses of that base class. The result is a complex, interdependent hierarchy of classes that requires programmers to understand the interrelationships between the classes. This monolithic structure also makes code reuse impractical in many situations and applications.

A component, on the other hand, is a stand-alone element that is not externally a part of a large hierarchy of classes. A component may be very complex internally and be built using class structures and inheritance; but to the rest of the world, the component is only viewed by a clean, external interface that is not interdependent upon other components. Exhibit 3.4 illustrates the difference between an interdependent set of classes and individual components.

Image

Exhibit 3.4 Interdependent Classes Compared to Components

Component models have been developed over the past decade or so following the paradigm called PME, which stands for Properties, Methods, and Events. PME defines the characteristics, behaviors, and communication interfaces to a component. Prior to JavaBeans, the PME model was implemented by a variety of vendors in a variety of different models, including Microsoft’s COM, Apple’s OpenDoc, and Delphi’s VCL.

In PME, a property is defined as an attribute or variable, together with its value. A property could represent how a component appears, its current state or reading, its display properties, etc. A property is examined or changed by other external agents, such as other components, using Get and Set methods. Methods are the operations upon which the component will act. For example, an address book component may add contacts, display contacts, and make a particular contact part of a group of contacts. Events are the output of the component, the way in which the component communicates with the outside world (i.e., another component) that something has happened. Events can be synchronous, meaning that they are output as the event is occurring; or they can be asynchronous, meaning that they are output some time after the event has occurred. In the address book example, a synchronous event to the DisplayContact method may be the output of the particular contact information. An asynchronous event to the AddContactToList method may be confirmation of the action of adding a contact to a particular distribution list.

JavaBeans is a component model that implements the PME paradigm. A bean is a Java component that adheres to the JavaBeans model. A bean, like a Java applet, can be embedded within an HTML page. Beans can be visual elements that are distributed to users and can be interactive and event-driven. Beans can also be invisible, as would be the case for beans that live on servers. A bean that adheres to the JavaBeans model has the following characteristics, and Exhibit 3.5 illustrates a bean that has these characteristics:

▪  defined PME

▪  introspection

▪  customization

▪  persistence

Because the JavaBeans model is based on the PME paradigm, beans must have defined properties, methods, and events. A bean must have properties that can be read and modified by external tools or other components. A bean’s properties can be defined by the programmer as read/write, read-only, or write-only. The JavaBeans model adheres to the principle that its properties cannot be directly changed or manipulated, but the values of properties can be changed or manipulated (if defined as read/write or write-only). The JavaBeans model supports single-value and indexed properties. Properties can also be either bound, which means that interested parties are notified via events if the value of a property changes, or constrained, which means that interested parties can veto the modification of a property’s value. Methods are those actions that a bean will perform. Events are the bean’s notification to the outside world that something has occurred. In the JavaBeans model, interested parties (i.e., other components) can subscribe to a bean’s event, meaning that they will be notified when the event occurs. Using a visual development tool, an event-driven chain of interaction between different beans can be created.

Image

Exhibit 3.5 A JavaBean

Introspection is the ability for other components and tools to discover the PME interfaces of the bean. Without introspection, the bean interfaces must be published in static form. If the bean changes, then the published interface specification becomes out-of-date. Introspection allows the interfaces to be read or sensed in real-time as the bean is being accessed or incorporated into a program using a visual development tool. JavaBeans have two basic mechanisms for introspection. The first mechanism, known as reflection, allows an external entity to discover the signature of the bean’s interface in real-time. This is accomplished when the bean adheres to a set of naming conventions by which the bean’s methods can be ascertained by the use of common semantics, primarily used for the setting and getting of properties and the sending and receiving of events. The second mechanism involves the use of an explicit class, BeanInfo, which is provided by the bean’s programmer and provides an explicit description of the bean.

Customization is the ability of a programmer to change the properties of a bean to suit a particular use or implementation. This is really the ability to change the value of the property — not to change the fundamental set of bean properties, as described above. To encourage the reuse of beans, the JavaBeans model enables bean programmers to provide a lot of hooks to the outside world so that potential users of the bean can easily modify the bean through the use of a visual development tool. JavaBeans specifies a Customizer class that can be used to provide a wizard-like dialog to interface with the bean or property sheets that allow easy customization.

Persistence is the ability for the bean to maintain state across various executions and requires the ability to store the state of the bean in nonvolatile memory, such as on a hard drive. The bean programmer can make fields in a class persistent simply by defining them as “serializable” up front. Fields that should not be saved are defined as transient or static. The JDK provides the serialization mechanism and also supports versioning, which allows a newer bean to load state information written by an older version of the bean.

The JavaBeans model was defined from the start with the idea that programmers and non-programmers alike would utilize visual development tools to build applications that utilize the beans. Visual development tools that are “bean-aware” are available from a number of different vendors (e.g., Symantec, Borland, IBM). These tools provide a GUI-based, drag-and-drop interface that allows beans to be easily manipulated and incorporated into programs without having to write code from scratch. The tools present a toolbox and palette interface and allow the programmer to drag-and-drop a bean, modify its appearance, define its interaction with other beans using methods and events, and then create a Java application, applet, or new bean.

There is a difference between a design-time bean and a runtime bean. The design-time bean is the superset that has all of the information needed by the visual development tool, including such things as the property editor, BeanInfo class, Customizer class, icons, etc. While these items are necessary to allow a visual tool to easily utilize and customize the bean, their presence in a runtime environment adds unnecessary bloat. Beans can (and should) be packaged into separate archives (JARs) for design-time and runtime.

Sun Microsystems offers a JavaBeans Development Kit (BDK) for developers of tools and beans. The BDK is licensed in addition to a JDK. The BDK includes:

▪  BeanBox test container (i.e., a reference container that demonstrates how a container is built)

▪  example beans that run within the BeanBox and demonstrate a variety of bean behaviors

▪  variety of reference source code

▪  makefile information

▪  JavaBean tutorial

Since its introduction in 1996, the JavaBeans architecture has been extended with three new APIs intended to facilitate the interconnection of beans at runtime. The first, the Extensible Runtime Containment and Services Protocol (also known as the BeanContext API), allows a bean to interrogate its environment at runtime. Before this API was available, bean introspection and reflection happened during design time only. That is, a programmer using visual development tools was able to determine the properties, methods, and events of a bean through introspection and create a program utilizing that information by interconnecting beans together. The BeanContext API supports a logical containment hierarchy in which beans can be grouped together in a logical and traversable manner. The services API of BeanContext allows beans, during runtime, to discover what services are available from other beans and to connect to those beans to make use of the services.

The second JavaBeans extension, the InfoBus extension, was originally defined by Lotus. InfoBus enables the dynamic exchange of information between different beans. Its name is based on the concept of an information bus between components. The InfoBus specification defines a small number of interfaces for cooperating beans and defines the protocol used for the communication between the beans. All beans that implement InfoBus can plug into the bus and exchange information with any other bean connected to the bus.

The third extension to the JavaBeans model is the JavaBeans Activation Framework JAF). JAF allows a bean to elicit certain information about data in a runtime environment so that it can act properly upon that data. A common example about the usefulness of JAF is in a helper application that needs to be able to discern the contents of a file in order to display it. For example, a Web browser could determine that a particular stream of data is a JPEG image file and therefore display it properly as a JPEG. JAF determines the type of arbitrary data, encapsulates access to the data, discovers operations available on a particular type of data, and instantiates the software used to operate on a particular type of data.

Development of the JavaBeans model was an important piece in the evolution of Java. With the addition of the JavaBeans component model, Java began to be viewed as a programming environment rather than just a programming language. While JavaBeans was an important development, it was the later addition of Enterprise JavaBeans and enterprise-class APIs that allowed Java to completely fulfill its promise as a total computing framework capable of supporting the enterprise and its variety of applications.

Enterprise JavaBeans

Enterprise JavaBeans (EJB) is positioned as an extension of the JavaBeans model for server-side, transactional-based applications. However, the two frameworks are very different because they are solving very different technical problems and address different markets and requirements. JavaBeans is targeted to the client development community. As such, the focus of the JavaBeans framework is to facilitate the creation of client-based components using visual development tools. Beans developed using the JavaBeans framework typically reside in a single address space, such as on a desktop or handheld device, and are often GUI elements like buttons, viewers, etc. EJB, on the other hand, is targeted to the enterprise, transaction-oriented, multitier application environment. In this environment, the focus is on building scalable enterprise systems that can support thousands or tens of thousands of users.

EJB is a component model for server-side components. Like client-side components, server components are reusable and may be purchased, off-the-shelf elements that an enterprise programmer can use to build unique business applications. The EJB specification defines not only the component interface and how components communicate, but it also defines a complete set of middleware services provided by the EJB server. These services are provided on behalf of the components and include security, transactional integrity, persistence, and other services.

An EJB component is called an enterprise bean. An enterprise bean cannot execute on a server on its own — it requires a container. A container is the environment in which an enterprise bean runs. It provides the middleware services to the enterprise bean, and shields the enterprise bean from direct interaction with the client. When the client application invokes the enterprise bean through a defined method, the container intercepts the invocation to manage security, persistence, and system resources. For example, the enterprise bean does not manage threads, processes, or memory. These are managed by the container. The reason for this goes back to the goal of scalability in a server environment. The container parsimoniously manages scarce system resources to maximize the scalability of the server. Therefore, when a thread is no longer needed or is not being utilized at the time, the container returns the thread and memory to a common pool to be used by active beans. A container may contain one enterprise bean or many enterprise beans.

There are two different types of enterprise beans: session beans and entity beans. A session bean can be viewed as a somewhat transient entity that is created by the client and usually only exists for the duration of the session between the client and the server. Session beans can be stateful or stateless. A stateful session bean maintains state during a conversation with the client that spans multiple methods. For example, a stateful session bean may be a shopping cart that keeps track of a customer’s choices and then executes the sale when the shopping session is complete. A stateless session bean is one in which state is not maintained between methods. An E-commerce example of a stateless session bean is a credit card authorization method.

An entity bean is viewed as a persistent entity that represents the backend resources of the EJB server. In the current EJB model, the entity bean usually represents a hook to a relational database. An entity bean is usually invoked once and persists throughout the duration of many client/server sessions. An example of an entity bean is the concept of a Customer. The entity bean developer would decide which fields of a given set of customer databases are relevant and then would define the methods that could operate upon the Customer bean. Many clients can access the Customer bean identity at any given time, although only one client could manipulate a particular instance of the Customer bean (e.g., Mary Jones). Exhibit 3.6 illustrates the difference between a session bean and an entity bean.

Entity beans are persistent, but there are two types of entity bean persistence: container-managed persistence (CMP) and bean-managed persistence (BMP). As the names imply, the difference between these two models of persistence has to do with which entity manages the persistent data and connection. In the CMP case, the container manages persistence. The bean developer does not have to write any explicit code to synchronize database queries or updates. The enterprise bean developer simply indicates which fields should be persistent. In the case of a relational database, a persistent field may be associated with a particular column in a table. The container takes care of the synchronization and alerts the bean when fields have been populated with data from the database or when data is about to be written to the database. CMP is not limited to relational databases; CMP beans can be mapped to flat file systems and other legacy data systems.

Image

Exhibit 3.6 Session Beans and Entity Beans

A BMP bean, on the other hand, synchronizes its state with the database manually (i.e., by the bean programmer). BMP provides more flexibility to the bean programmer but demands greater sophistication on the part of the programmer. Entity beans that need to access several data sources, including perhaps legacy systems, are good candidates for BMP rather than CMP. CMP provides an excellent set of services, but may not meet the needs of all environments; when more sophistication and control is required, BMP may be necessary. The BMP bean manages its own persistence, but the container still provides other services to the BMP bean, such as security and read/write coordination.

The relationship between an enterprise bean (either session or entity) and its container is referred to as a contract. The contract defines an established set of services and a clean interface boundary, allowing beans to reside within the containers of multiple different vendors. The enterprise bean and the container communicate through one of three mechanisms:

1.  Callback methods. Every enterprise bean must implement several callback methods that alert the bean to several events. For example, a callback method will alert an enterprise bean when the container is about to remove the bean from memory, write its state to the database, etc. A callback method is a means to allow the enterprise bean to perform housekeeping duties.

2.  EJBContext. Every enterprise bean must define an EJBContext object, which allows the bean to interact with the container to request information about its environment.

3.  Java Naming and Directory Interface (JNDI). This is the Java enterprise API that allows Java objects to access naming systems such as Lightweight Directory Access Protocol (LDAP) servers and NetWare Directory Services (NDS) servers. The JNDI interface is a fundamental part of the EJB architecture, allowing clients to locate EJB components.

The bean-container contract definition includes the communication mechanisms described above, in addition to a set of rules that defines the operation of the enterprise bean and the container at runtime. The contract is meant to support portability, so that enterprise beans can run in a variety of different containers. Another benefit of the contract is that it simplifies the development of enterprise beans. Because the container manages system resources, persistence, resource location, etc., the enterprise bean can focus on business logic rather than infrastructure logic. The services provided by the container include the following:

▪  Life cycle. The container manages process allocation, thread management, memory management, object creation, and object destruction on behalf of the enterprise bean.

▪  State management. Enterprise beans do not need to implement logic to save and restore state information between method invocations; these duties are performed by the container.

▪  Persistence. The container manages persistent data on behalf of the enterprise bean.

▪  Security. The container authenticates users and checks authorization levels on behalf of the enterprise bean.

▪  Transactions. The container can manage the start, enrollment, commitment, and rollback of database transactions on behalf of the enterprise bean.

The client application interacts with the enterprise bean through two different “wrapper” interfaces. These interfaces shelter the enterprise bean from direct contact with the client and provide the middleware services for the enterprise bean. The first wrapper interface, EJB Home, provides access to the life-cycle services of the bean. Using EJB Home, the client can locate, create, or destroy an instance of an enterprise bean. EJB Object is the wrapper interface that provides access from the client to all of the business methods that are acted on by the enterprise bean. In other words, EJB Object implements all of the methods that are externally accessible for the enterprise bean except the create and destroy methods. The EJB Object for a particular enterprise bean implements either the entity bean interface or the session bean interface, depending on the type of the bean. Exhibit 3.7 illustrates the enterprise bean model with the client wrapper interfaces.

There are two enterprise APIs and sets of services that are a fundamental part of the EJB architecture: JNDI and RMI. The container automatically registers the EJB Home interface in a directory using JNDI for each enterprise bean defined in that container. This allows clients to locate the enterprise bean in order to create an instance of the enterprise bean. Once the instance is created, the container returns the EJB Object interface to the client so that it can then issue methods to the bean.

EJB uses the Remote Method Invocation (RMI) API to handle the communication between the client and the enterprise bean on the server. RMI is the API defined by Java to allow distributed objects to communicate. The RMI compiler creates a stub for the client, which is then either installed on the client or downloaded over the network. This stub handles all the details of the communication with the server. The RMI specification does not specify a communications protocol to be used over this connection. The native protocol, supported in the original EJB implementation, is Java Remote Method Protocol (JRMP). EJB 1.1 has added support for CORBA’s Internet InterORB Protocol (IIOP), which will facilitate the interaction between CORBA and Java environments. For example, using the common IIOP protocol, CORBA clients can communicate with enterprise beans and Java clients can communicate with CORBA objects.

Knowing what an EJB server does, it is time to examine where it operates within an enterprise. An organization utilizing EJB servers will still, obviously, have Web servers and browser-based clients. The Web servers (i.e., HTTP servers) still respond to user requests for pages of information. The Web server, or a separate server, may also be a servlet engine executing Java servlets. The EJB server can be viewed as another layer that sits between the Web/servlet servers and the enterprise databases. Exhibit 3.8 illustrates the overall enterprise server architecture.

Image

Exhibit 3.7 Enterprise Bean Wrapper Interfaces

Image

Exhibit 3.8 EJB Server in the Enterprise

The Web clients will usually access the enterprise beans (and the EJB server) via servlets or JSP code. A client applet could, in theory, access the EJB server directly but the applet’s browser must be equipped with J2EE, JNDI, and RMI classes. Because this requirement severely limits the number of browsers that can directly access the EJB server, it is recommended that the hooks to the EJB server be coded on a JSP page directly or through the combination of JSP and a regular JavaBean. The JavaBean code becomes an intermediary that allows the JSP code to be quite simple and promotes reuse because multiple JSP pages can rely on the same JavaBean for access to the EJB server.

As of this writing, the current EJB specification is version 1.1, which is the second major release of the specification. Version 2.0, the third major release, is currently out for review and comment but is not expected to be finalized with products implementing it available until some time in 2001 or 2002.

To summarize, an EJB server is an entity that supports the creation of distributed server-side objects in a Java environment. The EJB server and its container provide a number of services to these objects, known as enterprise beans, that facilitate the creation of enterprise beans and promote scalability and security. The EJB server parsimoniously manages scarce system resources on behalf of the enterprise beans to ensure that the server can scale to support thousands or tens of thousands of clients.

How, then, does an EJB server compare to definition of an application server? There is a great deal of overlap, and one could certainly argue that an EJB server, at the current specification level, is a specialized application server that handles database transactions. A more complete application server, however, includes hooks to other types of enterprise applications. A more complete application server also provides sophisticated load balancing and a more complete security model, among other things. The EJB specification will evolve over time, perhaps including these other services. For now, a true application server may include an EJB server engine but then augment that engine with other services and APIs.

Enterprise Java APIs

The EJB specification makes use of some — but not all — of Java’s enterprise APIs. The enterprise APIs are intended to provide access to a variety of enterprise resources, including directories, legacy applications, policy servers, and CORBA applications. The list of current enterprise APIs is provided in Exhibit 3.9. This exhibit is followed by a brief description of each of the APIs that has not already been discussed.

Java Authentication and Authorization Service (JAAS)

The initial concept of security in a Java environment focused on the notion that applets are downloaded to client systems. The early sandbox model and its subsequent enhancements are all code-centric security models, in which the user is authorizing code from a particular source to be trusted in part or completely. However, this model does not deal with the security from a server standpoint, in which the user must be authenticated and then authorized to perform a given set of tasks. This is a more traditional view of security from the perspective of enterprise applications.

With the proliferation of server-side Java applications, JAAS provides a framework to allow multiuser applications to authenticate users and assign privileges. The JAAS authentication framework is based on pluggable authentication as defined by X/OPEN. With this framework, the system administrator can “plug in” any authentication module that adheres to the PAM standard and that is appropriate to the situation. JAAS extends the existing Java 2 security policy that allows administrators to define which resources are accessible to authorized individuals.

Exhibit 3.9 Current Enterprise APIs

Image

Java Interface Definition Language (Java IDL)

IDL is a concept used in CORBA to define objects and their interfaces (see Chapter 4 for a complete description). Java IDL is an implementation of this IDL to allow Java applications to define, implement, and access CORBA objects.

While Java IDL is still supported in Java 2, the addition of RMI-IIOP has rendered Java IDL somewhat obsolete. As described earlier, RMI-IIOP represents the marriage of Java’s RMI with the IIOP used in CORBA. This allows Java objects to access CORBA resources and vice versa. With RMI-IIOP, programmers can write CORBA interfaces directly into their Java applications without requiring the intervening Java IDL.

JavaMail

The JavaMail API provides a set of abstract classes that model a mail system and a platform to build Java-based mail and messaging applications that are platform neutral and protocol independent.

Java Database Connectivity (JDBC)

JDBC provides Java applets and applications access to a variety of existing databases. That access may be direct in the case in which the database vendor has provided a native JDBC interface, or it may be through some driver or middleware that converts the JDBC to some other native format expected by the database. JDBC supports SQL databases as well as tabular data and data found in flat files.

Java Message Service (JMS)

The Java Message Service API facilitates the asynchronous communication between various different applications. A message-based application is not synonymous with an e-mail application. A message-based application shares reports, events, or requests asynchronously with other message-based applications. E-mail is one example of a message-based application. However, JMS facilitates the creation of distributed, enterprisewide applications that asynchronously share events, data, and information to allow each application to track the progress of the enterprise.

Java Management Extensions (JMX)

The JMX specification defines a management architecture, APIs, and management services under a single umbrella. JMX does not, on the other hand, specify a new management protocol. Rather, it works with existing systems and network management protocols such as Simple Network Management Protocol (SNMP). Using JMX, any Java application can be management-enabled with just a few lines of code.

The JMX architecture is divided into three levels: the instrumentation level, the agent level, and the manager level. In addition, JMX provides a number of APIs to allow JMX applications written in the Java language to link with existing management technologies.

Java Transaction API (JTA)

JTA is a service-oriented API that provides a demarcation for transactions. Programmers use JTA to group multiple different operations into one or more logical transactions. JTA provides three types of services: transactional operations in clients, transactional operations in application servers on behalf of clients, and global transactional management in a Java transaction manager.

Java Transaction Service (JTS)

JTS specifies the implementation of a transaction manager that implements JTA and also implements the CORBA Object Transaction Service (OTS). A JTS transaction manager provides transaction services to the parties involved in distributed transactions: the application server, the resource manager, the stand-alone transactional application, and the Communication Resource Manager (CRM).

Java 2 Platform

Sun announced the “Java 2” name in December of 1998, just as it was beginning to release the initial technology for the Java Development Kit version 1.2. Since then, the Java platforms have all assumed the Java 2 branding. There are three platforms — Standard Edition, Enterprise Edition, and Micro Edition — each packaging various Java technologies for a given environment. The Java virtual machine and the Java programming language do not, however, take on the Java 2 branding.

Java 2 Platform: Standard Edition

The Java 2 Platform, Standard Edition (referred to as J2SE), is a collection of the essential Java Software Development Kit (SDK, previously referred to as the JDK), tools, APIs, and the Java runtime. This collection is targeted to developers of Java applets and applications. The platform is not a piece of software; it is the abstract functionality that is implemented in the SDK and the JRE.

The version of J2SE that is shipping at the time of this writing is version 1.3, announced in May of 2000. This release added the Java HotSpot Client VM for increased performance and a smaller footprint on the client. Several enterprise APIs are bundled with J2SE, including RMI-IIOP, Java IDL, JDBC, and JNDI. However, the Enterprise Edition platform is the one targeted to the development and deployment of enterprise application and has the complete set of enterprise APIs.

J2SE is available for license at no charge and the SDK and JRE source and binary code are available on the Sun Web site for download. Platforms supported by J2SE include Solaris, Linux, and Windows (2000, 98, 95, NT 4.0).

Java 2 Platform, Enterprise Edition

The Java 2 Platform, Enterprise Edition (J2EE), is targeted to developers of enterprise-class, server-side applications. It is this platform that forms the basis for Java application servers and also the basis for custom-developed business applications. J2EE is a superset of J2SE. Although J2SE supports some of the enterprise APIs, J2EE includes all of the enterprise APIs including, notably, EJB. With EJB support, J2EE becomes a complete framework for server-based applications. Exhibit 3.10 summarizes the capabilities of J2SE and J2EE.

There are four deliverables of the J2EE platform:

1.  J2EE platform specification: specifies the Java APIs that must be supported in order to be compliant as a J2EE platform and defines a common way of packaging applications for deployment on any J2EE-compatible platform.

2.  J2EE compatibility test suite: a suite of tests, provided and licensed by Sun, that allows programmers to test their implementations to ensure conformance to the J2EE platform specification.

3.  J2EE reference implementation: an implementation, provided by Sun, that is the “gold standard” for adherence to the J2EE platform specification. The reference implementation is not a commercial product and its licensing terms do not allow its commercial use. However, it is available for free in binary form and may be used for demonstrations, prototyping, and research.

4.  J2EE blueprints (formerly referred to as the J2EE application programming model): design guidelines that represent the best-practices philosophy for the design and building of J2EE-based applications. The philosophy for building n-tier applications is provided in addition to a set of design patterns with a set of examples on how to build the applications.

The model of computing that results from the implementation of J2EE platforms and applications is depicted in Exhibit 3.11.

Exhibit 3.10 Comparison of J2SE and J2EE

Image

Source: Sun Microsystems.

Image

Exhibit 3.11 J2EE Model of Computing

The popularity of J2EE is growing rapidly, in large part due to the fact that the platform provides a great deal of the infrastructure required to build many different types of applications, including:

▪  distributed object technology

▪  security

▪  persistence

▪  messaging

▪  transaction interface

▪  application deployment

▪  database connectivity

▪  server middleware and resource management

As a result of the J2EE infrastructure, application programmers are finding that they are able to implement new applications faster. Further, most of the leading application server vendors have licensed J2EE and plan to integrate the platform into their offerings. Chapter 5 provides a complete overview of application servers and Chapter 7 provides a description and comparison of some of the leading application server offerings available in the marketplace.

Java 2 Platform, Micro Edition

The Java 2 Platform, Micro Edition (J2ME), is an optimized Java runtime environment to support consumer devices and embedded systems such as pagers, cellular phones, screenphones, set-top boxes, and car navigational systems. J2ME is designed to support these consumer devices, which often have very limited resources, with the same portability and safe network delivery that is the hallmark of Java technologies. Applications that are written using J2ME can later be scaled upward through the use of J2SE or J2EE.

Final Thoughts

Java has evolved at really a dramatic rate when compared to other computing languages, models, and architectures. In only five years, it has become a complete set of platforms targeted to desktop, server, and consumer electronic systems. The amount of press devoted to Java, the number of vendors supporting Java platforms and technologies, and the exponential growth in the number of Java programmers all attest to its widespread appeal and relevance to implementing E-business solutions.

The original excitement surrounding Java centered on the client. Java applets, downloaded at will and on demand from Web servers, would facilitate the replacement of big, complex, and difficult-to-manage desktop PC systems with a new breed of thin, inexpensive, and easy-to-manage network computers (NCs). Industry leaders and luminaries heralded the end of Microsoft’s stranglehold on the industry and the dawn of a new era of thin-client computing.

However, Java applets that had meaningful functionality were very slow to download. JVMs were also resource-hungry and slow. As a result, the NC industry stalled and many early predictions about the dominance of Java-centric thin clients failed to materialize.

Nevertheless, the evolution of Java continued, and server-side Java technologies like EJB and enterprise APIs renewed interest in Java for server-based servlets and applications. Server-based computing is proving to be the brass ring for Java. J2EE, in particular, is allowing the rapid proliferation of the complete set of Java technologies within enterprises. Application servers based on the J2EE platform are now common and are rapidly gaining acceptance.

It is worth pondering the role of standards bodies in the quick evolution and deployment of new, disruptive technologies such as Java. Sun originally indicated that it would hand over responsibility for Java evolution and development to standards bodies. However, it decided against that move and instead has maintained control over Java. It does, however, involve the user and vendor community in providing requirements, input, and reviews through the Java Community Process. Sun has also been very “open” about Java technologies; complete disclosure through documentation and sometimes even the release of source code has been a standard operating procedure.

It can be argued that Sun’s stewardship of Java has provided a level playing field for all interested parties. A level playing field is the general reason that user and vendor communities tend to prefer standards bodies to control and define technologies rather than a single vendor with its own agenda and commercial interests. However, the standards process is typically characterized by its glacial speeds. The standards process sometimes creates standards that are bloated and late. Java, on the other hand, has gained a lot of functionality in a relatively short period of time.

The end result appears to be that Java will gain an irretrievable foothold in many enterprise environments. Alas, this cannot be said for some technologies that have complete blessings of a vendor-neutral standards body. For example, CORBA, the subject of Chapter 4, has evolved over a number of years through the leadership of the Object Management Group (OMG). Some argue that Java’s success is in part due to the failure of CORBA to quickly evolve to embrace Web technologies. Whether this criticism is fair, it is clear that Java is enjoying wider vendor and user support. Sun must be doing something right in its stewardship of Java.

Note

1.  See http://java.sun.com/docs/overviews/java/java-overview-1.html.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.225.55.151