Package edu.umd.cs.findbugs
Class PluginLoader
- java.lang.Object
-
- edu.umd.cs.findbugs.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
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description static class
PluginLoader.Summary
-
Field Summary
Fields Modifier and Type Field Description (package private) boolean
cannotDisable
private java.lang.ClassLoader
classLoader
private java.lang.ClassLoader
classLoaderForResources
private boolean
corePlugin
private java.util.List<java.net.URLClassLoader>
createdClassLoaders
(package private) boolean
initialPlugin
private java.lang.String
jarName
(package private) static boolean
lazyInitialization
private java.net.URL
loadedFrom
private java.net.URI
loadedFromUri
(package private) static java.util.HashSet<java.lang.String>
loadedPluginIds
private static org.slf4j.Logger
LOG
private static int
nextUnknownId
private boolean
optionalPlugin
(package private) java.lang.String
parentId
plugin Id for parent plugin(package private) static java.util.LinkedList<PluginLoader>
partiallyInitialized
private Plugin
plugin
private static java.lang.String
XPATH_PLUGIN_PLUGINID
private static java.lang.String
XPATH_PLUGIN_PROVIDER
private static java.lang.String
XPATH_PLUGIN_SHORT_DESCRIPTION
private static java.lang.String
XPATH_PLUGIN_WEBSITE
-
Constructor Summary
Constructors Modifier Constructor Description PluginLoader()
Deprecated.PluginLoader(boolean fake, java.net.URL url)
Deprecated.PluginLoader(java.net.URL url)
Deprecated.PluginLoader(java.net.URL url, java.lang.ClassLoader parent)
Deprecated.private
PluginLoader(java.net.URL url, java.net.URI uri, java.lang.ClassLoader parent, boolean isInitial, boolean optional)
Constructor.
-
Method Summary
All Methods Static Methods Instance Methods Concrete Methods Modifier and Type Method Description private static void
addClassPathFromManifest(java.net.URL url, java.util.List<java.net.URL> urls, java.util.jar.Manifest mf)
private void
addCollection(java.util.List<org.dom4j.Document> messageCollectionList, java.lang.String filename)
private java.net.URLClassLoader
buildURLClassLoader(java.net.URL[] urls)
Creates a newURLClassLoader
and adds it to the list of classloaders we need to close if we close the corresponding pluginprivate java.net.URLClassLoader
buildURLClassLoader(java.net.URL[] urls, java.lang.ClassLoader parent)
Creates a newURLClassLoader
and adds it to the list of classloaders we need to close if we close the corresponding pluginvoid
close()
Closes the class loaders created in thisPluginLoader
private static java.net.URL
computeCoreUrl()
private Plugin
constructMinimalPlugin(org.dom4j.Document pluginDescriptor, java.util.List<org.dom4j.Document> messageCollectionList)
private static java.net.URL[]
createClassloaderUrls(java.net.URL url)
Patch for issue 3429143: allow plugins load classes/resources from 3rd party jarsprivate static org.dom4j.Node
findMessageNode(java.util.List<org.dom4j.Document> messageCollectionList, java.lang.String xpath, java.lang.String missingMsg)
private static java.lang.String
findMessageText(java.util.List<org.dom4j.Document> messageCollectionList, java.lang.String xpath, java.lang.String missingMsg)
private static void
finishLazyInitialization()
private static java.lang.String
getChildText(org.dom4j.Node node, java.lang.String childName)
private static <T> java.lang.Class<? extends T>
getClass(java.lang.ClassLoader loader, java.lang.String className, java.lang.Class<T> type)
java.lang.ClassLoader
getClassLoader()
private DetectorFactorySelector
getConstraintSelector(org.dom4j.Element constraintElement, Plugin plugin, java.lang.String singleDetectorElementName)
static PluginLoader
getCorePluginLoader()
(package private) static java.net.URL
getCoreResource(java.lang.String name)
private static java.net.URL
getFindbugsJar()
private static java.lang.String
getJarName(java.net.URL url)
private java.util.List<org.dom4j.Document>
getMessageDocuments()
Plugin
getPlugin()
org.dom4j.Document
getPluginDescriptor()
static PluginLoader
getPluginLoader(java.net.URL url, java.lang.ClassLoader parent, boolean isInitial, boolean optional)
private static java.util.List<java.lang.String>
getPotentialMessageFiles()
java.net.URL
getResource(java.lang.String name)
Get a resource using the URLClassLoader classLoader.java.net.URI
getURI()
java.net.URL
getURL()
private static java.net.URL
getUrlBase(java.net.URL pluginListProperties)
private static java.io.File
guessManifest(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)boolean
hasParent()
private Plugin
init()
(package private) static void
installStandardPlugins()
(package private) static void
installUserInstalledPlugins()
(package private) static void
installWebStartPlugins()
boolean
isCorePlugin()
private <T> void
loadComponentPlugin(Plugin plugin, java.lang.Class<T> componentKind, java.lang.String componentClassname, java.lang.String filterId, boolean disabled, java.lang.String description, java.lang.String details, PropertyBundle properties)
private static void
loadCorePlugin()
static java.net.URL
loadFromFindBugsEtcDir(java.lang.String name)
static java.net.URL
loadFromFindBugsPluginDir(java.lang.String name)
private static void
loadInitialPlugin(java.net.URL u, boolean initial, boolean optional)
(package private) static void
loadInitialPlugins()
Plugin
loadPlugin()
Get the Plugin.private void
loadPluginComponents()
private static void
loadPlugins(java.io.File home)
private static void
loadPluginsInDir(java.io.File pluginDir, boolean optional)
private static java.util.Date
parseDate(java.lang.String releaseDate)
private static org.dom4j.Document
parseDocument(java.io.InputStream in)
private static java.net.URL
resourceFromFindbugsJar(java.lang.String slashedResourceName)
Try to load resource from JAR file of Findbugs core plugin.private static java.net.URL
resourceFromPlugin(java.net.URL u, java.lang.String args)
java.lang.String
toString()
private static java.net.URI
toUri(java.net.URL url)
static PluginLoader.Summary
validate(java.io.File file)
-
-
-
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
@Deprecated public PluginLoader(java.net.URL url, java.lang.ClassLoader parent) throws PluginException
Deprecated.Constructor.- Parameters:
url
- the URL of the plugin Jar fileparent
- the parent classloader- Throws:
PluginException
-
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 fileuri
-parent
- the parent classloaderisInitial
- is this plugin loaded from one of the standard locations for pluginsoptional
- 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 newURLClassLoader
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 newURLClassLoader
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 resourcesparent
- the parent class loader for delegation- Returns:
- a new
URLClassLoader
-
close
public void close() throws java.io.IOException
Closes the class loaders created in thisPluginLoader
- Specified by:
close
in interfacejava.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()
-
toUri
private static java.net.URI toUri(java.net.URL url) throws PluginException
- Throws:
PluginException
-
getJarName
private static java.lang.String getJarName(java.net.URL url)
-
getClassLoader
public java.lang.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 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)
-
getClass
private static <T> java.lang.Class<? extends T> getClass(java.lang.ClassLoader loader, @DottedClassName java.lang.String className, java.lang.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, java.util.List<org.dom4j.Document> messageCollectionList) throws DuplicatePluginIdError
- Throws:
DuplicatePluginIdError
-
getPluginDescriptor
public org.dom4j.Document getPluginDescriptor() throws PluginException
- Throws:
PluginException
-
getPotentialMessageFiles
private static java.util.List<java.lang.String> getPotentialMessageFiles()
-
getMessageDocuments
private java.util.List<org.dom4j.Document> getMessageDocuments() throws PluginException
- Throws:
PluginException
-
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)
-
getConstraintSelector
private DetectorFactorySelector getConstraintSelector(org.dom4j.Element constraintElement, Plugin plugin, java.lang.String singleDetectorElementName) throws PluginException
- Throws:
PluginException
-
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
-
getPluginLoader
public static PluginLoader getPluginLoader(java.net.URL url, java.lang.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(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 classjava.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, java.io.IOException
- Throws:
org.dom4j.DocumentException
java.io.IOException
-
-