public abstract class ExtensionFinder extends Object implements ExtensionPoint
This extension point allows you to write your implementations of ExtensionPoint
s
in arbitrary DI containers, and have Hudson discover them.
ExtensionFinder
itself is an extension point, but to avoid infinite recursion,
Jenkins discovers ExtensionFinder
s through ExtensionFinder.Sezpoz
and that alone.
ExtensionFilter
Modifier and Type | Class and Description |
---|---|
static class |
ExtensionFinder.DefaultGuiceExtensionAnnotation |
static class |
ExtensionFinder.GuiceExtensionAnnotation<T extends Annotation>
Captures information about the annotation that we use to mark Guice-instantiated components.
|
static class |
ExtensionFinder.GuiceFinder
Discovers components via sezpoz but instantiates them by using Guice.
|
static class |
ExtensionFinder.Sezpoz
The bootstrap implementation that looks for the
Extension marker. |
ExtensionPoint.LegacyInstancesAreScopedToHudson
Constructor and Description |
---|
ExtensionFinder() |
Modifier and Type | Method and Description |
---|---|
<T> Collection<ExtensionComponent<T>> |
_find(Class<T> type,
Hudson hudson)
Deprecated.
|
abstract <T> Collection<ExtensionComponent<T>> |
find(Class<T> type,
Hudson jenkins)
Discover extensions of the given type.
|
<T> Collection<T> |
findExtensions(Class<T> type,
Hudson hudson)
Deprecated.
as of 1.356
Use and implement
find(Class,Hudson) that allows us to put some metadata. |
boolean |
isRefreshable()
Returns true if this extension finder supports the
refresh() operation. |
abstract ExtensionComponentSet |
refresh()
Rebuilds the internal index, if any, so that future
find(Class, Hudson) calls
will discover components newly added to PluginManager.uberClassLoader . |
void |
scout(Class extensionType,
Hudson hudson)
Performs class initializations without creating instances.
|
@Restricted(value=org.kohsuke.accmod.restrictions.NoExternalUse.class) @Deprecated public <T> Collection<T> findExtensions(Class<T> type, Hudson hudson)
find(Class,Hudson)
that allows us to put some metadata.public boolean isRefreshable()
refresh()
operation.public abstract ExtensionComponentSet refresh() throws ExtensionRefreshException
find(Class, Hudson)
calls
will discover components newly added to PluginManager.uberClassLoader
.
The point of the refresh operation is not to disrupt instances of already loaded ExtensionComponent
s,
and only instantiate those that are new. Otherwise this will break the singleton semantics of various
objects, such as Descriptor
s.
The behaviour is undefined if isRefreshable()
is returning false.
ExtensionRefreshException
isRefreshable()
public abstract <T> Collection<ExtensionComponent<T>> find(Class<T> type, Hudson jenkins)
This method is called only once per the given type after all the plugins are loaded, so implementations need not worry about caching.
This method should return all the known components at the time of the call, including
those that are discovered later via refresh()
, even though those components
are separately returned in ExtensionComponentSet
.
T
- The type of the extension points. This is not bound to ExtensionPoint
because
of Descriptor
, which by itself doesn't implement ExtensionPoint
for
a historical reason.jenkins
- Jenkins whose behalf this extension finder is performing lookup.findExtensions(Class,Hudson)
@Deprecated public <T> Collection<ExtensionComponent<T>> _find(Class<T> type, Hudson hudson)
public void scout(Class extensionType, Hudson hudson)
ExtensionFinder
s.
That is, one thread can try to list extensions, which results in ExtensionFinder
loading and initializing classes. This happens inside a context of a lock, so that
another thread that tries to list the same extensions don't end up creating different
extension instances. So this activity locks extension list first, then class initialization next.
In the mean time, another thread can load and initialize a class, and that initialization can eventually results in listing up extensions, for example through static initializer. Such activity locks class initialization first, then locks extension list.
This inconsistent locking order results in a dead lock, you see.
So to reduce the likelihood, this method is called in prior to find(Class,Hudson)
invocation,
but from outside the lock. The implementation is expected to perform all the class initialization activities
from here.
See https://bugs.openjdk.java.net/browse/JDK-4993813 for how to force a class initialization. Also see http://kohsuke.org/2010/09/01/deadlock-that-you-cant-avoid/ for how class initialization can results in a dead lock.
Copyright © 2004–2021. All rights reserved.