March 2, 2021
Hot Topics:

Binding Java and Web Services to Native Code

  • By Robert Brewin
  • Send Email »
  • More Articles »

API Metadata

The 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"/>

Example 1: PLanML for a simple class

Transformation/Code Generation

Given 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:

  • Generate all of the bridging code required to create a Connector.
  • Generate build instructions/rules (such as a Makefile useable by the make tool).
  • Generate descriptor information describing the generated code as well as the output of the build for use in assembly and deployment of the Connector.

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 Anatomy

A given component that adheres to the Native Connector Architecture is modeled as shown in Figure 2:

  • The original code is unchanged and may be composed of a single object, or a collection of objects or methods.
  • The original code is "wrapped" in methods and objects, which both abstract the original code's APIs as well as provide any "plumbing" (such as marshalling, un-marshalling, or system calls) that may be needed to isolate the original code.
  • A single, new interface is generated around the "plumbing" code, which provides an interface that is natural within the context of the client environment. This means, for example, that if the client is a Java application, the new interface is a pure Java class/object rather than a collection of native methods.
  • The client interacts with the component in its natural environment, obeying the semantics and rules that govern it. The mechanisms and foreign semantics of the underlying code are encapsulated and hidden to the client application.

Click here for a larger image.

Figure 2: Native Connector Component Anatomy

Runtime Architecture

The 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:

  • A Container, which logically encapsulates the APIs exposed by the legacy code. Functionality exposed by the legacy code is delegated to it by the Container methods
  • A Bridge, which serves the function of mapping the Container methods to the Component (the point of integration for client code) as well as any marshalling, un-marshalling, or special system processing
  • A Component or Accessor, which serves as the point of integration for client code
  • A Runtime component, which handles any system behavior required, such as object lifetime management, exception handling, and so forth

The general runtime architecture for a Connector-based system can be described as in Figure 3:

Click here for a larger image.

Figure 3: Runtime Architecture Overview

Connector Generation Process

The 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:

  • PLanML, a specific schema of XML that describes the interfaces both consumed and emitted in a language- and platform-agnostic fashion
  • XSL/T, a set of patterns embodied as XSL transformations that consume PLanML and emit code for later compilation. The overall process is shown in Figure 4:

Click here for a larger image.

Figure 4: Overall Connector Generation Process

Page 2 of 3

This article was originally published on July 2, 2002

Enterprise Development Update

Don't miss an article. Subscribe to our newsletter below.

Thanks for your registration, follow us on our social networks to keep up-to-date