Package hudson

Class PluginManager

All Implemented Interfaces:
ModelObject, SearchableModelObject, SearchItem, OnMaster, org.kohsuke.stapler.StaplerOverridable, org.kohsuke.stapler.StaplerProxy
Direct Known Subclasses:
LocalPluginManager

@ExportedBean public abstract class PluginManager extends AbstractModelObject implements OnMaster, org.kohsuke.stapler.StaplerOverridable, org.kohsuke.stapler.StaplerProxy
Manages PluginWrappers.

Setting default Plugin Managers. The default plugin manager in Jenkins can be replaced by defining a System Property (hudson.PluginManager.className). See createDefault(Jenkins). This className should be available on early startup, so it cannot come only from a library (e.g. Jenkins module or Extra library dependency in the WAR file project). Plugins cannot be used for such purpose. In order to be correctly instantiated, the class definition must have at least one constructor with the same signature as the following ones:

  1. LocalPluginManager(Jenkins)
  2. LocalPluginManager(ServletContext, File)
  3. LocalPluginManager(File)
Constructors are searched in the order provided above and only the first found suitable constructor is tried to build an instance. In the last two cases the File argument refers to the Jenkins home directory.
Author:
Kohsuke Kawaguchi
  • Field Details

    • CUSTOM_PLUGIN_MANAGER

      public static final String CUSTOM_PLUGIN_MANAGER
      Custom plugin manager system property or context param.
    • plugins

      protected final List<PluginWrapper> plugins
      All discovered plugins.
    • activePlugins

      protected final List<PluginWrapper> activePlugins
      All active plugins, topologically sorted so that when X depends on Y, Y appears in the list before X does.
    • failedPlugins

      protected final List<PluginManager.FailedPlugin> failedPlugins
    • rootDir

      public final File rootDir
      Plug-in root directory.
    • context

      @Deprecated public final jakarta.servlet.ServletContext context
      Deprecated.
      as of 1.355 PluginManager can now live longer than Jenkins instance, so use Hudson.getInstance().servletContext instead.
    • uberClassLoader

      public final ClassLoader uberClassLoader
      ClassLoader that can load all the publicly visible classes from plugins (and including the classloader that loads Hudson itself.)
    • pluginUploaded

      public volatile boolean pluginUploaded
      Once plugin is uploaded, this flag becomes true. This is used to report a message that Jenkins needs to be restarted for new plugins to take effect.
    • FAST_LOOKUP

      public static boolean FAST_LOOKUP
    • UPLOAD_PLUGINS

      @Deprecated public static final Permission UPLOAD_PLUGINS
      Deprecated.
      in Jenkins 2.222 use Jenkins.ADMINISTER instead
    • CONFIGURE_UPDATECENTER

      @Deprecated public static final Permission CONFIGURE_UPDATECENTER
      Deprecated.
      in Jenkins 2.222 use Jenkins.ADMINISTER instead
    • SKIP_PERMISSION_CHECK

      @Restricted(org.kohsuke.accmod.restrictions.NoExternalUse.class) public static boolean SKIP_PERMISSION_CHECK
      Escape hatch for StaplerProxy-based access control
  • Constructor Details

  • Method Details

    • createDefault

      @NonNull public static PluginManager createDefault(@NonNull Jenkins jenkins)
      Creates the PluginManager to use if no one is provided to a Jenkins object. This method will be called after creation of Jenkins object, but before it is fully initialized.
      Parameters:
      jenkins - Jenkins Instance.
      Returns:
      Plugin manager to use. If no custom class is configured or in case of any error, the default LocalPluginManager is returned.
    • getApi

      public Api getApi()
    • getWorkDir

      @CheckForNull public File getWorkDir()
      If non-null, the base directory for all exploded .hpi/.jpi plugins.
      Returns:
      the base directory for all exploded .hpi/.jpi plugins or null to leave this up to the strategy.
    • getOverrides

      public Collection<PluginManagerStaplerOverride> getOverrides()
      Find all registered overrides (intended to allow overriding/adding views)
      Specified by:
      getOverrides in interface org.kohsuke.stapler.StaplerOverridable
      Returns:
      List of extensions
      Since:
      1.627
    • initTasks

      public org.jvnet.hudson.reactor.TaskBuilder initTasks(InitStrategy initStrategy)
      Called immediately after the construction. This is a separate method so that code executed from here will see a valid value in Jenkins.pluginManager.
    • getDetachedLocation

      @NonNull protected String getDetachedLocation()
      Defines the location of the detached plugins in the WAR.
      Returns:
      by default, /WEB-INF/detached-plugins
      Since:
      2.377
    • loadPluginsFromWar

      @NonNull protected Set<String> loadPluginsFromWar(@NonNull String fromPath)
    • loadPluginsFromWar

      @NonNull protected Set<String> loadPluginsFromWar(@NonNull String fromPath, @CheckForNull FilenameFilter filter)
    • addDependencies

      protected static void addDependencies(URL hpiResUrl, String fromPath, Set<URL> dependencySet) throws URISyntaxException, MalformedURLException
      Throws:
      URISyntaxException
      MalformedURLException
    • loadDetachedPlugins

      protected void loadDetachedPlugins()
      Load detached plugins and their dependencies.

      Only loads plugins that:

      • Have been detached since the last running version.
      • Are already installed and need to be upgraded. This can be the case if this Jenkins install has been running since before plugins were "unbundled".
      • Are dependencies of one of the above e.g. script-security is not one of the detached plugins but it must be loaded if matrix-project is loaded.
    • getBundledPluginManifest

      @Deprecated @CheckForNull public Manifest getBundledPluginManifest(String shortName)
      Deprecated.
      removed without replacement
      Returns the manifest of a bundled but not-extracted plugin.
    • dynamicLoad

      public void dynamicLoad(File arc) throws IOException, InterruptedException, RestartRequiredException
      TODO: revisit where/how to expose this. This is an experiment.
      Throws:
      IOException
      InterruptedException
      RestartRequiredException
    • dynamicLoad

      @Restricted(org.kohsuke.accmod.restrictions.NoExternalUse.class) public void dynamicLoad(File arc, boolean removeExisting, @CheckForNull List<PluginWrapper> batch) throws IOException, InterruptedException, RestartRequiredException
      Try the dynamicLoad, removeExisting to attempt to dynamic load disabled plugins
      Throws:
      IOException
      InterruptedException
      RestartRequiredException
    • start

      @Restricted(org.kohsuke.accmod.restrictions.NoExternalUse.class) public void start(List<PluginWrapper> plugins) throws Exception
      Throws:
      Exception
    • resolveDependentPlugins

      @Restricted(org.kohsuke.accmod.restrictions.NoExternalUse.class) public void resolveDependentPlugins()
    • loadBundledPlugins

      protected abstract Collection<String> loadBundledPlugins() throws Exception
      If the war file has any "/WEB-INF/plugins/[*.jpi | *.hpi]", extract them into the plugin directory.
      Returns:
      File names of the bundled plugins. Normally empty (not to be confused with loadDetachedPlugins()) but OEM WARs may have some.
      Throws:
      Exception - Any exception will be reported and halt the startup.
    • copyBundledPlugin

      protected void copyBundledPlugin(URL src, String fileName) throws IOException
      Copies the plugin from the given URL to the given destination. Despite the name, this is used also from loadDetachedPlugins(). Includes a reasonable up-to-date check. A convenience method to be used by loadBundledPlugins().
      Parameters:
      fileName - like abc.jpi
      Throws:
      IOException
    • createPluginStrategy

      protected PluginStrategy createPluginStrategy()
      Creates a hudson.PluginStrategy, looking at the corresponding system property.
    • getPluginStrategy

      public PluginStrategy getPluginStrategy()
    • isPluginUploaded

      public boolean isPluginUploaded()
      Returns true if any new plugin was added.
    • getPlugins

      @Exported public List<PluginWrapper> getPlugins()
      All discovered plugins.
    • getPluginsSortedByTitle

      @Restricted(org.kohsuke.accmod.restrictions.NoExternalUse.class) public List<PluginWrapper> getPluginsSortedByTitle()
    • getFailedPlugins

      public List<PluginManager.FailedPlugin> getFailedPlugins()
    • getPlugin

      @CheckForNull public PluginWrapper getPlugin(String shortName)
      Get the plugin instance with the given short name.
      Parameters:
      shortName - the short name of the plugin
      Returns:
      The plugin singleton or null if a plugin with the given short name does not exist. The fact the plugin is loaded does not mean it is enabled and fully initialized for the current Jenkins session. Use PluginWrapper.isActive() to check it.
    • getPlugin

      @CheckForNull public PluginWrapper getPlugin(Class<? extends Plugin> pluginClazz)
      Get the plugin instance that implements a specific class, use to find your plugin singleton. Note: beware the classloader fun.
      Parameters:
      pluginClazz - The class that your plugin implements.
      Returns:
      The plugin singleton or null if for some reason the plugin is not loaded. The fact the plugin is loaded does not mean it is enabled and fully initialized for the current Jenkins session. Use Plugin.getWrapper() and then PluginWrapper.isActive() to check it.
    • getPlugins

      public List<PluginWrapper> getPlugins(Class<? extends Plugin> pluginSuperclass)
      Get the plugin instances that extend a specific class, use to find similar plugins. Note: beware the classloader fun.
      Parameters:
      pluginSuperclass - The class that your plugin is derived from.
      Returns:
      The list of plugins implementing the specified class.
    • getDisplayName

      public String getDisplayName()
      Specified by:
      getDisplayName in interface ModelObject
    • getSearchUrl

      public String getSearchUrl()
      Description copied from interface: SearchItem
      Returns the URL of this item relative to the parent SearchItem.
      Specified by:
      getSearchUrl in interface SearchItem
      Returns:
      URL like "foo" or "foo/bar". The path can end with '/'. The path that starts with '/' will be interpreted as the absolute path (within the context path of Jenkins.)
    • discover

      @Deprecated public <T> Collection<Class<? extends T>> discover(Class<T> spi)
      Deprecated.
      Use ServiceLoader instead, or (more commonly) ExtensionList.
      Discover all the service provider implementations of the given class, via META-INF/services.
    • whichPlugin

      public PluginWrapper whichPlugin(Class c)
      Return the PluginWrapper that loaded the given class 'c'.
      Since:
      1.402.
    • stop

      public void stop()
      Orderly terminates all the plugins.
    • isNonMetaLabel

      @Restricted(org.kohsuke.accmod.restrictions.NoExternalUse.class) public static boolean isNonMetaLabel(String label)
    • getUpdates

      public PluginManager.UpdateCenterProxy getUpdates()
    • doPluginsSearch

      @Restricted(org.kohsuke.accmod.restrictions.NoExternalUse.class) public org.kohsuke.stapler.HttpResponse doPluginsSearch(@QueryParameter String query, @QueryParameter Integer limit)
    • doPlugins

      @Restricted(org.kohsuke.accmod.restrictions.DoNotUse.class) public org.kohsuke.stapler.HttpResponse doPlugins()
      Get the list of all plugins - available and installed.
      Returns:
      The list of all plugins - available and installed.
    • doUpdateSources

      public org.kohsuke.stapler.HttpResponse doUpdateSources(org.kohsuke.stapler.StaplerRequest2 req) throws IOException
      Throws:
      IOException
    • doInstallPluginsDone

      @Restricted(org.kohsuke.accmod.restrictions.DoNotUse.class) public void doInstallPluginsDone()
      Called to progress status beyond installing plugins, e.g. if there were failures that prevented installation from naturally proceeding
    • doInstall

      public void doInstall(org.kohsuke.stapler.StaplerRequest2 req, org.kohsuke.stapler.StaplerResponse2 rsp) throws IOException, jakarta.servlet.ServletException
      Performs the installation of the plugins.
      Throws:
      IOException
      jakarta.servlet.ServletException
    • doInstallPlugins

      @Restricted(org.kohsuke.accmod.restrictions.DoNotUse.class) public org.kohsuke.stapler.HttpResponse doInstallPlugins(org.kohsuke.stapler.StaplerRequest2 req) throws IOException
      Installs a list of plugins from a JSON POST.
      Parameters:
      req - The request object.
      Returns:
      A JSON response that includes a "correlationId" in the "data" element. That "correlationId" can then be used in calls to UpdateCenter.doInstallStatus(org.kohsuke.stapler.StaplerRequest2).
      Throws:
      IOException - Error reading JSON payload fro request.
    • install

      @Restricted(org.kohsuke.accmod.restrictions.NoExternalUse.class) public List<Future<UpdateCenter.UpdateCenterJob>> install(@NonNull Collection<String> plugins, boolean dynamicLoad)
      Performs the installation of the plugins.
      Parameters:
      plugins - The collection of plugins to install.
      dynamicLoad - If true, the plugin will be dynamically loaded into this Jenkins. If false, the plugin will only take effect after the reboot. See UpdateCenter.isRestartRequiredForCompletion()
      Returns:
      The install job list.
      Since:
      2.0
    • doSiteConfigure

      public org.kohsuke.stapler.HttpResponse doSiteConfigure(@QueryParameter String site) throws IOException
      Bare-minimum configuration mechanism to change the update center.
      Throws:
      IOException
    • doProxyConfigure

      @POST public org.kohsuke.stapler.HttpResponse doProxyConfigure(org.kohsuke.stapler.StaplerRequest2 req) throws IOException, jakarta.servlet.ServletException
      Throws:
      IOException
      jakarta.servlet.ServletException
    • doUploadPlugin

      public org.kohsuke.stapler.HttpResponse doUploadPlugin(org.kohsuke.stapler.StaplerRequest2 req) throws IOException, jakarta.servlet.ServletException
      Uploads a plugin.
      Throws:
      IOException
      jakarta.servlet.ServletException
    • doUploadPlugin

      @Deprecated @StaplerNotDispatchable public org.kohsuke.stapler.HttpResponse doUploadPlugin(org.kohsuke.stapler.StaplerRequest req) throws IOException, javax.servlet.ServletException
      Throws:
      IOException
      javax.servlet.ServletException
    • doCheckPluginUrl

      @Restricted(org.kohsuke.accmod.restrictions.NoExternalUse.class) public FormValidation doCheckPluginUrl(org.kohsuke.stapler.StaplerRequest2 request, @QueryParameter String value) throws IOException
      Throws:
      IOException
    • doCheckUpdateSiteUrl

      @Restricted(org.kohsuke.accmod.restrictions.NoExternalUse.class) public FormValidation doCheckUpdateSiteUrl(org.kohsuke.stapler.StaplerRequest2 request, @QueryParameter String value) throws InterruptedException
      Throws:
      InterruptedException
    • doCheckUpdatesServer

      @Restricted(org.kohsuke.accmod.restrictions.NoExternalUse.class) public org.kohsuke.stapler.HttpResponse doCheckUpdatesServer() throws IOException
      Throws:
      IOException
    • getLastErrorCheckUpdateCenters

      public String getLastErrorCheckUpdateCenters()
      Returns the last error raised during the update sites checking.
      Returns:
      the last error message
    • identifyPluginShortName

      protected String identifyPluginShortName(File t)
    • getProxyDescriptor

      public Descriptor<ProxyConfiguration> getProxyDescriptor()
    • prevalidateConfig

      public List<Future<UpdateCenter.UpdateCenterJob>> prevalidateConfig(InputStream configXml) throws IOException
      Prepares plugins for some expected XML configuration. If the configuration (typically a job’s config.xml) needs some plugins to be installed (or updated), those jobs will be triggered. Plugins are dynamically loaded whenever possible. Requires Jenkins.ADMINISTER.
      Parameters:
      configXml - configuration that might be uploaded
      Returns:
      an empty list if all is well, else a list of submitted jobs which must be completed before this configuration can be fully read
      Throws:
      IOException - if loading or parsing the configuration failed
      Since:
      1.483
      See Also:
    • doPrevalidateConfig

      public net.sf.json.JSONArray doPrevalidateConfig(org.kohsuke.stapler.StaplerRequest2 req) throws IOException
      Like doInstallNecessaryPlugins(StaplerRequest2) but only checks if everything is installed or if some plugins need updates or installation. This method runs without side-effect. I'm still requiring the ADMINISTER permission since XML file can contain various external references and we don't configure parsers properly against that.
      Throws:
      IOException
      Since:
      1.483
    • doInstallNecessaryPlugins

      public org.kohsuke.stapler.HttpResponse doInstallNecessaryPlugins(org.kohsuke.stapler.StaplerRequest2 req) throws IOException
      Runs prevalidateConfig(java.io.InputStream) on posted XML and redirects to the UpdateCenter.
      Throws:
      IOException
      Since:
      1.483
    • parseRequestedPlugins

      public Map<String,VersionNumber> parseRequestedPlugins(InputStream configXml) throws IOException
      Parses configuration XML files and picks up references to XML files.
      Throws:
      IOException
    • createCache

      @Restricted(org.kohsuke.accmod.restrictions.DoNotUse.class) public PluginManager.MetadataCache createCache()
    • disablePlugins

      @NonNull public List<PluginWrapper.PluginDisableResult> disablePlugins(@NonNull PluginWrapper.PluginDisableStrategy strategy, @NonNull List<String> plugins) throws IOException
      Disable a list of plugins using a strategy for their dependents plugins.
      Parameters:
      strategy - the strategy regarding how the dependent plugins are processed
      plugins - the list of plugins
      Returns:
      the list of results for every plugin and their dependent plugins.
      Throws:
      IOException - see PluginWrapper.disable()
    • unscientific

      @Restricted(org.kohsuke.accmod.restrictions.DoNotUse.class) public String unscientific(double d)
    • getTarget

      @Restricted(org.kohsuke.accmod.restrictions.NoExternalUse.class) public Object getTarget()
      Specified by:
      getTarget in interface org.kohsuke.stapler.StaplerProxy
    • isMetaLabel

      @Restricted(org.kohsuke.accmod.restrictions.DoNotUse.class) public boolean isMetaLabel(String label)
    • hasAdoptThisPluginLabel

      @Restricted(org.kohsuke.accmod.restrictions.DoNotUse.class) public boolean hasAdoptThisPluginLabel(UpdateSite.Plugin plugin)
    • hasAdoptThisPluginLabel

      @Restricted(org.kohsuke.accmod.restrictions.DoNotUse.class) public boolean hasAdoptThisPluginLabel(PluginWrapper plugin)