private void loadPluginUpgradeChecksFromStack(UpgradePack upgradePack,
      PluginUpgradeChecks pluginChecks) throws AmbariException {
    Set<String> pluginCheckClassNames = new HashSet<>(upgradePack.getPrerequisiteChecks());
    StackId ownerStackId = upgradePack.getOwnerStackId();
    StackInfo stackInfo = metainfoProvider.get().getStack(ownerStackId);

    URLClassLoader classLoader = stackInfo.getLibraryClassLoader();
    if (null != classLoader) {

      // first find all of the plugins which are explicitely defined in the
      // upgrade pack and attempt to load and register them
      for (String pluginCheckClassName : pluginCheckClassNames) {
        try {
          UpgradeCheck upgradeCheck = stackInfo.getLibraryInstance(m_injector,
              pluginCheckClassName);

          pluginChecks.m_loadedChecks.add(upgradeCheck);

          LOG.info("Registered pre-upgrade check {} for stack {}", pluginCheckClassName, ownerStackId);
        } catch (Exception exception) {
          LOG.error("Unable to load the upgrade check {}", pluginCheckClassName, exception);

          // keep track of the failed check
          pluginChecks.m_failedChecks.add(pluginCheckClassName);
        }
      }

      // next find all plugin checks which are required for this upgrade type by
      // scanning just the classes shipped with the stack's library JAR
      Reflections reflections = new Reflections(
          new ConfigurationBuilder()
            .addClassLoader(classLoader)
            .addUrls(classLoader.getURLs())
            .setScanners(new SubTypesScanner(),new TypeAnnotationsScanner()));

      Set<Class<? extends UpgradeCheck>> upgradeChecksFromLoader = reflections.getSubTypesOf(
          UpgradeCheck.class);

      if(null != upgradeChecksFromLoader && !upgradeChecksFromLoader.isEmpty()) {
        for (Class<? extends UpgradeCheck> clazz : upgradeChecksFromLoader) {
          // first check to make sure we didn't already try to load this one if it
          // was explicitely defined in the upgrade pack (from above)
          if (pluginCheckClassNames.contains(clazz.getName())) {
            continue;
          }

          // see if this check required by inspecting the annotation
          UpgradeCheckInfo upgradeCheckInfo = clazz.getAnnotation(UpgradeCheckInfo.class);
          if (null != upgradeCheckInfo && ArrayUtils.contains(upgradeCheckInfo.required(), upgradePack.getType())) {
            // if the annotation says the check is required, then load it
            try {
              pluginChecks.m_loadedChecks.add(clazz.newInstance());

              LOG.info("Registered pre-upgrade check {} for stack {}", clazz, ownerStackId);
            } catch (Exception exception) {
              LOG.error("Unable to load the upgrade check {}", clazz, exception);

              // keep track of the failed check
              pluginChecks.m_failedChecks.add(clazz.getName());
            }
          }
        }
      }
    } else {
      LOG.error(
          "Unable to perform the following upgrade checks because no libraries could be loaded for the {} stack: {}",
          ownerStackId, StringUtils.join(pluginCheckClassNames, ", "));

      pluginChecks.m_failedChecks.addAll(pluginCheckClassNames);
    }
  }
Uses the library classloader from the the target stack in order to find any
plugin-in {@link UpgradeCheck}s which are declared in the upgrade pack as
well as any upgrade checks which are found in the classloader and marked as
{@link UpgradeCheckInfo#required()} for this {@link UpgradeType}.
<p/>
This method uses a {@link Reflections} instance which has been created
using only the {@link URL}s which the stack library is comprised of. This
means that scanning the path for {@link UpgradeCheck} instances is quick.
However, this also means that the {@link ClassLoader} is unable to load
classes which are defined in the stack but ship with Ambari's
{@link ClassLoader}. For this reason, we must use a different
{@link ClassLoader} for loading explicitly defined classes versus those
which are discovered by {@link Reflections}.

@param upgradePack
         the upgrade pack which defines the upgrade check classes.
@param pluginChecks
         the collection to popoulate.
ambari-server/src/main/java/org/apache/ambari/server/checks/UpgradeCheckRegistry.java