DPML
Building on the Sholders of Giants
HomeUtilitiesStationMetro
Building on the Sholders of Giants
Tutorial Objective

This tutorial aims to demonstrate the reuse of existing component jar files and deployment definitions. The demonstration uses three projects involving an API, an implementation of that API, and a demo component and associated testcase. The API is used by both the implementation and the demo and the implementation is plugged into our demo component at runtime. Apart from the direct demonstration of different combination techniques used in component construction, the tutorial details the impact on classloader chain construction.

Project Definitions

The clock API is defined in a separate project so that we can reuse the service interface Clock in our demo and implementation projects. The separation of the API ensures that the jar file can exist at a level in a classloader heirachy appropriate for its role as a shared contract (as destinct from a jar file containing an private implementation which would typically exist at a lower level in the classloader heirachy).

<index ..... >

  <project name="acme-clock-api" basedir="api">
    <types>
      <type id="jar"/>
    </types>
  </project>
  
  ...
  
</index>

The acme-clock-impl project contains a clock implementation SimpleClock together with deployment information (as a component-based part artifact). The project definition includes a runtime dependency on the acme-clock-api API project and as such, the runtime classloader chain definition for the implementation will include a reference to its own jar file and the api jar file (as artifact uris).

<index ..... >

  <project name="acme-clock-impl" basedir="clock">
    <types>
      <type id="jar"/>
      <component xmlns="dpml:metro" 
           type="org.acme.scheduler.SimpleClock" alias="true"/>
    </types>
    <dependencies>
      <runtime>
        <include key="acme-clock-api"/>
      </runtime>
    </dependencies>
  </project>
  
  ...
  
</index>

The acme-clock-demo project is an example of a component definition that incorporates the clock implementation as an internal part and uses the implementation through the service API. In the following project definition we have included the clock implementation deployment data by referencing the component uri argument (as such we are defining a new component type that extends the base component referenced by the uri value) enabling the possibility to ovderride the context arguments with new values. In addition we have declared a build time dependency on the acme-clock-impl (just to ensure that it is build before or demo project is built). It is important to note that a build time dependency only concerns build sequencing and does not impact our runtime dependency model. In fact, during runtime the demo component is established and the clock implementation is created within a classloader that is a child of the enclosing demo component classloader. As such, the implementation classes are private to the implementation component and the common APIs are provided via the demo components classloader.

<index ... >

  <project name="acme-clock-demo" basedir="demo">
    <types>
      <type id="jar"/>
      <component xmlns="dpml:metro"
           type="org.acme.demo.Demo">
        <parts>
          <component key="clock" uri="link:part:org/acme/import/acme-clock-impl">
            <context>
              <entry key="format" value="h:mm a"/>
            </context>
          </component>
        </parts>
      </component>
    </types>
    <dependencies>
      <build>
        <include key="acme-clock-impl"/>
      </build>
      <runtime>
        <include key="acme-clock-api"/>
        <include ref="dpml/util/dpml-logging-api"/>
      </runtime>
      <test>
        <include ref="ant/ant-junit"/>
        <include ref="dpml/transit/dpml-transit-main"/>
      </test>
    </dependencies>
  </project> 
  
  ...
  
</index>
Summary