ExtensionFinder.DefaultGuiceExtensionAnnotation, ExtensionFinder.GuiceExtensionAnnotation<T extends Annotation>, ExtensionFinder.GuiceFinder, ExtensionFinder.Sezpoz
|Constructor and Description|
|Modifier and Type||Method and Description|
Discover extensions of the given type.
Performs class initializations without creating instances.
public ExtensionComponentSet refresh()
ExtensionFinder.find(Class, Hudson)calls will discover components newly added to
The point of the refresh operation is not to disrupt instances of already loaded
and only instantiate those that are new. Otherwise this will break the singleton semantics of various
objects, such as
The behaviour is undefined if
ExtensionFinder.isRefreshable() is returning false.
SezPoz implements value-equality of
public <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
ExtensionFinder.refresh(), even though those components
are separately returned in
T- The type of the extension points. This is not bound to
Descriptor, which by itself doesn't implement
ExtensionPointfor a historical reason.
jenkins- Jenkins whose behalf this extension finder is performing lookup.
That is, one thread can try to list extensions, which results in
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
but from outside the lock. The implementation is expected to perform all the class initialization activities
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–2020. All rights reserved.