Survey
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
Software Architectures for Integrating Clients, Servers, Legacy, Database, and COTS CSE Technical Report CSE TR-02-99 Prof. Steven A. Demurjian Dept. of Computer Science & Engineering The University of Connecticut Storrs, CT 06269-3155 Abstract Enterprise computing (EC) is the recognition that to effectively utilize and disseminate information within an entity (university, corporation, government agency, etc.) it will be necessary to design and develop integrated distributed computing environments that allow all types of existing and future systems to interoperate. In EC, there are legacy, COTS, database, and new client/server applications that all must interact to facilitate both peace and war time communications among personnel at various locations. To allow these different applications and systems to interoperate, a number of approaches can be applied that translate to a common framework. Possibilities for such a common framework could range from very low level (e.g., assembly) to low level (e.g., C/C++ and RPC) with existing technologies. When emerging technologies are considered, one can choose among new object-oriented programming technologies (e.g., Java and its Enterprise Computing API), database systems (e.g., Jasmine), or distributed object computing paradigms (e.g., CORBA, DCE, DCOM/OLE, etc.). This paper explores software architectural alternatives for integrating the clients, servers, legacy/COTS, and databases that comprise EC applications. The emphasis of the work is to report on our practical experiences in upgrading a C++ legacy application to be Java compatible. Table of Contents 1. Introduction 2. Architectural Alternatives 3. Integrating a C++ Legacy Application with Java 3.1 The ADAM Software Architecture 3.2 Client Requirements and Functionality 3.3 Wrapper Requirements and Functionality 3.4 Communication Requirements and Functionality 3.5 TwinPeaks Requirements and Functionality 3.6 Incorporation of CORBA 4. Assessing the Impact and Importance to EC 5. Concluding Remarks and Future Work 1 1. Introduction Distributed computing environments for the 21st century will require designers and developers to architect solutions that facilitate the interoperation of new and existing applications. In ECA, a system of systems must be constructed, consisting of legacy, COTS, database, and new client/server applications that must interact to communicate and exchange information between users in peace and war-time settings. However, there is a larger purpose to solving the enterprise computing problems of integrated applications. The issue is not simply to provide a means to allow different systems to interact and exchange information, but rather to promote the use of existing applications in new and innovative ways in a distributed environment. In the enterprise computing environment, an existing legacy/COTS application can be extended in a variety of ways, including: an expansion with multi-user capabilities; the incorporation of a new graphical user interface (GUI) that employs modern tools; or, the addition of new functionality that adds value and increases capabilities. To address enterprise computing problems and solutions for applications, the field of software architectures can be utilized. Software architectures [Shaw96] expands traditional software engineering by looking at how different major system components can mesh and interact. ECA, as a system of systems, is particularly suited to an architectural approach, to clearly and definitively specify the interactions between the legacy, COTS, databases, clients, and servers. Software architectures is an emerging discipline whose intent is to force software engineers to step back from their traditional algorithm/data structure perspective and view software as a collection of interacting components. Interactions occur both locally (within each component) and globally (between components). In understanding interactions, the key consideration is to identify the communication and synchronization requirements which will allow the functionality of the system to be precisely captured. By taking a broader view of the problem definition process, software architectures permits database needs, performance/scaling issues, and security requirements, to be considered, all of which are critical for ECA. Enterprise computing solutions using software architectures are varied, and are often dependent on application domain. In some applications, like a university, a software architectural solution that advocates a common framework might suffice. For example, unifying all of the systems at a university that involve scheduling, registration, transcripts, accounts, purchasing, etc., with new Web-based tools for faculty and students may be feasible with a Java-wrapper solution. In such a solution, existing systems are wrapped with Java to achieve a common framework (via RMI, object-serialization, or CORBA) for interacting with new Java tools. In a university setting, performance demands, life/death issues, or profit/loss considerations are not as pervasive when integrating new and existing systems. In other applications, performance, reliability, life/death issues, etc., are all critical, and may require the examination of wrapper-based and other solutions to achieve integration and interoperation. The purpose of this paper is to explore software architectural alternatives for ECA that can be utilized to guide the integration the clients, servers, legacy, COTS, and databases 2 into a system of systems. To do so, the remainder of this paper is organized into four sections. In Section 2, we review different architectural alteratives that can be utilized to integrate legacy/COTS applications with new clients/servers, which is a synopsis from our prior paper [Demu97M]. In Section 3, we explore the process of integrating a C++ legacy application with Java, by detailing our experiences and approach in constructing a new Java client that interacts with a Java wrapped C++ legacy server. The work in Section 3 involves the utilization of Java as a common framework through which a C++ legacy server can interact with new Java clients. In Section 4, we step back from the experiences of Section 3, to assess the impact and importance. Through the discussion of Section 4, we are able to generalize the practical experiences of the case study of Section 3 into a blueprint that can be followed by software engineers that need to undertake the process for their applications. Finally, in Section 5, we conclude this paper. 2. Architectural Alternatives There are several architectural alternatives for integrating legacy/COTS applications with today’s applications [Moor97, Mori97, OBJMAG96, Robe97, Thra97], as we reported in our earlier paper [Demu97M]. In this section, we briefly review this earlier effort to motivate and set the context for the remainder of the paper. There are many possible ways to integrate legacy/COTS applications with modern technologies, including: the data-transformation approach that relies on commercial database management system technology as a means for data exchange between a Java client and a legacy/COTS application; the ORB approach that utilizes DOC and CORBA ideas and introduces the concept of a wrapper to integrate the legacy/COTS application to an ORB that is then accessible via Java clients; the Java-client wrapper approach that avoids ORB/CORBA by integrating the Java-client with a wrapper that maps down to the native OS/network level, which is then accessible to the legacy/COTS application; and, an approach that illustrates the way that two or more legacy/COTS applications can be integrated to multiple-java clients. In all of these approaches, the legacy/COTS application is evolving to a state where it can function as a server to one or more clients. Note that to simplify the discussion, whenever the term legacy appears, the reader can interpret that to mean legacy/COTS. The data-transformation approach, outlined in [Robe97], is a data-centered solution that is appropriate for legacy applications that generate data. The data-transformation approach is illustrated in Figure 1 for a Java client. 3 Transformed Legacy Data Java Client Updated Data Relational Database System(RDS) Extract and Generate Data Transform and Store Data Legacy Application Figure 1. Java Client to Legacy Application via RDBS. In Figure 1, the process takes a number of steps. First, data is extracted from the legacy application and stored into a relational database system (RDBS), where it is now accessible to a Java client. Then, if the legacy application is dynamic (generates data), at periodic (or continuous, if needed) intervals, the data must be extracted and restored into the RDBS. Once in the RDBS, the data is accessible to the Java client, in both a read and write mode. Finally, if the Java client can generate or update the data from the legacy application, the dashed arrows are relevant, indicating the flow of information via the RDBS back into the legacy application. In such a process, two sets of bi-directional transformations (mappings) of data are necessary: Java client to/from RDBS to/from legacy application. When the Java client can write or update legacy data, concurrency and serializability become major problems, with software needed within the Java client and/or the RDBS. Multiple Java clients may or may not be concurrently supportable, depending on whether a client can write data, and if the legacy application can support simultaneous access. Object-request brokers and CORBA technologies can be utilized to integrate a legacy application with a Java client. The ORB approach, reported in [Thra97], utilizes the wrapper concept to facilitate the integration. A wrapper is a piece of software that functions as an interface or filter between two distinct software components that must interact. In Figure 2, the ORB approach is reproduced from [Thra97], with a wrapper utilized to facilitate the integration. 4 Legacy Application Java Client Java Wrapper Object Request Broker (ORB) CORBA is the Medium of Information Exchange Requires Java/CORBA Capabilities Figure 2. ORB Integration of Java Client and Legacy Application. In this case, the wrapper is coded using an IDL-to-PL compiler, where PL is the programming language of the legacy application. While the IDL-to-PL compiler will map to the legacy application at the data/object level, the software engineer must still provide the needed logic and control flow that promotes the exchange of information via the wrapper according to the programming interface of the legacy application. Using this approach, concurrent Java clients are possible, providing that the concept is supportable by the legacy application. If the legacy application needs to interface to two or more clients written in different (object-oriented) programming languages, then it will be necessary to design and develop multiple, dedicated wrappers. An alternative to the ORB approach, the Java-client wrapper approach, takes advantage of the Java Native Interface (JNI) and remote procedure calls (RPC), which has also been outlined in [Thra97]. The approach, shown in Figure 3, integrates the wrapper with the Java client across a network with a number of components. 5 Java Client Java Application Code WRAPPER Mapping Classes JAVA LAYER Interactions Between Java Client and Legacy Appl. via C and RPC C is the Medium of Info. Exchange Java Client with C++/C Wrapper NATIVE LAYER Native Functions (C++) RPC Client Stubs (C) Legacy Application Network Figure 3. Java Client with Wrapper to Legacy Application. The application code component written in Java realizes the new functionality of the client, which in turn must interact with the legacy application to get/store data and/or trigger operations. The wrapper component consists of a Java layer and the native layer. The Java layer maps from the platform-independent application code to the programming language interactions of the native layer in two stages. In the first stage, the native layer promotes interactions back and forth with the Java layer using a C++ interface which provides a compatible object-oriented context for the exchange. In the second stage of the native layer, there is a mapping from C++ to/from RPC client stubs written in C, which interact across the network to the legacy application. In this approach, it is assumed that the legacy application can interact via RPC over a network to permit the needed interactions with the Java application. Multiple Java clients may be possible, though this may be complicated and difficult to achieve if the clients need to synchronize actions and share data. Note that the mapping to the native layer is platform specific, requiring multiple implementations for Java clients on different hardware/OS platforms. Finally, in Figure 4, an example is provided that integrates one COTS application and an in-house legacy application, all of which are now accessible by one or more Java clients. In Figure 4, Java Network Wrappers are shown, whose purpose are to provide a mapping from the COTS/legacy application to Java application code. The sole purpose of the Java application code is to provide the means for COTS/legacy data to be Java-available over the network (Internet and/or intranet). Individually, a consistent Java interface to the COTS/legacy applications is now available for all of the Java clients that require access to one of the applications. If a Java client needs access to multiple COTS/legacy 6 applications in a simultaneous fashion, it is necessary to provide a substantial software component within the client to handle the required collection and synchronization requirements. COTS Application Legacy Application Java Application Code Java Application Code Native Functions that Map to COTS Appl Native Functions that Map to Legacy Appl NATIVE LAYER NATIVE LAYER JAVA LAYER Mapping Classes JAVA LAYER Mapping Classes JAVA NETWORK WRAPPER JAVA NETWORK WRAPPER Network Java Client Java Client Figure 4. One COTS and One Legacy Application to Java Clients. 3. Integrating a C++ Legacy Application with Java This section reports on our case study/prototyping efforts in moving an objectoriented/C++ legacy application to be Java compatible. The C++ application that serves as the basis for the case study is the ADAM (short for Active Design and Analyses Modeling) environment that supports object-oriented design. ADAM, as shown in Figure 5, contains an object-oriented design model that is tightly integrated into the environment, with the semantic, scope, content, and context of each modeling construct clearly defined. There is no specific syntax for the design model; choices are made via menus, browsers, etc., and text is directly entered by the designer using forms. Thus, the environment stresses programming language independence by focusing on design and allowing code to be generated in a variety of target languages (Ada83, Ada95, C++, Ontos C++, Eiffel) for supporting a transition to the implementation effort. ADAM supports incremental design by allowing design data to be stored persistently in the Ontos database system. 7 Figure 5. The ADAM Environment: A User Perspective. Multiple versions of ADAM have been designed/implemented or are in the planning stages. The original version of ADAM was implemented on a Sun architecture under a Unix environment using X windows, InterViews 3.01, AT&T C++ 2.0, and Ontos (ADAM-Unix). In the last two years, a PC/Windows 3.1 version using Borland 4.02 C++ has been prototyped (ADAM-PC). Future versions will include ADAM-NT, and of course, the client/server upgrade (ADAM-CS) that is the basis for the case study presented herein. The interested reader is referred to the published literature for further information on the object-oriented design model and ADAM [Elli93, Need96] and its user-role based security capabilities [Demu94a, Demu95a, Demu95b, Demu96b, Demu97a, Demu98a, Hu93a]. The purpose of this case study is to treat ADAM as a C++ legacy application that is to be upgraded and restructured to be Java compatible. In the process, ADAM will be changed from a single-user mode application to the client/server paradigm. A new Java client will be designed for ADAM that will interact with the C++ legacy application. To facilitate this interaction, a Java wrapper will be constructed to encapsulate the ADAM C++ legacy code as a server. Our experiments with ADAM-CS are extremely relevant for EC. ECA will be realized as a system of systems, and will require the integration of existing and new applications into a cohesive, interacting solution. Both object-oriented and procedural legacy/COTS applications must interoperate for the successful ECA. The underlying ideas and concepts of our efforts on ADAM-CS are applicable to C++ in particular, and object-oriented systems, in general, with the potential for exploiting select aspects of our solution approach to procedural legacy/COTS applications. 8 The remainder of this section begins by reviewing the current ADAM software architecture and its components in Section 3.1. Then, this section continues by examining/defining the requirements and functionality for the new Java client in Section 3.2, the Java-to-ADAM legacy wrapper in Section 3.3, and the communications between the client and the server in Section 3.4. This presentation is followed in Section 3.5 by a detailed study of the utilization of the TwinPeaks [Twin98] software package, which generates a Java interface for a C or C++ native library. TwinPeaks is one solution alternative for the construction of the Java-to-ADAM legacy wrapper of ADAM-CS. We conclude the section by considering the potential impact of CORBA on this integration process in Section 3.6. 3.1 The ADAM Software Architecture ADAM is a monolithic, single-user environment, which can be treated as a C++ legacy application that contains four major interacting components, as shown in Figure 6: 1. the ADAM graphical user interface component, which is compiler dependent, developed using Interviews and Unidraw on Unix, and Borland C++/OWL on Windows 95; 2. the design/generation component, which is compiler independent, and contains the C++ design classes that are used to store an active ADAM design and the code generation algorithms that translate an ADAM design to C++, Ada95, etc.; 3. the database server component that provides a abstraction layer between the object-oriented design instances and the Ontos OODBS, allowing designs to be persistently stored; and, 4. the Ontos commercial OODBS. From an interaction perspective, software engineers can begin by creating a new design in ADAM or by loading an existing design. As a new design is created (or an existing design is modified), the object-oriented design information from the software engineer is captured by the GUI, and then passed on to be represented and stored as a set of C++ instances in the design/generation component, while a given design is active. When a design is loaded (stored) to Ontos, the request is initiated by the GUI and carried out by the database server component, which interacts in turn with both the GUI and the design/generation components to access (save) a ADAM design to Ontos. At any point during the design process, the software engineer can request that code be generated in one or more programming languages, which uses the design/generation component to create the desired object-oriented code. 9 Figure 6. The ADAM Environment: Current Software Architecture. Given the architecture in Figure 6, our goal is to restructure, redesign, and reformulate ADAM’s software architecture from the monolithic case to a client/server paradigm that is Java compatible. The current ADAM GUI component will be replaced by a new Java client (to be discussed in Section 3.2). The design/generation and database server components will be grouped as a server (to be discussed in Section 3.3) that is wrapped by Java using the TwinPeaks package from SunSoft (to be discussed in Section 3.5). The Ontos OODBS component will be disabled, to allow for its long-range replacement with the Jasmine [CAI] OODBS in 1998, which is beyond the scope of this paper. By transitioning to a Java-compatible environment for the client and server, all of the communications can occur using appropriate Java API primitives (to be discussed in Section 3.4). To accomplish all of the above tasks, one must understand the underlying composition of the ADAM components. Basically, the ADAM software is composed of a significant C++ class library that was intended for single-CPU, single-user access. The C++ classes of ADAM are structured as multiple, interacting hierarchies that are utilized across the various components. Essentially, there are four groupings of C++ classes: for the GUI; for storing and manipulating the design as it is being created; for controlling the code generation for the different programming languages; and, for interfacing with the Ontos OODBS. It is likely that some of the legacy/COTS applications that will comprise ABCS/FD have similar class grouping. Specifically, it is often typical that there is a differentiation between the classes needed for the GUI to receive/display information 10 from/to the user and the classes required to store the entered information independent of the GUI for manipulation by the functional components of the legacy application. The other software characteristic of ADAM is that we have all of the source code available. While this may occur for some EC legacy/COTS applications, for other applications, an object-oriented class based programming interface may only be available. In order for this work to apply to both kinds of legacy applications (source code vs. programming interface), one of our goals will be to minimize the code-level modifications as ADAMCS is created. 3.2 Client Requirements and Functionality Figure 7 contains a high-level conceptualization of ADAM-CS, separating the client functionality (GUI) from the server capabilities (Java wrapper plus ADAM C++ legacy code). The new ADAM-CS Java GUI client is based on the GUI of both ADAM-Unix and ADAM-PC, but has been redesigned and restructured to take advantage of the more modern GUI tools offered by Java. In the process, capabilities not included in earlier versions of ADAM (e.g., the ability to modify and change object-oriented design components) have been included in ADAM-CS. In the general case of upgrading a C++ legacy application of an EC component to Java compatibility, a non-sophisticated or rudimentary user interface may be modernized when a new Java client is created. This is one advantage to upgrading a legacy application, namely, the ability to offer tools with more typical look-and-feel than older technologies, thereby adding value. Figure 7. The Software Architecture of ADAM-CS. The new Java GUI client of ADAM-CS will also require other capabilities to support the interactions of users. Specifically, the new client will need to redesign and reimplement select C++ legacy server classes in Java, to support the transitory storage of designs. 11 Thus, two of the categories of Java classes that exist in the client are GUI-related classes and design classes. The GUI-related classes are utilized for the different components (e.g., windows, dialog boxes, message boxes, etc.) of the GUI while they are being manipulated by the user, while the design classes are a holding area for the objectoriented design information after it has been supplied by the user via the GUI. There are a number of reasons why the design classes are need in the new Java GUI client. First, a user may request an existing design from the server to be displayed and manipulated at the client. By storing new or existing designs at the client for local manipulation the communications traffic is reduced. Second, local updates are maintained at the client until the design is ready to be persistently stored at the server. While this also reduces communication, it also introduces the potential for inconsistent versions if multiple users (clients) are sharing the same design. Overall, the new Java GUI would be a mediumsized client, as opposed to thin (with minimal functionality, say only GUI) or thick (with all functionality and a smaller server). Interactions between the Java GUI client and legacy server can occur in many different ways in Java. For the purposes of this current study, we utilized the Java communication techniques of object-serialization via sockets. Object serialization in Java is the conversion of an object into a string or some other data format that facilitates its storage to disk or its transfers across a network. The conversion back to an object from a serialized format is known as deserialization. Through object serialization, the Java GUI client can easily exchange information with the Java/TwinPeaks wrapper, which in turn will convert and pass that information to the ADAM C++ code, as shown in Figure 8. Figure 8. Object-Serialization in ADAM-CS. 12 Specifically, object serialization allows object-oriented designs to be shipped back and forth between the client and server. Our efforts have focused on storing a new design from the Java GUI client to the server. This occurs on-demand by the user, or when the user finishes his/her session with the Java GUI client. Note that issues relating to consistency and most-up-to-date copy of an object-oriented design being manipulated by a user at the Java GUI client have not been considered as part of this work, since we have focused on the client/server split and Java wrapper concepts. However, in a real-world situation, this issue may require frequent and automatic updates to insure that the information in the legacy application is always up-to-date. 3.3 Wrapper Requirements and Functionality In the general sense, a wrapper is utilized to upgrade a given application to a different context, which will allow an application written in one programming language to interact with an application written in another programming language. Wrappers are extremely popular today, especially for individuals that are seeking to support the integration of new Java client applications with existing legacy applications. Figure 9 contains a conceptualization of the components of a client, wrapper, and server, as it applies to the ADAM-CS environment. Figure 9. Client, Wrapper, and Server Components of ADAM-CS. 13 In Figure 9, the Java client consists of four layers of components: 1. the GUI classes/instances to allow for interactions between a user and the GUI; 2. the Java design classes/instances for the local storage of an object-oriented design at the client as discussed in Section 3.2; 3. the Java communication classes/instances for transitioning the Java design classes/instances to an appropriate format so that they can be transmitted over the network; and, 4. the communication layer to facilitate the exchange of information between the client and wrapper (which also implies the server). Note that the Java communication classes/instances component may not be needed, depending on the protocol utilized to transmit and receive information. Figure 9 also contains a component based view of the wrapper. Notice that the first three components (communication, Java communication classes/instances, and Java design classes/instances) are the same as in the client. The fourth component handles the translation from Java to/from C++. Overall, the Java wrapper for the ADAM C++ legacy code is fundamentally in charge of the transmission and receipt of messages from the clients, as shown in Figure 10. There are two main messages that are processed by the Java wrapper. The first message requests that an existing design be sent from the server to the client. In this case, the Java wrapper must locate the C++ instances in the ADAM C++ server, create Java design instances, which are then transmitted via object serialization to the client. The second message requests that an object-oriented design of the client be stored into the server, which involves similar actions to the first message in the reverse order. Interactions between the wrapper and C++ legacy code can occur using either the Java Native Interface (JNI), or as we discuss in Section 3.5, the TwinPeaks package. The client, wrapper, and server presented in Figures 9 and 10, while specific to ADAMCS, can also be applied to a general C or C++ legacy application that would be part of an ECA. Notice that in both Figures 9 and 10, the only ADAM specific notation refers to either the ADAM C++ server or ADAM classes and instances. In fact, the different components in Figures 9 and 10 are the ones that are most likely to occur as one attempts to transition from a legacy application to a Java compatible framework. Classes for the GUI, classes to buffer information from either the GUI or the server, and communication classes, as shown in Figure 9, are all likely to occur as part of a new Java client for a legacy/COTS application. Whether all of them will occur depends on the thinness or thickness of the client. Similarly, classes and algorithms to support the bidirectional transformation of Java to/from C++ are also likely to be required; however, if the Java client is a read-only browser, then only a C++-to-Java transformation would be needed. 14 Figure 10. The Java to C++ Wrapper in ADAM-CS. 3.4 Communications Requirements and Functionality The communication requirements and functionality are strongly related to the new Java GUI client and wrapper, which was shown in Figure 9. Specifically, the communications is usually involved with the information that is needed by both the client and the wrapper. In the case of Figure 9, the Java design classes and the Java communication classes are the means through which information is exchanged. In addition, to actually manage the sending and receiving of messages, a communication layer is needed in both the client and the wrapper. In ADAM-CS, the communication layer has been implemented using sockets and object serialization in Java. Sockets are used in TCP/IP networks as a link between two or more processes to support the exchange of information and messages for distributed applications. Using socket APIs, a C++ or Java client can open a basic byte-stream connection to another C++ or Java process. Both sides can read and write to this byte stream, responding as necessary as new information is sent through the connection. Basic sockets in Java or C++ have substantial overhead, requiring the software engineer to provide capabilities such as naming service, error handing, and failure detection. Also, since socket data is an unstructured byte stream, each application must design its own communication protocol between server and client, this protocol must be generated and parsed, and failures must be handled gracefully to avoid large-scale application crashes. Java sockets for communicating between two or more Java processes have some substantial improvements over the basic socket concept, namely, support for error handling via exceptions and the communication of complex structures via object serialization (see Section 3.2 again). 15 Using sockets and object serialization from Java, the transmission of design objects between the new Java GUI client and wrapper is seamlessly supported. The java.net package provides classes that implement the client and server sides of the socket connection. To communicate, the client and the server each reads from and writes to the socket bound to the connection. The server application will listen to a specific port waiting for connection requests from a client. In order to make a request, the client needs to know the precise host where the server is running and the port number where the request should be sent. When a request arrives, the client is assigned a local port number, and it assigns its socket to it; the server and the client then establish a dedicated connection over which to communicate. The messages that are sent between the client and wrapper in ADAM-CS are quite complex. An instance of an object-oriented design that has been created by a user via the new Java GUI client contains complex, interrelated, and recursive data. The object-oriented design consists of different classes, methods and attributes defined on classes, inheritance among classes, relationships and aggregations between classes, and so on. Object serialization in Java allows these instances to be flattened so that they may easily be sent through a stream (e.g., a file or socket). Once the socket connection has been initialized and established for the client and server, the exchange of an object-oriented design between the client and the server, occurs with three or four lines of code via object serialization. While ADAM-CS has been designed and implemented using sockets and objectserialization, since this has been encapsulated into a communication layer (see Figure 9 again), it is also possible to explore other alternatives for supporting interactions between the client and server. One such alternative is remote method invocation (RMI), which is a distributed technology that extends the pure Java object model over the network. RMI enables objects in one Java Virtual Machine (JVM) to seamlessly invoke methods on objects in a remote JVM. RMI supports traditional distribution models, such as client/server and peer-to-peer, and enriches these models with new kinds of agent-based distributed applications. Another alternative for client/server interaction is CORBA, which we will consider in Section 3.6. Both RMI and CORBA can be explored as future work in examining the benefits and disadvantages to the technologies that are available to support the upgrade of a legacy/COTS application to Java compatibility. 3.5 TwinPeaks Requirements and Functionality The last remaining issue in designing/implementing ADAM-CS involves the interactions of the various components of the wrapper/server. As shown in Figure 10, there must be some way to allow interactions between Java and C++ to occur. One approach to this interaction is via the Java Native Interface, JNI. By using JNI, it is possible to have your Java applications directly call a program written in another language (like C or C++), or to alternatively, allow an application written in another language to call a Java application. JNI is essentially a trap-door that allows sophisticated software engineers to circumvent the platform independence of Java. JNI can be utilized to facilitate the integration of a Java wrapper with a legacy/COTS application (see Figures 3 and 4 in Section 2). However, as outlined in [DiGi97], JNI has a number of problems, since it: introduces platform dependence, may open the potential for a security breach, and most 16 importantly, requires significant programming skill for correct and consistent usage. As part of our initial efforts on ADAM-CS, we examined and evaluated JNI. Our conclusion was that JNI is difficult to both understand and effectively utilize. In fact, in searching for other alternatives to provide the Java-to-C++ bridge, we found that SunSoft was promoting another product, namely TwinPeaks [Twin98]. TwinPeaks is a beta product that has been designed to automatically generate a Java interface to a C or C++ native library. As shown in Figure 11, TwinPeaks works by analyzing the native library header files from which a Java API is produced that closely mirrors the original C/C++. TwinPeaks is currently constructed on top of the Java native method API, which was originally shipped with JDK 1.0. All versions of the JDK since 1.0 have been shipped with the JNI as a replacement to the Java native method API. For our efforts as reported in this paper, we critique the utility and effectiveness of TwinPeaks. Figure 11. The TwinPeaks Architecture and Processing. Our efforts with utilizing TwinPeaks have gone through a number of phases over the past four months. Since TwinPeaks is a beta product, our first attempts to establish the environment required us to download TwinPeaks on multiple occasions, and install the software multiple times. Once we had a working version of TwinPeaks, we focused on understanding the mechanism, the test cases, and the proper steps necessary to utilize the environment. UConn, as a beta testing site for TwinPeaks, provided many suggestions and feedback to SunSoft. Many of the suggestions for improvement are reflected in the second release of TwinPeaks which became available in mid-November 1997. As of January 15, 1998, the most up-to-date version of TwinPeaks is installed, and we have developed two test programs that generate the Java-to-C++ mapping for a subset of 17 the ADAM C++ server legacy code. While this has demonstrated to us that TwinPeaks can be a pivotal tool for integrating and upgrading a legacy application to Java compatibility, we have also encountered a number of problems that highlight the need for caution on this beta-product. Consequently, we discuss the pros and cons of TwinPeaks at the end of this section. Note that we have not fully generated a Java API for the ADAM C++ legacy code. This has been due to a number of factors. First, the newness and instability of TwinPeaks, requiring us to download multiple times and reload a new version in November, slowed down our efforts with learning and using TwinPeaks. Second, the ADAM C++ legacy code, while it does contain a set of C++ header files, was not designed and implemented as a clean and usable object-oriented class library. That is, ADAM was not developed as an object-oriented class library upon which GUI and code generation capabilities were added. The nature of ADAM's prototyping (10 graduate and undergraduate students over the last 6 years) has resulted in an evolutionary piece of software, that in many portions of its class structure is severely lacking in adequate object-oriented design techniques and principles. Thus, due to the nonprofessional nature of the ADAM C++ legacy code, the lack of a clean C++ API made it difficult to generate a Java API for the entire C++ legacy code. Note that an independent study project with a graduate student is ongoing during the Spring 1998 semester to continue this work. In the course of our efforts with TwinPeaks over the past four months, we have reached a number of conclusions regarding the advantages and drawbacks of the package. On the plus side, the biggest advantage to TwinPeaks is that, to our knowledge, it is the only available tool that supports Java to C/C++ at a high-level of abstraction. Second, the automated nature of TwinPeaks clearly is targeted for minimizing the tedious and error prone process of generating Java classes for C++ code. Third, TwinPeaks offers clever techniques to solve semantic mismatch problems between Java and C/C++, most notably when dealing with C/C++ libraries that contain pointers, multiple inheritance, and operator overloading. A final advantage, at least for now, is the fact that TwinPeaks is available at no cost. The first three advantages are critical for ECA, since there is the potential for a large number of C/C++ legacy/COTS that must interoperate in the system of systems solution. Tools like TwinPeaks that automate the integration process are critical to reduce manpower and effort as the transition to ECA is planned and undertaken. Unfortunately, at the present, time the drawbacks of TwinPeaks are much more numerous. First and foremost is that TwinPeaks is only available for Solaris platforms and requires the SunSoft C++ compiler. This means that Java-to-C++ interactions on Windows 95 or NT will require the use of JNI. Also, if the C++ legacy application was not built with SunSoft C++, there may be problems in compilation, since it is clearly the case that not all C++ compilers are created equally. A second problem is that TwinPeaks is based on the older Java native method API and not the JNI. Later releases of Java (JDK and JRE) have not always been compatible with earlier ones, e.g., the need to remove deprecated calls when using JDK 1.1.4 or JDK 1.1.5 on code developed using JDK 1.1.3 or earlier. Clearly, there is the potential for abandonment of the Java native method API in JDK 1.2 or later versions; hopefully, TwinPeaks will transition seamlessly 18 if that occurs. Third, the amount of support, user community, and documentation is very minimal. When we encountered problems early on and sent email to different individuals at Sun, at times we had conflicting responses to the the same questions. At one point, we found it easier to remove and reinstall TwinPeaks rather than attempt to fix problems related to Unix sets and paths. From a C/C++ programming language perspective, the early access release of TwinPeaks [Twin98] does have a number of significant limitations including: Lack of support for generics (templates) and unions, both of which are unavailable in the Java API generated from C/C++ library. Intertwined exception handling which would allow the interchangeable processing of C++ and/or Java exceptions is not supported. Ignoring of C/C++ libraries that contain: anonymous classes, functions with varargs, pointers to functions not defined by typedef, protected embedded classes, and pointer to member types. Again, unless the Java language changes, support for interfacing a Java API with a C++ template or a C union is not likely to occur. Overall, while TwinPeaks is automatic, it can be difficult to use, and requires the software engineer to be familiar with both SunSoft C++ and the Java native method API. At times, there are too many warnings that do not make sense, and the lack of adequate debugging facilities makes both understanding and correcting errors a difficult process. A final drawback is that TwinPeaks is one way, allowing Java-to-C++ calls, but not permitting the invocation of Java from a C++ program. Our conclusion at this time is that TwinPeaks is a tool that is continuing to evolve, and in our opinion, has not reached a stable state. Moreover, it definitely fell short of our expectations, i.e., the attractiveness of having a tool to generate Java to C++ interactions automatically rather than having to perform tedious and difficult work with JNI was not proven to our satisfaction. In retrospect, it may have been better to have chosen JNI when seeking to integrate Java and C++. The TwinPeaks product will need to be tracked to see if, in the future, it has better and easier to use capabilities. At this point in time, the numerous drawbacks to TwinPeaks strongly suggest that its acceptance and adoption for ECA is premature. 3.6 Incorporation of CORBA Common Object Request Broker Architecture (CORBA) is an industry standard for application level communication for distributed systems. CORBA is a high-level sophisticated set of services including an interface description language (IDL) for describing software components independently of their implementation language, a middleware communications protocol (the Internet Inter-ORB Protocol, or IIOP), and a functional description of the way that an object request broker (ORB) should interact 19 with clients. CORBA is today the only widely accepted standard for doing languageindependent distributed computing. The IDL component of CORBA is a technology independent syntax for describing object encapsulation boundaries. Its specifications can be compiled into header files, stubs and skeleton programs for direct use by developers. These IDL specifications can be potentially mapped to several different programming languages. The mapping relates to the way that an object invokes an IDL-defined object and the way that an object implementor should implement and IDL-defined object in a given implementation language. Several vendors have already developed compilers for C, C++, Smalltalk, Ada95 and Java. The other main component of CORBA is the ORB, that is the application level communication infrastructure. It aids in the development of objects and arranges for objects to access each other at run-time. There are two types of interfaces, static invocation interfaces (SII) and dynamic invocation interfaces (DII), which are stored in an interface repository (IR) for the ORB to be able to find the appropriate object when required. A full CORBA-solution requires developers to describe networked software components using the CORBA IDL. The IDL description is then compiled into server-side and clientside stub code; the server developer must implement the server stub code while the client developer calls the client-side stub code, thus, using the software component transparently. In addition, there is a server-side and a client-side runtime library that provides APIs for setting up connections and handling various events, including communication failures. CORBA is language-independent since IDL compilers and runtime libraries can be written for a variety of languages. Because CORBA relies on a standard communication protocol (IIOP), objects and methods can, in theory, be shared between clients and servers even if they are written in different languages using different CORBA implementations. CORBA can be utilized without Java to support the integration of legacy/COTS into a consistent framework, where each legacy/COTS application will be wrapped to allow the interaction with an ORB. Since IDL compilers for C, C++, Ada95, and Java are available, it will be possible to wrap legacy/COTS application written in these languages to the CORBA framework. Such an approach is analogous to the one given in Figure 2 for Java (see Section 2 again). CORBA/ORBs with Java, would utilize the Enterprise API of Java [JAPI] to exploit the packages/classes for the Java IDL and JDBC (Java database connectivity). Such an approach, as conceptualized in Figure 12, would either introduce an additional layer of translation or replace an existing layer. 20 Figure 12. ADAM-CS Architecture: Java, CORBA, ORB. For example, as noted in Section 3.3, the Java communication classes/instances, may not be needed in the sockets/object-serialization version of ADAM-CS. For an ADAM-CS using CORBA, this component layer may be replaced with the mapping from the Java design classes/instances to IDL. The Java wrapper as shown in Figure 11 may retain a similar structure to the non-CORBA case, or since CORBA is the medium of commonality, it may be simplified to a component that maps to/from IDL directly to the C++ legacy code. Thus, there is the potential to simplify the server side in some situations, reducing the multiple layers of components. The key potential drawbacks in any of the approaches described for ADAM-CS throughout Section 3 is two-fold and related to the multiple layers of components in Figure 11: performance slowdowns due to the transformations/translations that occur as information is passed between client and server, and the potential data inconsistency if semantic information is lost as a result of the transformations/translations. These two drawbacks are critical for evaluating CORBA as a potential solution alternative for ECA. 4. Assessing the Impact and Importance to EC In this section, we assess the impact and importance of the work presented in Section 3 of this paper to EC. One of the major roadblocks will be to solve the enterprise computing problem to allow legacy/COTS applications and new applications to all interact with one another in the heterogeneous, distributed, computing environment. The integration achieved in the system of systems will hopefully result in new and innovative ways to view, disseminate, and share information. The work undertaken on ADAM-CS, to upgrade a C++ legacy application to the client/server paradigm with a new Java client 21 interacting with a Java-wrapped C++ server, is directly relevant to EC. That is since ECA will also likely require the design, implementation, and integration of new Java clients that must interact with not just one legacy C++ application, but perhaps, multiple legacy/COTS applications written with both procedural and object-oriented programming languages. The work presented in Section 3 can be summarized and aggregated as a blueprint for transitioning general C++ (and C) legacy/COTS applications to Java compatibility. While ADAM as presented in Section 3 appears to be a very specific application, it is possible to step back and abstract, thereby identifying the general features and characteristics of ADAM as a C++ legacy application. In particular, to upgrade a C++ legacy application to a client/server architectural solution using Java, in support of an ECA, a software engineer or designer should consider the following: The ability to pull-off or disable the legacy GUI. If this is not possible, perhaps one can circumvent the GUI of the legacy application by directly interacting with its object-oriented class library interface. This is needed to allow the C++ legacy server to be wrapped by Java for supporting Java-to-Java interactions with clients. In constructing ADAM-CS, we were able to disable the GUI at the C++ legacy server side, which in turn, facilitated our work with TwinPeaks. This may not be possible for every legacy application of an ECA. Source-code availability or a robust programming interface. Related to the prior point, to facilitate the conversion to client/server, either source code must be available for modification or a robust object-oriented class library (API) must be present. In constructing ADAM-CS, we had the source code available, which directly supported the work in constructing the Java-to-C++ wrapper using TwinPeaks. It is important to note that the legacy applications of ECA may contain neither source code nor a robust programming interface, which may severely hinder the process to upgrade the legacy application. Development of a new Java GUI client. The new Java GUI client replicates and perhaps enhances the original legacy GUI. The legacy GUI may be terminal oriented, without graphics, and as such, the new Java GUI at the client will offer more typical and modern look-and-feel. There may also be functional enchancements to offer a capability at the new Java client that was not present in the original legacy GUI. Specifically, a new java GUI client may collect, synthesize, and interpret information from multiple legacy/COTS applications, thereby providing a innovative capability as a direct result of the distributed computing environment. To construct the new Java client GUI for ADAM-CS, we relied on the look-and-feel of ADAM-PC, but we also took liberty to enchance the user-friendliness features. As technologies continue to change, ECA will need to have the most up-to-date GUIs. Short-term persistence of client data. The new Java GUI client may require the creation of Java-based classes for storing data locally at the client. This is needed 22 for both receiving information from the C++ legacy server and for forwarding information to the legacy C++ server. For ADAM-CS, we provided a set of Java design classes for storing an object-oriented design at the client. These Java design classes are also instrumental on the server side for the exchange of information to/from the client, and the interactions with the C++ legacy code. ADAM-CS was a medium-sized client. If thin clients were desired, then short term persistence of large volumes of client information would not be necessary. Short term persistence of client data may be very critical for some ECA, particularly for those clients that are constantly entering and leaving the dynamic network or have limited bandwidth for communications. In this case, having data locally will be required if the network link is intentionally or inadvertently broken. Message-passing interface to legacy application. If a message-based approach is used in a client/server solution to exchange information, then a message-passing interface for the legacy application may be required. Certainly, if the messagepassing interface is present in the legacy application, it can facilitate the exchange of information between the Java wrapper and the C++ legacy server. If it is not present, it may be possible to have the communications layer of the Java wrapper handle the message passing between the client and from the wrapper to the server. This is the approach we have taken in ADAM-CS. Note that if RMI or CORBA is utilized, allowing direct method calls from the client against server objects (and vice-versa), then a message-passing interface may not be needed. Again, for some EC legacy applications, a message interface may not be present, or may occur at such a low level (byte streams) that extra processing (e.g., transformations) is required. Extra layers of data translation come with a high cost, potentially resulting in inconsistency. Integration of Java and C++. The Java wrapper and C++ legacy server must interact to allow calls and information to flow between both components. Using TwinPeaks, such an interaction requires the ability to encompass and build the C++ legacy server code as a shared library. The interaction can only occur from Java-to-C++ using TwinPeaks. Using JNI, direct calls between Java and C++ can be made, in either direction, to facilitate the exchange of information. For either TwinPeaks or JNI, it may be necessary to design a new C++ library to serve as the abstract interface to the C++ legacy code. This would be necessary in the case where the object-oriented class library of the C++ legacy code was inadequate or ill-designed. As noted for ADAM-CS, all of the multiple versions of the same data in different formats (Java GUI classes, Java design classes, Java communication classes, C++ legacy classes) requires multiple layers of translation, which will likely result in both consistency and performance problems. For EC, it may be the case that legacy applications written in C, C++, Ada83, Ada95, Fortran, and assembly language may all need to be integrated to a common Java framework. At the present time, it is unclear how many of these languages will be supported. 23 The above discussion represent the key functionalities and capabilities that must be considered as a first step in transitioning a C++ legacy application to a client/server paradigm. Our discussion to this point is also relevant for COTS applications, realizing that source code may not be available, unless the upgrade is being performed by the company that produced the COTS application. In general, the considerations described above should be compatible and extensible to C legacy/COTS applications. In the worst case, an object-oriented/C++ class library can be constructed as a bridge to the C programming interface. While an extra layer of translation would be needed, once the C++ class library is available, the techniques as described above and in Section 3 can be readily applied. In fact, one could argue that this is a preferred approach, since an object-oriented interface to a C legacy/COTS application may be easier to utilize than a low-level C programming interface. Overall, the work presented in Section 3 on ADAM-CS should be applicable to C and C++ legacy/COTS applications. Our approach has emphasized a component-based view to organize and encapsulate the subcomponents of the client, wrapper, and server. Once a Java compatible framework has been attained, the new Java GUI client can offer a tool that is modern and adaptable, and information can be easily exchanged, among not only a single client and its server, but potentially between multiple clients and multiple servers. However, caution must be taken to emphasize the drawbacks, which include: the additional performance overhead and possible inconsistency of multiple data formats and associated translations; the instability, immaturity, and difficulty of using Java-to-C++ techniques (TwinPeaks and JNI); the overall complexity of the task, as clearly seen in Section 3 and its figures; and the fact that for many ECA, the likely performance degradation due to multiple data formats/translations would not be acceptable in any situation. We can make a conclusion from three perspectives. First, while the work described in Section 3 requires significant effort of a number of individuals, the potential long-range benefit of the common Java medium is extremely attractive. Second, the state of the Java, RMI, JNI, TwinPeaks, CORBA, etc., technologies raise a red flag as to whether the potential benefits outweigh the unknowns, risks, and current shortfalls. Third, for certain key EC legacy/COTS applications, another viable alternative may involve the redesign and redevelopment of a completely new application that replaces the existing one with new software. In fact, for ADAM-CS, we are seriously considering this alternative, to recode the entire C++ legacy server in Java. 5. Concluding Remarks and Future Work This paper has explored software architectural alternatives for integrating legacy, COTS, databases, clients, and servers into a distributed computing environment. We have concentrated on detailing our experiences with upgrading a C++ legacy application to be Java compatible (see Section 3 again), which were then generalized to serve as a blueprint for software engineers seeking to upgrade the legacy/COTS applications that will comprise ECA (see Section 4 again). From the work presented in Sections 3 and 4, 24 it is possible to step back even further to identify four key issues that influence and guide the integration and upgrade processes, which are summarized below: 1. Software Reuse in a Distributed Computing Environment: This represents the underlying motivation behind enterprise computing. Namely, there is the need to reuse existing software (legacy/COTS) in innovative ways, possibly in conjunction with new software constructed with emerging technologies. Clearly, it is neither cost-effective nor feasible to redesign and reimplement the legacy/COTS applications of ECA with emerging languages (e.g., Java) and paradigms (e.g., CORBA). Moreover, users of ECA will not be satisfied with old-fashioned interfaces, but will demand up-to-date tools that are prevalent on modern computing platforms (e.g., Solaris, Linux, Windows 95/NT, etc.). Therefore, legacy/COTS applications must be reused as is, with the effort concentrating on the optimal way to provide a seamless and transparent integration within the distributed computing environment. 2. Wrappers for Cohesive and Seamless Interactions: The approach to utilize wrappers for legacy/COTS applications, thereby upgrading them to a common framework, is relevant for many different programming languages (e.g., C, C++, Java, etc.) and paradigms (e.g., OODBS, CORBA, RPC, etc.). Regardless of the approach, most wrappers must have functionality to address communication, data object translation, security, and concurrent (multi-user) access to data objects. All of these functions are important to ECA, and may be further impacted by performance considerations and bandwidth limitations, thereby complicating the process of designing and implementing wrappers. Nevertheless, the wrapper remains an important component for facilitating the interaction of legacy/COTS applications within the distributed computing environment. 3. Communications Alternatives Dictated by Application Domain: There are many communication alteratives that can be explored, ranging from low-level (sockets) to mid-level (e.g., RPC or RMI) to high-level (e.g., CORBA, DCOM, etc.), each with their own advantages and disadvantages. Sockets offer fast communication with a lack of abstraction, requiring software engineers to manage all of the lowlevel details. RPC or RMI, an intermediate option, provides higher-level design with a minimal impact on the communication rate. Distributed computing environments (e.g., CORBA, DCOM, DCE, etc.) offer the highest level of abstraction with relocatable components and interfaces to multiple programming languages, but may be severely limited in performance. For ECA, the different communication alternatives must be explored to arrive at a solution that best suits its requirements. It would not be surprising if all three alternatives are necessary to support the communication requirements of ECA. 4. Consistency of Information in the Distributed Computing Environment: In EC, where a system of systems is to be constructed, the result will be an integrated environment where legacy/COTS applications are now accessible in new and different ways. As new clients are prototyped that provide access to 25 legacy/COTS information, data consistency becomes an important concern. When is data that is resident and under the control of the client sent to the legacy/COTS application? Is it done automatically whenever changes are made at the client? Or rather, it is initiated by the user? Or, instead, at certain regular intervals (e.g., session initiation or completion)? Or, when bandwidth is available due to a lull in network traffic? ECA will likely require a combination of these and other approaches to insure that data remains in a consistent state for peace and war-time activities. Overall, we believe that this paper provides an important foundational effort for understanding the software architectural alternatives and available technologies for integrating legacy/COTS applications into distributed computing environments. The future and ongoing work as it relates to EC can be explored in a number of important areas: A Taxonomy of Software Architectural Variants: In Section 2, Figures 1 through 4, different variants for integrating legacy/COTS applications were presented. In Section 3, a detailed exploration of a variant for upgrading a C++ legacy application to be Java compatible has been provided. The next logical step involves the development of a taxonomy that characterizes different software architectural variants for all types of legacy/COTS applications. Using this taxonomy, software engineers can choose the variant that is most closely aligned with their legacy/COTS application as a basis for the integration/upgrade process. This will greatly assist in the construction of ECA. Exploration and Evaluation of Emerging Paradigms and Technologies: The work on ADAM-CS, presented in Section 3, involved the paradigms of client/server, object-oriented, and wrappers, and the technologies of Java, objectserialization, and TwinPeaks. Other candidate paradigms to be considered could include OODBS (Jasmine [CAI]) and CORBA, with related technologies such as RMI, JDBC, and ORBs. Using ADAM-CS as a test-bed, we can obtain an understanding and comparison of the different solution alternatives. At a implementation level, this information supplements the taxonomy discussed previously to provide additional factors that could influence the choice of a software architectural variant. In the Spring 1998 semester at UConn, work is continuing on a number of fronts in undergraduate/graduate projects, including: increasing the capabilities of the ADAM-CS Java GUI client; evaluating the feasibility of the TwinPeaks package; and, examining the Jasmine OODBS for storing object-oriented designs in ADAM-NT. 26 References [CAI] Computer Associates, Inc., the WWW site for the object-oriented database system Jasmine. http://www.cai.com/products/jasmine/jasmine_pd/jasmine_pd.htm [Demu94a] S. Demurjian and T.C. Ting, “The Factors that Influence Apropos Security Approaches for the Object-Oriented Paradigm”, Workshops in Computing, SpringerVerlag, 1994. [Demu95a] S. Demurjian, T. Daggett, T.C. Ting, and M.-Y. Hu, “URBS Enforcement Mechanisms for Object-Oriented Systems and Applications”, in Database Security, IX: Status and Prospects, D. Spooner, S. Demurjian, and J. Dobson (eds.), Chapman Hall, 1995. [Demu95b] S. Demurjian, M.-Y. Hu, and T.C. Ting, “Role-Based Access Control for Object-Oriented/C++ Systems”, Proc. of First ACM Workshop on Role-Based Access Control, Gaithersburg, MD, November 1995. [Demu96b] S. Demurjian, T.C. Ting, M. Price, and M.-Y. Hu, “Extensible and Reusable Role-Based Object-Oriented Security”, in Database Security, X: Status and Prospects, D. Spooner, P. Samarati, and R. Sandhu (eds.), Chapman Hall, 1997. [Demu97a] S. Demurjian, T.C. Ting, and J. Reisner, “Software Architectural Alternatives for User Role-Based Security Policies”, in Database Security, XI: Status and Prospects, T.Y. Lin and X. Qian (eds.), Chapman Hall, 1998. [Demu97b] S. Demurjian and T.C. Ting, “Towards a Definitive Paradigm for Security in Object-Oriented Systems and Applications”, Journal of Computer Security, Vol. 5, No. 4, 1997. [Demu97M] S. Demurjian and D.G. Shin, “The Java Programming Language Impact upon the Army Technical Architecture (ATA) and Joint Technical Architecture (JTA)”, paper, Mitre Corporation, Eatontown NJ, Summer 1997. [DiGi97] R. Di Giorgio, “Java Developer: Use Native Methods to Expand the Java Environment”, July 1997, JavaWorld; see also http://www.javaworld.com/javaworld/jw07-1997/jw-07-javadev.html. 27 [Elli93] H.J.C. Ellis and S. Demurjian, “Object-Oriented Design and Analyses for Advanced Application Development - Progress Towards a New Frontier”, Proc. of the 21st Annual ACM Computer Science Conf., Feb. 1993. [Hu93a] M.-Y. Hu, S. Demurjian, and T.C. Ting, “User-Role Based Security Profiles for an Object-Oriented Design Model”, in Database Security, VI: Status and Prospects, C. Landwehr and B. Thuraisingham (eds.), North-Holland, 1993. [JAPI] The Sun/Javasoft WWW site for the Java Application Programmer Interface (API) libraries. http://www.javasoft.com/products/api-overview/index.html#1.1 [Moor97] K. Moore and E. Kirshenbaum, “Building Evolvable Systems: The ORBlite Project”, Hewlett-Packard Journal, Feb. 1997. [Mori97] T. Morin, “Distribute those Legacy Assets!”, Distributed Object Computing, Vol. 1., No. 3, Apr. 1997. [Need96] D. Needham, S. Demurjian, K. El Guemhioui, T. Peters, P. Zemani, M. McMahon, H. Ellis “ ADAM: A Language-Independent, Object-Oriented, Design Environment for Modeling Inheritance and Relationship Variants in Ada 95, C++, and Eiffel”, Proc. of 1996 TriAda Conf., Philadelphia, PA, December 1996. [OBJMAG96] “Cover Story/Legacy and Migration Strategies”, a series of articles in Object Magazine, SIGS Publications, Oct. 1996. [Robe97] P. Robertson, “Integrating Legacy Systems with Modern Corporate Applications”, Communications of ACM, Vol. 40., No. 5, May 1997. [Shaw96] M. Shaw and D. Garlan, Software Architecture: Perspectives on an Emerging Discipline, Prentice-Hall, 1996. [Shva98] Shvartsman, A., “Enterprise Architecture: A Layered Approach”, submitted to Mitre Corporation, January 1998. paper [Thra97] K. Thrampoulidis and E. Hatzigeorgiou, “Interfacing Java Clients with Legacy Applications”, Object Magazine, SIGS Publications, June 1997. [Twin98] The Sun/Javasoft http://neo.sun.com:8029/ WWW site 28 for the TwinPeaks beta package.