WebSphere Enterprise Team Development Guidelines for Component Broker ApplicationsAssumptionsThe primary assumption at this point is that you are already familiar with the key components and collaborations of the WebSphere Application Server Enterprise Edition (WAS EE) Component Broker (CB) Managed Object Framework (MOFW). If you are not familiar with the MOFW then please refer to A Nutshell Guide to the CB Programming Model Since you're using the Rational Unified Process, you'll have Use Cases, Scenarios, and other design documentation from your project to guide you in this effort. Contents
Introduction
The Big PictureBefore we begin our discussion, let's step back for a moment to see where we are in the overall application development process the context of an iterative, incremental development process where the phases have been defined as: Analysis -> Design -> Build -> Test -> Deploy -> Maintain This means that before we actually start to build anything, we already have a significant amount of information about our project available to us. The overall design and architecture of the application has already been determined. The Business Objects that you will be building have been defined and documented in Rational Rose®. The design model may or may not be partitioned into categories at this time. This discussion will provide you with information to that will guide you the partitioning process. Where were headedOur discussion will initially describe a very simple scenario, with a single user developing a single model. The development process and basic capabilities required for the scenario will be described and the enhancements being added to Object Builder in V3.0 to support the scenario will be outlined. This description will then be repeated for increasingly complex scenarios, with multiple models, and then multiple developers being covered. This approach is not used to infer that there will be serious development occurring with the single user scenarios, but rather as a way to introduce the various changes and complexities in stages. Every enhancement that is described should be usable and useful in the subsequent scenarios. The scenarios primarily describe the development of C++ or Java BOs, and not the deployment of EJBs. After the overall development process has been outlined, we will then discuss some specific issues that should be considered before starting the build phase of your project. Overview
Development of a distributed enterprise application is fundamentally different from the development of a stand-alone program. It's important to take the time to design the scope and structure of the application before beginning large scale development. While the tools provided (such as Object Builder and Rational Rose) can be used to model and prototype parts of the application, it's not realistic to expect the rapid edit-compile-debug cycle time that can occur during development of much smaller programs. The amount of code that must be generated and compiled to reflect even simple changes (such as the addition of an attribute) mean that the turnaround time can become prohibitive. As a consequence, it is strongly recommended that the design be comprehensively planned out before significant implementation is attempted. Another important consideration regards the different roles that occur during the development of an enterprise application. It's expected that the overall design and architecture of the application, the mapping of state data, the development of business logic, and the run-time deployment and configuration will all be accomplished by separate people. Of these roles, the design is expected to be completed primarily in Rational Rose; the state data mapping and framework code generation will be completed within Object Builder; the business logic will be entered in Object Builder or a separate IDE; and the run-time configuration will be completed partly within Object Builder and partly in the System Management tool. These are not required distinctions, but they reflect the guiding principles that were used when designing the development tools. Single
User, Single Model Development Process
The initial design of an application is expected to take place in Rational Rose. The user will create the basic structure of the application, including the relationships between interfaces (including inheritance, association, and aggregation), and the basic definition of the interfaces (method and attribute definitions). The design for a single model will be contained within a single Rose .cat file, and is exported from Rose into Object Builder. The definition of the interfaces can be completed or modified within Object Builder. Any changes made to the interfaces can be re-imported back to Rational Rose. Interfaces can also be defined entirely within Object Builder, if so desired. IDL Constructs (typedefs, structs, unions, and the like), Non-IDL types, interface definitions, and platform targeting information are all reasonable data elements to define or modify within Object Builder. A new auto save capability means that changes made within Object Builder can be automatically saved on a timed basis. In V3.0, several enhancements have been made to the supported code generation patterns. Relationships between interfaces can be designated as read-only, allowing the generation of just the "list" method, and the suppression of the "add" and "remove" methods. Any complex IDL type (such as typedefs, structs, and unions) can be used in copy helpers. In addition, typedefs of primitive types can now be used in the primary key. The persistence mechanisms for the interface state data must be defined within Object Builder. This process includes identifying the backing store of the state data, and mapping the various data elements to their associated persistent representation. The DO/PO attribute and method mapping mechanisms have been simplified in V3.0 to allow automatic mappings to be created where reasonable defaults can be deduced. Another significant change in V3.0 allows for nested home/key mappings in the DO implementations. In V2.0, object reference attributes could either be mapped by a stringified handle or by the primary key attributes mapped to primitive attributes in the PO. In V3.0, the primary key attributes can now include nested object references, which can in turn be mapped by the primary key attributes. Once the state date has been mapped, Object Builder is capable of generating the significant amount of framework code that is required to implement the structures, relationships, and state data that have been defined. At this stage, it's appropriate to begin implementing the business logic in the BOs. The business logic can be entered in three different ways. A basic editing capability is available within the edit window in Object Builder. This allows individual method bodies to be viewed or edited. The framework code generated by Object Builder can also be easily viewed within this edit window. If desired, different implementations of any method can be provided for each targeted platform. The completed code can be compiled within the Object Builder "build" window. Any errors that occur within method bodies can be selected in this window, and the relevant method body will be automatically selected into the edit window. Corrections can be made to the method body, and then the next error selected, or the code regenerated. The recommended approach for development of a large amount of business logic is to use an external IDE. The design and structure of the interfaces should be completed first, as much as possible, within Object Builder. The code and make files are then generated to the file system, at which point the IDE is used to develop and compile the business logic. This mode of operation allows each tool to be used for its primary purpose; Object Builder for the definition of the structure and generation of the framework code; and the IDE for comprehensive editing, browsing, and overall rapid development. Once the business logic is complete, the source code can be re-imported into Object Builder, and the modified method bodies will be inserted into the correct place in the model. Note that new attributes or methods cannot be added using this approach, so its important to have the design and structure of the interfaces as complete as possible before starting implementation. New in V3.0, methods can be optionally designated as not to be re-imported into Object Builder. This means that framework methods, for example, can be left as "tool defined", even if the original code no longer matches the current implementation due to changes in the definition of the interface. In V3.0, there will be significantly enhanced capability to specify adornments to the generated code. In V2.0 the adornment support was limited to the file scope, and not every file type could have adornments. In V3.0, adornments can be defined as prefixes or suffixes to both files and interfaces (classes). In addition, adornments can be designated for multiple file types (IDL, implementation, and header). This new capability can be used to supplement the existing Object Builder capabilities. For example, a Java nested class can be defined as an interface adornment. The class, a text "blob" defined in Object Builder, will be generated into the file in the correct place, surrounded by structured comments. All adornments have complete round-trip capability, so the contents can be modified outside Object Builder and re-imported later. Object Builder also allows method bodies to be provided via external files. This mechanism is less useful for iterative development within Object Builder, but it provides an easy mechanism to completely separate the implementation of the methods from the definition and structure of the interface. Finally, Object Builder V3.0 provides multiple binary directory support. This means that the binary results of a build can be placed in distinct directories, dependent on the build type. Four build types are provided Non-optimized; Trace; Trace & Debug. This means that a debug build can be built, without having to overlay the results of a previous optimized build. Linked Model Capabilities
In order to support finer grained versioning of changes (and also to facilitate concurrent editing in the team development scenario), models can be partitioned into a number of linked models. Each model is uniquely identified by an internal UUID, and by an external model name. Models can be partitioned across the interface files; every file containing a BO, DO or PO interface can be placed in a separate model. In addition, the build (make file), application configuration, and container definitions can all be placed in separate models. When a model is opened in Object Builder, it's opened in edit mode. Any dependent projects are opened in read-only mode and information in them cannot be modified. The location of the dependent projects is dynamically resolved via a search path, allowing different directory structures to be used on different machines. The search path can described by either an environment variable ("OBModelPath") or via a new UI control provided for the purpose. If desired, a distinct search path can be used for each project opened. However, it is recommended that consistent directory structure be defined and all dependent projects be placed under a common sub-directory (nested arbitrarily many levels deep). The search path defines the root location(s) to start searching, so individual project directories do not need to be listed. V3.0 Object Builder also includes enhanced messages and recovery mechanisms to be used if a dependent project is not located. The Rational Rose bridge provides better multiple project support capabilities in V3.0; a single Rose .cat file (which is a versionable artifact for Rose) automatically maps to an Object Builder project. This means that the partitioning of multiple projects can be defined at the Rose level, and the associated artifacts (the Rose model, the Object Builder model, and any related files) can all be versioned as a group, independently from the artifacts associated with other (linked) models. Type definitions are commonly cross-model, and V3.0 Object Builder provides a scaleable type browser mechanism that can be used to search for and select types. Selection criteria include the name, type (struct, typedef, and so on), and containing model (local or remote). Team Development Process
Versioning UNI filesWhen partitioning models for use in a team development scenario, the division should be done based on two factors; desired granularity of versioning, and expected concurrent usage. In V3.0, the unit of work (and versioning) is primarily the model, and its persistent representation (the .uni files). The recommended model divisions can be stated very plainly; every piece of your application that you expect to have developers working on concurrently should be located in a distinct model. The finest granularity available for objects is the BO/Key/Copy/MO grouping, the DO, or the PO. This means that it will not be possible to have two developers concurrently modifying the same BO implementation, for example, unless external files are used for method bodies or the changes are merged using the XML store. The recommended process for team development requires a source code configuration/versioning system and a build server. All linked models need to be checked into the configuration system. When a build is required (either on demand or on a scheduled basis), the models are extracted from the configuration system. The model search path on the build machine allows the various model dependencies to be satisfied, even if the directory structure of the build machine is completely different from that of the individual developers machine. Once all models have been extracted, each model can be optionally run through the model consistency checker. This can be run in batch mode (obcheck) and the return code of the command can be used to determine the highest severity warning/error detected. In turn, this can be used to provide ongoing validation of the structure and implementation of the models an error is detected, for example, a failed build can be declared. If this approach is used, each developer would be required (or it would be strongly recommended) to run the consistency checker prior to checking their model in, and to correct any problems identified. Options to the command allow different checks to be enabled or disabled. The code for each model must now be generated. Again, a batch tool (obgen) is available for this task. The "-linked" option of obgen should be used, causing only the code defined in a model to be generated for that model. The make files that are generated will assume that each source file is in the "Working" directory of its owning model. The location of each model will be dynamically determined (via the model search path, as above) and placed only in a single file ("prjdefs.mk"). This file is then included by each make file. The indirection this provides means that the make files themselves are location independent. The type of build required (optimized, debug, and so on) is specified as an option to obgen. Finally, each project should be built. This can also be run in batch mode and is simply a matter of running "nmake /f all.mak" in the working directory of each project. At the conclusion of the build process, the complete results (model .uni files, generated source code, and resultant binary code) should be made available to developers. This can be accomplished in many different ways, ranging from making the build server an accessible read-only LAN drive, to packaging the complete build into a .zip file and distributing that to developers for extraction on their own machines. Some mechanism of distributing the build results, as opposed to having each developer refer to a common copy, is recommended for two reasons. Firstly performance; Component Broker projects are large is typically more code generated by Object Builder and IDLC than the user has directly created. Referring to all the required files over the LAN can be a performance problem for a large number of developers. Secondly, it may be required to recompile some parts of the build results. No unnecessary compiles are done, but if the developer changes a base interface, all derived interfaces will need to be recompiled. This can be problematic if the derived interfaces are located on a read-only LAN drive. Each developers environment should be set up such that the model search path points to a local directory, and then the results of the build, which may be either local or remote. When a change needs to be made to a model, it is checked out of the configuration system and placed as a sub-directory of the first local drive mentioned above. Multiple models can be checked out simultaneously, if required; Object Builder will follow the order of the directories contained in the model search path to locate any dependencies, and so any models that have been checked out will be used as dependencies before the "build machine" copy of that model is used. Developers can then make the changes that are required to their models as outlined in the first part of this document. Depending on the role of the particular developer, this could include using Object Builder to modify the structure of the interface; change the implementation of a method, or generate all the source for the model and make many method changes in an external IDE. When the make file is generated for the checked-out model, the location of the various dependent projects is used to generate the "prjdefs.mk" file. This means that the make file will refer to any dependencies in the correct location, either on the local or build machine. Finally, when the desired changes are complete, the model file(s) would be checked back into the configuration system. The results of the changes made would not be generally available to other developers until the results of the next build cycle are published. This is desirable, as it would otherwise leave developers vulnerable to the possibility that an interface they are dependent on may change without warning. In turn, this would require unnecessary recompilation. If a developer needs immediate access to a change, they can simply extract the model files to their local machine, and generate and build the code themselves. Versioning XML filesThe structure of the XML generated by Object Builder in V3.0 has been significantly changed from previous versions. The new XML, and its accompanying import process, is more robust, performs better, and is generally more suitable than before as a mechanism to version the Object Builder model data. It's important to note that the new XML has far more uses than just as a versionable artifact. It can be used as a unit of exchange between tools, such as with the Rose bridge. It can be used with the XML SmartGuide tools, to provide customized user interfaces (UIs), data entry, and defaults. It can be used as a basis to browse models, via the XSL stylesheets to be provided. It can also be used in differential or change analysis, or as a mechanism to simply log the changes made in textual form. Team development will be supported using the basic mechanisms described in the previous section, but with the additional option of versioning some or all models as XML files. When the models are extracted from the configuration system by the build machine, the XML files would need to be imported to create a model (.uni) representation before the source code could be generated. Once the import was complete, the generation, build and publishing processes would proceed as previously described. Developers working on models that were versioned as .uni files would not be impacted in this environment. By the time the build results are published, all models are in .uni form, and the development process would continue exactly as described previously. Developers working on models that were versioned as XML files would have two options when checking a model out. The first method assumes there is not a local copy of the model they wish to change. The developers would check out all copies of the XML file they wish to change, and simply extract any additional XML files that existed for that model. All XML files for the model would then be imported and Object Builder would be run on the resultant .uni file. Alternatively, a local copy of the models .uni file is first copied to the developer's machine. This would likely be the .uni file that was created on the build machine, but any local copy of the .uni file is sufficient. Object Builder would be run on the .uni file, and the "Check out" action available on the file node in question would be invoked. From the users perspective, this would simply present a SmartGuide prompting for relevant details, such as a defect or release name. When completed, the XML file would be checked out and automatically imported into Object Builder. The mechanism used for this process is based on the XML SmartGuide tool set. This allows a SmartGuide to be dynamically generated based on the content of a source macro XML file (distinct from the XML file containing the Object Builder model data). When the SmartGuide is completed, a batch/script file is dynamically generated reflecting the data entered. This file is then executed to actually check out the XML data file. Upon completion, the XML file is imported into Object Builder. The data prompted for, and the format of the batch file generated, are completely determined by the macro XML file. By modifying this file with the XML customizer tool, a user (typically the site administrator) can provide a custom UI and batch file specific to the configuration system in use. After the file has been checked out, the developer would make whatever changes or enhancements required to the model, as described previously. Any dependencies on other models are satisfied via the model search path, as every model is in the .uni format at this point. When the changes are complete, the developer selects "Check in" from the popup menu on the file node in question. Again from the user's perspective, a SmartGuide prompts for relevant data, and the XML is then checked in to the configuration system. The implementation of this is very similar to the check out process; a user modifiable macro XML file is used to dynamically create a SmartGuide and then a batch/script file. The XML is exported and the batch file is run to check in the file. There is an additional function being added in V3.5 that will highlight when an XML file has been checked in or out. If the XML file for an object exists and is read-write, it is assumed the file is checked out. In this case, the object is shown as editable in the Object Builder UI and "check in" action is available on the popup menu. If the XML file does not exist, or is read-only, it is assumed the file is not checked out. The object is shown in the Object Builder UI as read-only and the "check out" action is available on the popup menu. This information is provided by IBM
Corporation © Copyright IBM Corporation 1999-2000
|
|
Rational Unified
Process |