To save content items to your account,
please confirm that you agree to abide by our usage policies.
If this is the first time you use this feature, you will be asked to authorise Cambridge Core to connect with your account.
Find out more about saving content to .
To save content items to your Kindle, first ensure no-reply@cambridge.org
is added to your Approved Personal Document E-mail List under your Personal Document Settings
on the Manage Your Content and Devices page of your Amazon account. Then enter the ‘name’ part
of your Kindle email address below.
Find out more about saving to your Kindle.
Note you can select to save to either the @free.kindle.com or @kindle.com variations.
‘@free.kindle.com’ emails are free but can only be saved to your device when it is connected to wi-fi.
‘@kindle.com’ emails can be delivered even when you are not connected to wi-fi, but note that service fees apply.
The persistent object layer forms the foundation of the application server. This layer is responsible for creating, initializing, and storing business objects derived from relational databases or other external applications. It also serves as the object broker for the application server, tracking and locating business objects already in memory. All of these tasks must be done quickly and efficiently to provide fast response time but must also work carefully to maintain the integrity of the data.
When an object is requested, the persistence layer must know how to access the data from a storage medium such as a relational database, then create the requested object from the data. Once the object is created, the new object must be registered into a data structure where it can be quickly located when the same object is requested by another process. The persistence layer must also provide concurrency control and synchronization to ensure that the data remains consistent with the database and other processes and is not corrupted when more than one process attempts to modify the attributes at the same time. The objects must also be synchronized with changes that occur in the database from other external applications so that the database itself is not corrupted.
This chapter will illustrate how to create a simple persistent object layer and discuss the implementation and programming issues involved. Although the Java language and JDBC will be used to illustrate the problems and tradeoffs that must be considered, the implementation could just as easily be done using C++ and ODBC. Java was chosen for its simplicity and brevity, not because it is a superior platform.
Part 2 examines the issues involved in designing an open, scaleable application server architecture. These include requirements analysis, user interface and business object design, persistent storage, and application integration. Emphasis is on user involvement through joint application design teams, use cases analysis, and incremental, iterative development.
Over the past year or so, quite a few software vendors have released packages they call application servers. Inprise, Oracle, BEA, and a number of others all have jumped onto the application server bandwagon, extending their product lines with products that target enterprise computing. So, what exactly is an application server?
This chapter will explore the reasons why application server technology will play an important role in the next generation of enterprise computing. Topics include:
Two-tiered vs. multi-tiered computing
Why I chose multi-tiered client/server
What can an application server do?
Costs and disadvantages of application servers
Moving from traditional client/server to n-tier computing
Two-Tiered vs. Multi-Tiered Computing
There are quite a few advantages to traditional two-tiered client/server. The database products are very mature with heavy competition to constantly improve performance and features. Client-side development tools like Microsoft Access, Borland Delphi, and C++ Builder have become so easy to use that much of the code writes itself. Even the networks are easier to install and maintain.
But as most client/server developers soon discover, it is almost too easy. New applications multiply on the server and, with the constantly plunging price of computers, more clients keep coming on board. In no time at all, the server is overloaded. Even after all of the memory slots have been filled, more CPUs have been added, and thousands of dollars have been spent to upgrade the network, the users still complain that response time is too slow.
Up to now, this book has looked at application servers as abstract concepts—first from an architectural view, then from the designer's vantage point. It's almost time to roll up our sleeves and start the real work: translating the abstractions into program code. But before we can start programming, we need to establish a general framework that can hold the service interfaces, business objects, and persistent objects that implement the server. This chapter bridges the discussion between design and programming, describing how to establish this framework.
In addition to the program framework, we must also create an organizational framework that manages and structures the development process. This includes communication channels, programming tools, testing strategies and other administrative details. Although the emphasis of this book is on the technical side of application server development, these topics will also be discussed in this chapter.
This chapter will examine the following topics:
The application server framework
Additional application server requirements
Development strategies
The Application Server Framework
In the previous chapters, we examined each of the different application server layers as separate entities, each having different responsibilities and requirements. This is the advantage of using a layered architecture: each layer can be examined on its own, viewed independently. Business object design can focus on the needs of the application. Service interface design can implement services for the user interface. The persistence layer design can focus on mapping business objects to their representation inside databases or persistent storage. By focusing on a single layer at a time, it is easier to manage the complex requirements of the application server design.
To those outside the application server team, an application server is just a set of services that support the user interface programs. The user interface collects data and then sends it to the application server, where the data is processed. Depending on the result, the application server returns either the requested data or an error message. The user interface programmers do not need to know how the service interface does its job—only that it works according to the specifications.
This is the goal of a good service interface design. The implementation details should be irrelevant to those working with the services. The services are well defined and documented and the results are understood, but only the application server programmers need to know how the results are obtained.
This chapter will examine how the service interfaces are designed, from use case analysis through design specifications. The topics covered will include:
What is a service interface?
Design by interface
More on JAD: developing use cases
Turning use cases into services
Building services out of business objects
What Is a Service Interface?
A service interface is more than just a list of function calls specified by the user interface programmers. Each interface should contain a set of standardized services that not only make sense within the context of a single application, but conform to an organization's standard application architecture. This requires each service to conform to standard naming conventions and use consistent parameter-passing and exception-handling protocols. The user interface programmer should be able to take a new service interface and quickly and easily integrate it into an application with a minimum of research and testing.
A service interface is a set of consistent, easy-to-use application services that can be called by user interface programmers to perform the tasks requested by the user. When the post transaction button is clicked, the user interface calls the post transaction service, supplying the relevant data items. The user interface programmers have no need to know how the transaction is posted; they simply need to know how to request the appropriate post transaction service.
Once the data is supplied to the service interface, it is up to the application server programmer to ensure that the necessary business objects are retrieved by the persistent object layer and that methods are called to perform all of the tasks requested by the service interface specification. If the business objects are designed correctly and the persistence layer can correctly retrieve the business objects, programming the service interface should not be a difficult task.
What complicates service interface programming is the additional layers of middleware managing objects distributed over a number of different computers. This restricts the amount of data that can be passed between the client and the service interface, since much of the data must be passed through network connections and be marshaled to meet the requirements of the remote machine's data format. The network also adds a multitude of new exception and error conditions that must be anticipated. As an added restriction, the same service may be executing simultaneously for a large number of different clients, each requesting services for any number of different sets of data.
This chapter will examine these technical requirements and explore some of the programming techniques available to address these challenges.
One of the most striking differences between traditional client/server development and the application server environment is the need to service a large number of users simultaneously. Instead of relying on database servers to manage concurrent access, it is now the responsibility of the application programmer to anticipate these needs, making sure that one user's service request does not interrupt or corrupt another service already running. Because of this added complexity, the programmer must decide when objects can be shared, when separate instances must be created, how to synchronize persistent data between objects, and how to coordinate changes in data when there is a chance that it can be modified by other applications.
Fortunately, you have many tools and techniques available to handle these issues. You can purchase middleware tools to replace some of the functionality that used to be provided by the database server. Most development environments provide tools to manage concurrent access, object brokers can assist in life cycle management, and transaction monitors can support complex application dependencies. There are also techniques that can ease concurrency and life cycle management. Application server implementation is far more complex than traditional client/server development, but with the proper approach, your application framework will be open, robust and ready to grow with your business.
This chapter will examine the following issues:
The trouble with multiprocessing
Multiprocessing within the application server
The class factory model
Multi-threading
Synchronizing objects and data
Transactions
The Trouble with Multiprocessing
Multiprocessing, the ability to service many different users at the same time on the same machine, introduces several new issues that are not often addressed in traditional client/server development.
Part 1 offers an overview of application server architecture, describing its benefits in the business environment and providing an overview of its fundamental technologies including multi-tiered client/server computing, distributed applications and middleware.
According to the vendor literature, it appears that moving to multi-tiered client/server computing is as simple as buying a few products, creating a few Web pages, and writing a little bit of application code. In a recent Microsoft presentation, a company representative created a simple three-tiered application in less than ten minutes (Microsoft, Inc. 1998). He built a Web page with a couple extra lines of VBScript code, displayed about twenty lines of Visual Basic code that was already installed on the transaction server, and then with a few mouse clicks, showed how easy it was to validate a customer number. Too bad the transaction server code only returned “credit OK” if the customer number was 123456789.
Microsoft is not the only vendor using this approach to sell middleware products. Although the vendors make the development process look easy, these products are complex pieces of software. Just learning the programming conventions and protocols can take weeks, while producing industrial-strength code could take months. Tools like the Microsoft Transaction Server can make programming somewhat easier for developers by providing communications protocols and development frameworks, but even the simplest service will take far more than twenty lines of code.
This chapter will examine the application server from an architectural viewpoint and will also examine the major categories of middleware software. Topics will include:
Overview of the application server architecture
Middleware—the glue that holds it together
Middleware categories
Applying middleware to the application server architecture
The application server model will be an effective approach for building software in the twenty-first century, but it is only one of many different options available to the business software developer. Mainframe computing is still effective for large corporations, as millions of lines of code still perform their tasks effectively every day. Two-tiered client/server also offers an excellent option for less intensive database applications and there are a host of different Internet technologies available to deliver applications to Web browsers. In addition to existing technologies, the rapid rate of change will continue to bring new computing models that will spawn new software technologies. Just as client/server was a response to desktop computers, and a host of new software technology appeared in response to the Internet, other new technologies will continue to rise and shape the way that we build software.
Looking into the future is a difficult and perilous task. Even the best minds in the industry have trouble seeing beyond the next few years. To see how well others have fared, I got out the book Programmers at Work, published in 1986 (Lammers 1986). The book is a collection of interviews with some of the industry leaders of the time; early Mac developers Jeff Raskin and Andy Hertzfeld, dBase author Wayne Ratliff, VisiCalc designers Dan Bricklin and Bob Frankston, and of course Bill Gates.
What initially drew me to application server technology was the need to support constantly changing, complex business rules. Traditional two-tiered client/server worked well for data intensive applications, but as the processing requirements grew, it became difficult to create and manage large client-based programs that supported these complex requirements. Moving the business logic to centralized application servers simplified both software development and code distribution.
Today's business applications are expected to move far beyond simple data management chores, performing business intelligence and decision support tasks for all levels of the company. Business requirements are also constantly changing, with new products and processes introduced in ever-shorter business cycles. Applications must not only encapsulate existing business logic, but be structured openly to allow quick response when rules change.
Business rule processing takes on a variety of forms, from simple data validation to complex data classifications and business processing logic. Encapsulating these processes in program code that can respond to changing requirements is a challenging task. Often, implementing rule processing around data structures instead of program code enables more flexibility and ease of maintenance. Commercial business rule processors and languages can also make the task easier to manage.
This chapter will examine how to incorporate complex business rules and processing into the application server environment. It will examine what a business rule is, how to implement the rules in program code, where to place the logic within the application architecture, and how to standardize error handling and reporting. Application security will also be examined, both as an application server issue and as a way of illustrating how to implement complex business rules.
The goal of business object design is to create a collection of reusable software objects that model your business. While interface design is a bottom-up approach, used to determine application requirements, business object design is a top-down analysis of the entire business, identifying roles and functions. Business objects are formed by specifying properties and services that reflect the real-world objects they model. As with real-world objects, software objects often combine and collaborate to perform tasks that they cannot perform individually.
Object design requires a global view of the organization, determining not only the needs of the current task, but the functions required for the entire business. Objects must be designed for reuse across both the current application and be ready for use in the next project, even if the project is for another department or a different line of business. Although not a simple task, it is not as difficult as it seems. Business objects mirror people, forms, and other objects that have already been integrated into the business. As such, when the objects simulate these functions, they also fit inside the same business context.
The object designer cannot possibly know all of the business requirements, so designing all functionality from the beginning is an impossible task. Business requirements are constantly changing and today's needs may not be relevant tomorrow. Business objects must be designed as open, dynamic components that can easily be changed without impact on other functions.
You've read everything you can find about middleware, CORBA, transaction monitors, message brokers, enterprise JavaBeans, and other distributed technologies. Now it's time to put them to work. Time to build your company's first multi-tiered application. But where do you start? How do you structure the programs? How do you distribute the code? What about integrating existing applications and databases? This was the problem that I faced as I began working with multi-tiered development. There was plenty of information on the tools and technologies, but little on how to make them work in a business setting.
Application servers and related technologies offer great promise and potential for solving the issues that trouble corporate computing. Problems like scalability, application integration and code reuse. But before we can solve these grand problems, we have to figure out how to use the technology. How do we process orders, ship products, bill customers, approve loan applications and pay insurance claims.
My hope is that this book will offer some guidelines to start you on your way. Instead of focusing on middleware, the emphasis is on the design issues and programming techniques necessary to create an overall business application framework. The approach is user-centric, relying on joint development between developers and business people, using short, iterative design-program-review cycles. Object-oriented development is also stressed using designs illustrated with UML and programming examples written for the Java platform. Although Java and RMI are used, the framework will work with almost any language or distributed object platform.
Part 3 describes tools and processes that can be used to transform the user requirements into working program code. These chapters examine how to implement the business objects and place them into a framework that services the user interface programs.
The promise of Java as a truly distributed software platform is now a step closer to reality. The recent integration of Java archive functionality significantly improves the ability of developers to manage and transfer disbursed data over large networks. Specifically, Java now provides two disparate areas of archiving functionality that address the same issue: an improvement in download time—but through different means. Java Archive files, or JAR files, allow an entire applet's dependency list to be transferred in the form of a single compressed file, while Java's archiving classes provide functionality for the programmatic manipulation of files in various compression formats. Given the benefits of archives in a distributed model, I will detail some of these newly integrated features, as well as demonstrate how archive functionality can improve enterprise applet performance.
JAR FILES
Introduced with the JDK 1.1, Java Archive files provide a vastly improved delivery mechanism for applets. An entire applet's dependency list (all. class files, images, sounds, text, etc.) can now be aggregated into a single compressed file, which can then be transferred over a single HTTP connection. Once downloaded, JDK 1.1-compliant browsers can then seemly decompress and run the applet. The result of this process is a marked decrease in the time it takes to launch an applet, due in part to a reduction of both the bytes transferred and number of dependency-based HTTP transactions.
Java Archive files are based on the popular ZIP archive format as defined by PKWare.
Java and corba fit together. With Java, you have portability of code and platform independence. With CORBA you add location transparency and an enterprise level object model that allows us to interoperate with a multitude of existing languages and integrated or legacy systems.
One of the most important steps when designing your client applications and applets is how they should bootstrap into the CORBA system. With a good system design, you can make this bootstrapping phase straightforward and avoid any bottlenecks along the way. You need to consider how CORBA servers should distribute CORBA object references so that clients can easily and efficiently find them. Some of your decisions may be made at the relatively early IDL design phase, while others can be implemented as late as when you deploy your clients and servers.
BOOTSTRAPPING A CORBA APPLICATION
A CORBA application only needs to obtain one CORBA Object reference (otherwise known as an Interoperable Object Reference (IOR)) for it to be able to connect to and participate in a CORBA system. From then on, a CORBA client or server should be able to obtain new IORs through normal IDL invocations. Therefore, it is the mechanism by which a client or server obtains this initial object reference that can be vital for a CORBA system's overall accessibility and scalability. The most interoperable and scalable solution to locating CORBA objects is to use the CORBA Naming Service.
Java is becoming important for building real-world, mission-critical applications. Although Java is still not a perfect language, it is becoming more mature every day. We all know the advantages of Java, especially the “write once, run anywhere” approach, but we are also aware of the disadvantages (its performance being the most commonly offered reason for not using Java).
In spite of that, there are many large companies claiming they are developing their crucial business applications in Java. Modern applications are not monolithic programs, they are built of objects. Therefore, developers need a “glue” for bringing all the pieces together and coordinating them into a functional application. Object location independence is an advantage that gives developers the ability to structure the application into multiple tiers.
For building distributed applications in Java it is natural to choose the Remote Method Invocation (RMI), but there is another possibility—the Common Object Request Broker Architecture (CORBA). CORBA is a valuable alternative to RMI. We could describe CORBA as a superset of RMI, although both technologies are not compatible yet. Both CORBA and RMI allow remote method invocation independently of location, however, CORBA is more than just an object request broker. It offers programming language independence and a rich set of object services and common facilities all the way to the business objects.
There are multiple factors that can affect the decision. One of them is certainly the performance.
In the first article of this series, Tim Matthews described how JavaSoft is developing a Java Cryptography Architecture (JCA) and extensions (Java Cryptography Extensions, or JCE). He described their contents and structure in the java.security package, and outlined their uses. In the second installment, I presented some actual code using the base functionality in the JCA. This third article describes programming using the JCE and multiple providers.
After reading this article, you will, I trust, be able to write a program in Java (an application or applet) that can encrypt or decrypt data using DES and create an RSA digital envelope with the extensions package. Beyond the specific example presented here, though, I hope you will understand the JCE model enough to be able to quickly write code for any operation in the package, and to be able to use multiple providers.
Before beginning, however, it is important to note that the security packages are not part of the JDK 1.0.2, only JDK 1.1 and above. Furthermore, there are significant differences between the security packages in JDK 1.1 and 1.2. This article (and the previous) describes features in 1.2. If you have not yet left 1.0.2 behind, now would be a good time to do so. After all, with 1.2, you are not only getting the security packages, you are also getting improved cloning, serialization and many other features.
There is an important change from JDK 1.1 to 1.2, the JCE is in a different package.