private static void validateServiceDuplication(StackManager stackManager, StackInfo stack, ExtensionInfo extension, Collection<ServiceInfo> services) throws AmbariException {
    LOG.debug("Looking for duplicate services");
    for (ServiceInfo service : services) {
      if (service != null) {
        LOG.debug("Looking for duplicate service " + service.getName());
        ServiceInfo stackService = null;
        try {
          stackService = stack.getService(service.getName());
          if (stackService != null) {
            LOG.debug("Found service " + service.getName());
            if (isInheritedExtensionService(stackManager, stack, service.getName(), extension.getName())) {
              stackService = null;
            }
          }
        }
        catch (Exception e) {
          //Eat the exception
          LOG.error("Error validating service duplication", e);
        }
        if (stackService != null) {
          String message = "Existing service is included in extension"
                      + ", stackName=" + stack.getName()
                      + ", stackVersion=" + stack.getVersion()
                      + ", service=" + service.getName()
                      + ", extensionName=" + extension.getName()
                      + ", extensionVersion=" + extension.getVersion();

          throw new AmbariException(message);
        }
      }
    }
  }
An extension version is like a stack version but it contains custom services.  Linking an extension
version to the current stack version allows the cluster to install the custom services contained in
the extension version.
ambari-server/src/main/java/org/apache/ambari/server/stack/ExtensionHelper.java