Class PluginLoader

java.lang.Object
edu.umd.cs.findbugs.PluginLoader
All Implemented Interfaces:
AutoCloseable

public class PluginLoader extends Object implements AutoCloseable
Loader for a FindBugs plugin. A plugin is a jar file containing two metadata files, "findbugs.xml" and "messages.xml". Those files specify
  • the bug pattern Detector classes,
  • the bug patterns detected (including all text for displaying detected instances of those patterns), and
  • the "bug codes" which group together related bug instances

The PluginLoader creates a Plugin object to store the Detector factories and metadata.

See Also:
  • Field Details

    • XPATH_PLUGIN_SHORT_DESCRIPTION

      private static final String XPATH_PLUGIN_SHORT_DESCRIPTION
      See Also:
    • XPATH_PLUGIN_WEBSITE

      private static final String XPATH_PLUGIN_WEBSITE
      See Also:
    • XPATH_PLUGIN_PROVIDER

      private static final String XPATH_PLUGIN_PROVIDER
      See Also:
    • XPATH_PLUGIN_PLUGINID

      private static final String XPATH_PLUGIN_PLUGINID
      See Also:
    • LOG

      private static final org.slf4j.Logger LOG
    • lazyInitialization

      static boolean lazyInitialization
    • partiallyInitialized

      static LinkedList<PluginLoader> partiallyInitialized
    • nextUnknownId

      private static int nextUnknownId
    • classLoader

      private ClassLoader classLoader
    • classLoaderForResources

      private final ClassLoader classLoaderForResources
    • plugin

      private final Plugin plugin
    • corePlugin

      private final boolean corePlugin
    • initialPlugin

      boolean initialPlugin
    • cannotDisable

      boolean cannotDisable
    • optionalPlugin

      private boolean optionalPlugin
    • loadedFrom

      private final URL loadedFrom
    • jarName

      private final String jarName
    • loadedFromUri

      private final URI loadedFromUri
    • createdClassLoaders

      private List<URLClassLoader> createdClassLoaders
    • parentId

      String parentId
      plugin Id for parent plugin
    • loadedPluginIds

      static HashSet<String> loadedPluginIds
  • Constructor Details

    • PluginLoader

      @Deprecated public PluginLoader(URL url) throws PluginException
      Deprecated.
      Constructor.
      Parameters:
      url - the URL of the plugin Jar file
      Throws:
      PluginException - if the plugin cannot be fully loaded
    • PluginLoader

      @Deprecated public PluginLoader(URL url, ClassLoader parent) throws PluginException
      Constructor.
      Parameters:
      url - the URL of the plugin Jar file
      parent - the parent classloader
      Throws:
      PluginException
    • PluginLoader

      private PluginLoader(@Nonnull URL url, URI uri, ClassLoader parent, boolean isInitial, boolean optional) throws PluginException
      Constructor.
      Parameters:
      url - the URL of the plugin Jar file
      uri -
      parent - the parent classloader
      isInitial - is this plugin loaded from one of the standard locations for plugins
      optional - is this an optional plugin
      Throws:
      PluginException
    • PluginLoader

      @Deprecated public PluginLoader() throws PluginException
      Deprecated.
      Constructor. Loads a plugin using the caller's class loader. This constructor should only be used to load the "core" findbugs detectors, which are built into findbugs.jar.
      Throws:
      PluginException
    • PluginLoader

      @Deprecated public PluginLoader(boolean fake, URL url)
      Deprecated.
      Fake plugin.
  • Method Details

    • hasParent

      public boolean hasParent()
    • finishLazyInitialization

      private static void finishLazyInitialization()
    • buildURLClassLoader

      private URLClassLoader buildURLClassLoader(URL[] urls)
      Creates a new URLClassLoader and adds it to the list of classloaders we need to close if we close the corresponding plugin
      Parameters:
      urls - the URLs from which to load classes and resources
      Returns:
      a new URLClassLoader
    • buildURLClassLoader

      private URLClassLoader buildURLClassLoader(URL[] urls, ClassLoader parent)
      Creates a new URLClassLoader and adds it to the list of classloaders we need to close if we close the corresponding plugin
      Parameters:
      urls - the URLs from which to load classes and resources
      parent - the parent class loader for delegation
      Returns:
      a new URLClassLoader
    • close

      public void close() throws IOException
      Closes the class loaders created in this PluginLoader
      Specified by:
      close in interface AutoCloseable
      Throws:
      IOException - if a class loader fails to close, in that case the other classloaders won't be closed
    • createClassloaderUrls

      @Nonnull private static URL[] createClassloaderUrls(@Nonnull URL url) throws PluginException
      Patch for issue 3429143: allow plugins load classes/resources from 3rd party jars
      Parameters:
      url - plugin jar location as url
      Returns:
      non empty list with url to be used for loading classes from given plugin. If plugin jar contains standard Java manifest file, all entries of its "Class-Path" attribute will be translated to the jar-relative url's and added to the returned list. If plugin jar does not contains a manifest, or manifest does not have "Class-Path" attribute, the given argument will be the only entry in the array.
      Throws:
      PluginException
    • addClassPathFromManifest

      private static void addClassPathFromManifest(@Nonnull URL url, @Nonnull List<URL> urls, @Nonnull Manifest mf) throws MalformedURLException
      Throws:
      MalformedURLException
    • guessManifest

      @CheckForNull private static File guessManifest(@Nonnull File parent)
      Trying to find the manifest of "exploded plugin" in the current dir, "standard jar" manifest location or "standard" Eclipse location (sibling to the current classpath)
    • computeCoreUrl

      @Nonnull private static URL computeCoreUrl()
    • getURL

      public URL getURL()
    • getURI

      public URI getURI()
    • toUri

      private static URI toUri(URL url) throws PluginException
      Throws:
      PluginException
    • getJarName

      private static String getJarName(URL url)
    • getClassLoader

      public ClassLoader getClassLoader()
    • loadPlugin

      public Plugin loadPlugin() throws PluginException
      Get the Plugin.
      Throws:
      PluginException - if the plugin cannot be fully loaded
    • getPlugin

      public Plugin getPlugin()
    • resourceFromPlugin

      private static URL resourceFromPlugin(URL u, String args) throws MalformedURLException
      Throws:
      MalformedURLException
    • getResource

      public URL getResource(String name)
      Get a resource using the URLClassLoader classLoader. We try findResource first because (based on experiment) we can trust it to prefer resources in the jarfile to resources on the filesystem. Simply calling classLoader.getResource() allows the filesystem to override the jarfile, which can mess things up if, for example, there is a findbugs.xml or messages.xml in the current directory.
      Parameters:
      name - resource to get
      Returns:
      URL for the resource, or null if it could not be found
    • getCoreResource

      @CheckForNull static URL getCoreResource(String name)
    • resourceFromFindbugsJar

      @CheckForNull private static URL resourceFromFindbugsJar(String slashedResourceName)
      Try to load resource from JAR file of Findbugs core plugin.
      Parameters:
      slashedResourceName - Name of resource to load
      Returns:
      URL which points resource in jar file, or null if JAR file not found
    • getFindbugsJar

      @CheckForNull private static URL getFindbugsJar() throws MalformedURLException
      Returns:
      URL of findbugs.jar, or null if found no jar file which contains FindBugs.class
      Throws:
      MalformedURLException
    • loadFromFindBugsEtcDir

      @CheckForNull public static URL loadFromFindBugsEtcDir(String name)
    • loadFromFindBugsPluginDir

      @CheckForNull public static URL loadFromFindBugsPluginDir(String name)
    • getClass

      private static <T> Class<? extends T> getClass(ClassLoader loader, @DottedClassName String className, Class<T> type) throws PluginException
      Throws:
      PluginException
    • init

      private Plugin init() throws PluginException
      Throws:
      PluginException
    • loadPluginComponents

      private void loadPluginComponents() throws PluginException
      Throws:
      PluginException
    • constructMinimalPlugin

      private Plugin constructMinimalPlugin(org.dom4j.Document pluginDescriptor, List<org.dom4j.Document> messageCollectionList) throws DuplicatePluginIdError
      Throws:
      DuplicatePluginIdError
    • getPluginDescriptor

      public org.dom4j.Document getPluginDescriptor() throws PluginException, PluginDoesntContainMetadataException
      Throws:
      PluginException
      PluginDoesntContainMetadataException
    • getPotentialMessageFiles

      private static List<String> getPotentialMessageFiles()
    • getMessageDocuments

      private List<org.dom4j.Document> getMessageDocuments() throws PluginException
      Throws:
      PluginException
    • loadComponentPlugin

      private <T> void loadComponentPlugin(Plugin plugin, Class<T> componentKind, @DottedClassName String componentClassname, String filterId, boolean disabled, String description, String details, PropertyBundle properties) throws PluginException
      Throws:
      PluginException
    • parseDate

      private static Date parseDate(String releaseDate)
    • getConstraintSelector

      private DetectorFactorySelector getConstraintSelector(org.dom4j.Element constraintElement, Plugin plugin, String singleDetectorElementName) throws PluginException
      Throws:
      PluginException
    • addCollection

      private void addCollection(List<org.dom4j.Document> messageCollectionList, String filename) throws PluginException
      Throws:
      PluginException
    • findMessageNode

      private static org.dom4j.Node findMessageNode(List<org.dom4j.Document> messageCollectionList, String xpath, String missingMsg) throws PluginException
      Throws:
      PluginException
    • findMessageText

      private static String findMessageText(List<org.dom4j.Document> messageCollectionList, String xpath, String missingMsg)
    • getChildText

      private static String getChildText(org.dom4j.Node node, String childName) throws PluginException
      Throws:
      PluginException
    • getPluginLoader

      public static PluginLoader getPluginLoader(URL url, ClassLoader parent, boolean isInitial, boolean optional) throws PluginException
      Throws:
      PluginException
    • getCorePluginLoader

      @Nonnull public static PluginLoader getCorePluginLoader()
    • isCorePlugin

      public boolean isCorePlugin()
    • installStandardPlugins

      static void installStandardPlugins()
    • loadPlugins

      private static void loadPlugins(File home)
    • installUserInstalledPlugins

      static void installUserInstalledPlugins()
    • loadPluginsInDir

      private static void loadPluginsInDir(File pluginDir, boolean optional)
    • loadInitialPlugins

      static void loadInitialPlugins()
    • loadCorePlugin

      private static void loadCorePlugin()
    • loadInitialPlugin

      private static void loadInitialPlugin(URL u, boolean initial, boolean optional)
    • installWebStartPlugins

      static void installWebStartPlugins()
    • getUrlBase

      private static URL getUrlBase(URL pluginListProperties) throws MalformedURLException
      Throws:
      MalformedURLException
    • toString

      public String toString()
      Overrides:
      toString in class Object
    • validate

      public static PluginLoader.Summary validate(File file) throws IllegalArgumentException
      Throws:
      IllegalArgumentException
    • parseDocument

      private static org.dom4j.Document parseDocument(@WillClose InputStream in) throws org.dom4j.DocumentException
      Throws:
      org.dom4j.DocumentException