Show TOC

DependenciesLocate this document in the navigation structure

Use

The development components (DCs) can use one another and, therefore, depend on each other. A DC can depend on any number of DCs, and a number of DCs can depend on one single DC.

Dependencies between DCs are not static and may change over time. A DC may declare new dependencies or delete existing ones. The dependencies between DCs are only allowed at the same hierarchy level, for example, top-level DCs may depend on each other, or DCs that are included in the same parent DC.

To make possible the use of a public part that is enclosed by another DC, you have to create a public part entityreference .

In the following figure, dependencies are depicted as arrows:

Figure 1: Dependencies between DCs on same hierarchy level

Dependencies of a parent DC are not automatically inherited to child DCs. Child DCs are not allowed to declare dependencies to their parent DC. In contrast, a parent DC can use its DC components.

Dependency Type

We distinguish between four phases in the development cycle of a DC:

  • Design Time

    Dependencies between DCs can be used by special tools. The dependency is evaluated by tools supporting the development or design process. For example, a development environment could select certain plug-ins based on such dependencies. The build can ignore such dependencies. Tools can ignore such dependencies as a whole, or selectively.

  • Build Time

    Needed for the compilation. This dependency specifies that a DC is used during compilation or when wrapping another DC. The dependency itself will be evaluated during the build process.

  • Deploy Time

    Refuses deployment if dependants are missing. This dependency specifies that a used component must already exist in the runtime system to allow the using DC to be deployed.

    The dependency is evaluated during the deployment of the DC to a runtime system to ensure a certain deployment sequence. For example, database tables should be deployed before any code that tries to work with those tables. The preconditions for runtime dependencies regarding the availability of runtime artifacts also apply to deploy time dependencies. The build should validate, and if necessary, add missing, or remove invalid deploy time dependencies from the runtime artifacts. A runtime system can ignore such dependencies as a whole, or selectively.

  • Runtime

    This dependency specifies that a DC requires another DC at runtime. This means that it can be used meaningfully only if both DCs have deployable results.

    The dependency is evaluated by the runtime system. This attribute should only be set if the DC type indicates that the build process for the DC actually produces a runtime artifact. The meaning of the attribute is undefined if the build process does not produce such an artifact. The build should validate, and if necessary, add missing, or remove invalid runtime dependencies from the runtime artifacts. A runtime system can ignore such dependencies as a whole, or selectively.

You can combine any of these usage types.

Rules for Dependencies between DCs

All of the following conditions must be fulfilled, before a DC can use another DC:

  • Both DCs have to belong to the same software component (SC). If they do not belong to one and same SC, then you have to declare dependency on a different level. In the using DC you have to explicitly declare dependency to the SC that contains the targeted DC.

  • The used DC is either:

    • a top-level DC.

    • a direct child component of the using DC.

    • the parent DC of the used DC is a predecessor of the using DC.

  • There is no exclusion in the access control list of the used DC for the using DC.

  • The DC types are compatible. There are some exclusion criteria:

    • a normal DC should not use a build-infrastructure DC.

    • DC types dependencies that make no sense should not be used.

The figure below shows allowed and not allowed dependencies, based on the rules stated above:

To use a DC, use dependencies must be created.

Use Dependencies

If you want your development component (DC) to use objects from a public part of another DC you must define use dependencies between these DCs. Use dependencies are checked by the DC build.

Most dependencies between DCs have the semantics A uses some functionality of B, or A requires B. The concrete meaning of use depends on the technologies of the interacting development relations. Using a development object can stand for a number of different actions, such as calling the method of a Java class, implementing an interface, deriving one class from another, including a C header file or referring to a table definition.

Using a development object is allowed if it is named in a public part of its DC and a dependency to this public part has been declared. Note that in a dependency, although you actually use development objects, you declare the dependencies between the DCs.

Example

In the following figure, a Java class Y in DC B wants to implement an interface X in the public part of DC A . This is possible because DC B declares a use relation to public part ppA to which X belongs.

Note that usage relations are ordinary dependencies and, therefore, must obey the usual visibility rules. The class Z in the figure, for example, is not usable for Y .

Using a development object of another DC

Note

Declaring a dependency between DCs is a necessary prerequisite for using a public development object in the public part of another DC, but that alone is not enough. In the example above, according to the Java syntax, Y would have to explicitly import X with the import X statement, before the implementation could be executed. With a use dependency, you declare your intention of wanting to use a DC; the use dependency does not execute this use concretely (depending on the technology of the participating objects).

Cyclic Use Dependencies

Cyclic dependencies are not allowed. You must avoid cyclic dependencies. The best way is to determine the dependencies between function blocks of your software in the planning phase.

A cyclic use dependency is a dependency of the type DC A uses DC B and DC B uses DC A . The cyclic use can also include more intermediate steps, like DC A DC B DC C DC A. The build recognizes the cyclic dependencies and does not build them. The reason is that there is no clear definition of which DC to build first and that a use dependency would have to be violated.

Common build time - runtime dependency mismatch

Figure 2: Example of possible dependency mismatch

In the following example we try to explain common behavior that might lead to dependency mismatch, causing. In the example development component (DC) A with public parts ppA (with purpose compilation) and ppAA (with purpose assembly) is a simple Java DC with no runtime representation on Application Server Java (AS Java). On the AS Java, you can deploy such a Java library as long as it is wrapped in a special server library DC. For that purpose, a DC B is created that assembles public part ppAA from the DC A (assuming that ppAA contains everything from DC A that is relevant at runtime). After that a Java EE Web module C is created. The DC C uses some functionality from DC A and therefore refers to the compilation public part ppA. DC C itself is assembled into an enterprise application D. However, when the runtime artifacts of the DCs B and D are deployed, the runtime does not know that D depends on B and is likely to fail.

To solve this situation, you have to create an additional dependency, that is, an at-runtime dependency between D and B. Then the build can generate appropriate runtime descriptors for both DCs including the necessary runtime references.