@Override
  public void uninstall(LocalExtension localExtension, String namespace) throws UninstallException {
    ExtensionURLClassLoader classLoader =
        this.jarExtensionClassLoader.getURLClassLoader(namespace, false);

    if (namespace == null || classLoader.getWiki().equals(namespace)) {
      // unregister components
      unloadComponents(localExtension.getFile(), classLoader);

      // TODO: find a way to unload the jar from the classloader
    }
  }
  @Override
  public void install(LocalExtension localExtension, String namespace) throws InstallException {
    ExtensionURLClassLoader classLoader =
        this.jarExtensionClassLoader.getURLClassLoader(namespace, true);

    // 1) load jar into classloader
    try {
      classLoader.addURL(localExtension.getFile().toURI().toURL());
    } catch (MalformedURLException e) {
      throw new InstallException("Failed to load jar file", e);
    }

    // 2) load and register components
    loadComponents(localExtension.getFile(), classLoader);
  }
  private void unloadComponents(File jarFile, ExtensionURLClassLoader classLoader)
      throws UninstallException {
    try {
      List<ComponentDeclaration> componentDeclarations = getDeclaredComponents(jarFile);

      if (componentDeclarations == null) {
        this.logger.debug("[{}] does not contain any component", jarFile);
        return;
      }

      for (ComponentDeclaration componentDeclaration : componentDeclarations) {
        try {
          for (ComponentDescriptor componentDescriptor :
              this.jarLoader.getComponentsDescriptors(
                  classLoader.loadClass(componentDeclaration.getImplementationClassName()))) {
            this.componentManager.unregisterComponent(
                componentDescriptor.getRole(), componentDescriptor.getRoleHint());
          }
        } catch (ClassNotFoundException e) {
          this.logger.error(
              "Failed to load class [{}]", componentDeclaration.getImplementationClassName(), e);
        }
      }
    } catch (Exception e) {
      throw new UninstallException("Failed to load jar file components", e);
    }
  }