www.developer.com/java/web/article.php/1379751
|
By Robert Brewin July 2, 2002 AbstractThe Native Connector Architecture (NCA) is a model that allows for the automatic generation of code bridges between differing languages and platforms. Given a description of the interfaces exposed (and desired), it is then possible to derive and generate the code necessary to bridge the two bodies of code. The architecture defines an extensible and highly configurable model for the description of interfaces as well as the generation of bridging code using open standards for general use. As a result, bridges can easily be created between, for example, the C++ and JavaTM languages, differing C++ Application Binary Interfaces (ABI), Web service protocols (such as SOAP), as well as inter-platform bridges (for example, Microsoft COM/.NET to SolarisTM operating environment binaries). Existing TechnologyAt present, there are a number of models for bridging bodies of code or applications. Examples include: Problems and IssuesThe general problem of integration between languages and platforms is that for each such bridge between architectures, a new implementation must be created to provide the binding between environments. Worse, for each new application, even though the type of bridge may be identical (for example, between C++ and Java technology), specific interfaces used may be different, resulting in a brand new implementation of the bridge even though the general pattern remains the same. In general, this manual implementation of bridging code can (and does) lead to the following issues and problems:
The general result is sub-optimal performance of a bridged system because tuning a large-scale, complex application across multiple languages or platforms is necessarily difficult and frequently not attempted until it becomes a problem on deployment. JNI Integration ModelAs an example of such an existing technology, the JNI (Java Native Interface) is a model for integration used by the Java platform. As with all existing bridging technologies or architectures, the general rule is to pick a common implementation language or technology (for instance, a subset of the languages to be bridged) and use that as the foundation for the bridging code. Each component being bridged must therefore implement any conversions and handle any implementation-specific features on its side of the bridge. For the Java language, the C language is a natural fit as a bridging language, for a number of reasons:
The general steps one must use in a JNI-based solution are shown in Figure 1:
Figure 1: The JNI Process JNI requires special handling within the Java code to enable, load, and use native libraries within the Java environment, namely:
Native Connector Architecture ConceptsNCA defines a model as a process designed to reduce or eliminate the risks and complexity involved with manual integration between languages or platforms such as represented by the Java to C++ language example. While the architecture is agnostic in terms of which languages or platforms can be integrated, in the following discussion examples will typically use the bridging of the Java and C++ languages as an example of the solutions that the architecture provides. The underlying principles behind NCA are:
API MetadataThe patterns defined by NCA are designed to be implemented against a collection of metadata that describes the interfaces for the existing source (client) and the generated target API. When these are provided, and given a specific pattern to generate, the intermediate code can be generated according to the rules and semantics defined for a particular bridge. In modern computing, there are many potential systems that can provide descriptive information about APIs, the most powerful today being that of XML. To that end, NCA defines PLanML (Programming Language Markup Language), which is designed to represent a large number of the common languages used today. PLanML is defined by its own schema, which defines the principle types, methods and enumerations required by NCA-compliant tools to generate code according to the principal patterns. A representative sample of the metadata generated for a simple C++ class may look like Example 1.
<typeDef aliasName="HelloWorld" byteSize="1" category="struct"
name="HelloWorld" typeID="110">
<struct aliasName="HelloWorld" type="class">
<method access="public" methodID="144" name="value"
scopeRef="110" typeRef="105">
<parm typeRef="87" name="arg"/>
</method>
</struct>
</typeDef>
Example 1: PLanML for a simple class Transformation/Code GenerationGiven the existence of common metadata describing the APIs used for a set of common languages (PLanML), a natural extension is to use XSL/T (XSL Transformations) to allow for the generation of bridging code compliant with the Native Connector Architecture. As part of the transformation process, a compliant tool will be able to:
NCA defines some default patterns for the use of generating Java language to C++ connectors; however, one of the distinct advantages of the architecture is that the templates used are human readable (and thus modifiable). By invoking an XSL/T processor against different templates, one can generate different types of bridges and different bodies of code, resulting in a highly extensible bridging toolkit. Resulting Component AnatomyA given component that adheres to the Native Connector Architecture is modeled as shown in Figure 2:
Figure 2: Native Connector Component Anatomy Runtime ArchitectureThe runtime architecture of a system based on Native Connectors presumes that the existing client code and existing legacy code remain unchanged by the addition of the Connector. The Native Connector Architecture defines the following elements:
The general runtime architecture for a Connector-based system can be described as in Figure 3:
Figure 3: Runtime Architecture Overview Connector Generation ProcessThe process by which the Bridge, Container, and Component are generated is a mechanical, data-driven set of actions that forms a code generation process. The foundation of this generation is two-fold:
Figure 4: Overall Connector Generation Process Metadata GenerationThe process of metadata generation is shown in Figure 5 and will largely depend on the implementation of tools using the Native Connector Architecture. Examples of metadata sources include:
Figure 5: Metadata Generation Phase Component Design/SpecificationThe process of component specification can be performed automatically or manually and is shown in Figure 6.
Figure 6: Component Design/Specification Phase The limitations imposed on automated component specification are largely driven by the compatibility between the languages being bridged as well as whether a set of rules can be devised that can automatically handle issues such as naming conflicts, type promotions, or conversions. In contrast, a fully manual implementation requires user interaction to drive the component specification process, including choosing the interfaces, identifiers used, and parameter conversions, as well as the management of unsupported types and methods. The ideal solution is a hybrid, one in which a tool based on the NCA will handle much of the automated conversion process by the judicious use of established defaults for naming conventions, parameter usage, and conflict resolution. Such a tool will flag elements it cannot handle appropriately and allow the user to interact with the tool to resolve conflicts. Code GenerationCode generation (Figure 7) is the process of creating the bridge code to map between the two sets of APIs, those present in the target and those specified as part of the client interface.
Figure 7: Code Generation Phase Since the metadata used to describe both sets of APIs is a specific schema based on XML (PLanML), the architecture defines the use of XSL stylesheets to drive a pattern-based code generation process. Tools based on NCA will consume PLanML and pass this data to an XSL processing engine. In general, this may require multiple passes through the processing engine, once for each type of output desired. This approach may be useful for extensibility, since properly factored XSL stylesheets can be used in alternative bridge generation scenarios. Build, Assembly, and DeploymentThe final process involves taking the generated source, building the result into usable binary components, and packaging the results for deployment, as shown in Figure 8.
Figure 8: Build, Assembly, and Deployment Phase While building is generally independent of the type of bridge or target environment (the latter may require building on the target platform), packaging and deployment will change depending on the type of bridge being created. For example, when deploying into the J2EETM environment, the location, naming and descriptor information will need to be different than that of a standalone J2SETM application. Because a bridge generated by a tool such as the Sun ONE Studio Native Connector Tool is fully automated, and the target type is known, the system knows precisely which components were generated and is fully capable of not only generating the build rules (for example, scripts or makefiles), but populating the resulting packages appropriately and emitting descriptor data needed for deployment. Process ComparisonTo illustrate the differences between JNI and Native Connector processes, Figure 9 provides a comparison of the steps involved in each.
Figure 9: Process comparison between JNI and a Native Connector implementation. As can be seen from the above, most of the steps required by JNI are manual in nature, while those required by a Native Connector Architecture implementation are generally automatic:
SummaryThe Native Connector Architecture defines a model for the easy, automatic generation of components in, for instance, the Java language, which are bound to existing legacy implementations written in languages such as C and C++. The architecture and tools provide an extensible model for the addition of new bridge types and support for additional languages and platforms. While at this time tools exist that allow for the generation of J2SE and J2EE Connectors to C and C++, future implementations will likely provide additional capabilities and language/platform support, such as interoperability between Microsoft .NET components and other popular languages, such as Fortran. About the AuthorRobert Brewin is the Architect for Enterprise Development Tools responsible for architectural and engineering issues for Sun ONE Studio products. Sun, Sun Microsystems, the Sun Logo, Sun ONE Studio, Java, Solaris, J2SE, and J2EE are trademarks or registered trademarks of Sun Microsystems, Inc. in the United States and other countries. |