+ }
+ }
+
+ List<Component> started = new ArrayList<Component>();
+ for (Component component : _components) {
+ try {
+ checkAllRequiredServicesAlreadyProvided(allProvided, component);
+
+ // Start the service.
+ Object runtime = component.start(scope);
+ scope.addRuntime(component, runtime);
+ started.add(component);
+
+ // add all provided services
+ ProvidedInterface[] provided = component.getProvidedInterfaces();
+ allProvided.addAll(Arrays.asList(provided));
+ } catch (SystemAssemblyException e) {
+ throw e;
+ } catch (RuntimeException e) {
+ LOG.error(getQualifiedName() + ": could not start '"
+ + component.getQualifiedName() + "'", e);
+ stopAlreadyStartedComponents(started, scope);
+ throw e;
+ }
+ }
+ return scope;
+ }
+
+ private void stopAlreadyStartedComponents(List<Component> aStarted, Scope aScope) {
+ // an exception occurred, stop the successfully started
+ // components
+ for (int i = aStarted.size() - 1; i >= 0; i--) {
+ try {
+ aStarted.get(i).stop(aScope);
+ } catch (Throwable t) {
+ LOG.error(getQualifiedName() + ": error stopping "
+ + aStarted.get(i).getQualifiedName());
+ }
+ }
+ }
+
+ private void checkAllRequiredServicesAlreadyProvided(
+ List<ProvidedInterface> aAllProvided, Component aComponent) {
+ // Check if all required services are already provided by
+ // earlier
+ // systems.
+
+ for (RequiredInterface descriptor : aComponent.getRequiredInterfaces()) {
+ ProvidedInterface[] filtered = filterProvidedServices(
+ descriptor, aAllProvided);
+ if ( filtered.length == 1 ) {
+ descriptor.setProvider(filtered[0]);
+ } else if ( filtered.length > 1 ) {
+ throw new SystemAssemblyException(
+ "Service '"
+ + descriptor
+ + "' required by system '"
+ + aComponent
+ + "' matches multiple services provided by other systems: "
+ + getServers(filtered));
+ } else {
+ // filtered.length == 0
+ if ( !descriptor.isOptional()) {