Class PluginLoader

  • All Implemented Interfaces:
    java.lang.AutoCloseable

    public class PluginLoader
    extends java.lang.Object
    implements java.lang.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:
    Plugin, PluginException
    • Field Detail

      • XPATH_PLUGIN_SHORT_DESCRIPTION

        private static final java.lang.String XPATH_PLUGIN_SHORT_DESCRIPTION
        See Also:
        Constant Field Values
      • XPATH_PLUGIN_WEBSITE

        private static final java.lang.String XPATH_PLUGIN_WEBSITE
        See Also:
        Constant Field Values
      • XPATH_PLUGIN_PROVIDER

        private static final java.lang.String XPATH_PLUGIN_PROVIDER
        See Also:
        Constant Field Values
      • XPATH_PLUGIN_PLUGINID

        private static final java.lang.String XPATH_PLUGIN_PLUGINID
        See Also:
        Constant Field Values
      • LOG

        private static final org.slf4j.Logger LOG
      • lazyInitialization

        static boolean lazyInitialization
      • partiallyInitialized

        static java.util.LinkedList<PluginLoader> partiallyInitialized
      • nextUnknownId

        private static int nextUnknownId
      • classLoader

        private java.lang.ClassLoader classLoader
      • classLoaderForResources

        private final java.lang.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 java.net.URL loadedFrom
      • jarName

        private final java.lang.String jarName
      • loadedFromUri

        private final java.net.URI loadedFromUri
      • createdClassLoaders

        private java.util.List<java.net.URLClassLoader> createdClassLoaders
      • parentId

        java.lang.String parentId
        plugin Id for parent plugin
      • loadedPluginIds

        static java.util.HashSet<java.lang.String> loadedPluginIds
    • Constructor Detail

      • PluginLoader

        @Deprecated
        public PluginLoader​(java.net.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

        private PluginLoader​(@Nonnull
                             java.net.URL url,
                             java.net.URI uri,
                             java.lang.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,
                            java.net.URL url)
        Deprecated.
        Fake plugin.
    • Method Detail

      • hasParent

        public boolean hasParent()
      • finishLazyInitialization

        private static void finishLazyInitialization()
      • buildURLClassLoader

        private java.net.URLClassLoader buildURLClassLoader​(java.net.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 java.net.URLClassLoader buildURLClassLoader​(java.net.URL[] urls,
                                                            java.lang.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 java.io.IOException
        Closes the class loaders created in this PluginLoader
        Specified by:
        close in interface java.lang.AutoCloseable
        Throws:
        java.io.IOException - if a class loader fails to close, in that case the other classloaders won't be closed
      • createClassloaderUrls

        @Nonnull
        private static java.net.URL[] createClassloaderUrls​(@Nonnull
                                                            java.net.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
                                                     java.net.URL url,
                                                     @Nonnull
                                                     java.util.List<java.net.URL> urls,
                                                     @Nonnull
                                                     java.util.jar.Manifest mf)
                                              throws java.net.MalformedURLException
        Throws:
        java.net.MalformedURLException
      • guessManifest

        @CheckForNull
        private static java.io.File guessManifest​(@Nonnull
                                                  java.io.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 java.net.URL computeCoreUrl()
      • getURL

        public java.net.URL getURL()
      • getURI

        public java.net.URI getURI()
      • getJarName

        private static java.lang.String getJarName​(java.net.URL url)
      • getClassLoader

        public java.lang.ClassLoader getClassLoader()
      • getPlugin

        public Plugin getPlugin()
      • resourceFromPlugin

        private static java.net.URL resourceFromPlugin​(java.net.URL u,
                                                       java.lang.String args)
                                                throws java.net.MalformedURLException
        Throws:
        java.net.MalformedURLException
      • getResource

        public java.net.URL getResource​(java.lang.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 java.net.URL getCoreResource​(java.lang.String name)
      • resourceFromFindbugsJar

        @CheckForNull
        private static java.net.URL resourceFromFindbugsJar​(java.lang.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 java.net.URL getFindbugsJar()
                                            throws java.net.MalformedURLException
        Returns:
        URL of findbugs.jar, or null if found no jar file which contains FindBugs.class
        Throws:
        java.net.MalformedURLException
      • loadFromFindBugsEtcDir

        @CheckForNull
        public static java.net.URL loadFromFindBugsEtcDir​(java.lang.String name)
      • loadFromFindBugsPluginDir

        @CheckForNull
        public static java.net.URL loadFromFindBugsPluginDir​(java.lang.String name)
      • getPotentialMessageFiles

        private static java.util.List<java.lang.String> getPotentialMessageFiles()
      • loadComponentPlugin

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

        private static java.util.Date parseDate​(java.lang.String releaseDate)
      • addCollection

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

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

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

        private static java.lang.String getChildText​(org.dom4j.Node node,
                                                     java.lang.String childName)
                                              throws PluginException
        Throws:
        PluginException
      • getCorePluginLoader

        @Nonnull
        public static PluginLoader getCorePluginLoader()
      • isCorePlugin

        public boolean isCorePlugin()
      • installStandardPlugins

        static void installStandardPlugins()
      • loadPlugins

        private static void loadPlugins​(java.io.File home)
      • installUserInstalledPlugins

        static void installUserInstalledPlugins()
      • loadPluginsInDir

        private static void loadPluginsInDir​(java.io.File pluginDir,
                                             boolean optional)
      • loadInitialPlugins

        static void loadInitialPlugins()
      • loadCorePlugin

        private static void loadCorePlugin()
      • loadInitialPlugin

        private static void loadInitialPlugin​(java.net.URL u,
                                              boolean initial,
                                              boolean optional)
      • installWebStartPlugins

        static void installWebStartPlugins()
      • getUrlBase

        private static java.net.URL getUrlBase​(java.net.URL pluginListProperties)
                                        throws java.net.MalformedURLException
        Throws:
        java.net.MalformedURLException
      • toString

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

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

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