Assembly

Introduction

This document details how the Java Runtime performs assembly. Assembly is the process of wiring networks of services based on external configuration. Assembly may occur both locally (i.e. Between two services in a shared memory space) and remotely. Wires between two services within the same aggregate context are local; wires whose target is an external service or external URI are remote. Remote wires always follow pass-by-value semantics. Local wires generally follow pass-by-reference except when the component implementation contract declares otherwise.

Local Assembly

The Tuscany Java Runtime (TJR) attempts to precompute as much as possible of the assembly model when a configuration is registered. This process is termed the build phase. During this phase, the runtime walks the configuration (typically consisting of module components, components, entry points, and external services) and calls all registered implementations of o.t.core.builder.RuntimeConfigurationBuilder which in turn decorate the configuration with implementations of o.t.core.builder.RuntimeConfiguration (examples include the implementations in o.a.t.container.java.config and o.a.t.container.java.builder). RuntimeConfigurations are factories for creating instance contexts based on the corresponding configuration artifact. For example, an SCA Java component will be decorated with a RuntimeConfiguration that can produce an instance context which manages a POJO injected with the appropriate properties and references as defined by the configuration.

The strategy for how a runtime configuration creates an instance context is specific to the implementation type. For example, the SCA Java client implementation uses o.a.t.core.injection.PojoObjectFactory to create POJOs. This in turns uses implementations of o.a.t.core.Injector to inject properties and references during instantiation (the injectors are created during the build phase by o.a.t.container.java.builder.JavaComponentContextBuilder). Injectors are configured with implementations of o.a.t.core.injection.ObjectFactory to create or return a property or reference value. For example, reference values will have an injector that uses a factory such as o.a.t.core.injection.ReferenceTargetFactory which is capable of creating a proxy to the target service. In cases where a proxy is not needed, a factory may return the actual target instance.

Remote Assembly - TBD

Runtime Assembly

Runtime assembly is the process of wiring components which offer special services in the runtime. Runtime assembly is done in a manner similar to the standard assembly described above, except that system components have their own implementation type (cf. o.a.t.core.system). The system implementation type supports all SCA Java Client and Implementation model constructs (properties and references), metadata, and stateless and module scope lifecycles (request and session scopes are not currently supported but they could be added if needed). In addition, the system implementation type also supports the following capabilities:

Hierarchical Runtime Assembly

The TJR essentially assembles itself from a series of "system" components in a recursive fashion. Aggregate contexts are created from Module Components which in turn contain children that are assembled (other aggregates, simple components, entry points, and external services). Aggregate contexts may also be autowired (e.g. o.a.t.core.context.AggregateComponentContextImpl). Child aggregate contexts are managed by a special scope context, o.a.t.core.context.scope.AggregateScopeContext. This allows the runtime to assemble itself using a relatively lightweight builder infrastructure to an arbitrarily deep nesting. For further details see o.a.t.core.system.builder and o.a.t.core.system.config.