hudson
Class ExtensionFinder

java.lang.Object
  extended by hudson.ExtensionFinder
All Implemented Interfaces:
ExtensionPoint
Direct Known Subclasses:
CLIRegisterer, ExtensionFinder.GuiceFinder, ExtensionFinder.Sezpoz

public abstract class ExtensionFinder
extends Object
implements ExtensionPoint

Discovers the implementations of an extension point.

This extension point allows you to write your implementations of ExtensionPoints in arbitrary DI containers, and have Hudson discover them.

ExtensionFinder itself is an extension point, but to avoid infinite recursion, Jenkins discovers ExtensionFinders through ExtensionFinder.Sezpoz and that alone.

Since:
1.286
Author:
Kohsuke Kawaguchi
See Also:
ExtensionFilter

Nested Class Summary
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.
 
Nested classes/interfaces inherited from interface hudson.ExtensionPoint
ExtensionPoint.LegacyInstancesAreScopedToHudson
 
Constructor Summary
ExtensionFinder()
           
 
Method Summary
<T> Collection<ExtensionComponent<T>>
_find(Class<T> type, Hudson hudson)
          A pointless function to work around what appears to be a HotSpot problem.
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.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

ExtensionFinder

public ExtensionFinder()
Method Detail

findExtensions

@Restricted(value=org.kohsuke.accmod.restrictions.NoExternalUse.class)
public <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.


isRefreshable

public boolean isRefreshable()
Returns true if this extension finder supports the refresh() operation.


refresh

public abstract ExtensionComponentSet refresh()
                                       throws ExtensionRefreshException
Rebuilds the internal index, if any, so that future 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 ExtensionComponents, and only instantiate those that are new. Otherwise this will break the singleton semantics of various objects, such as Descriptors.

The behaviour is undefined if isRefreshable() is returning false.

Returns:
never null
Throws:
ExtensionRefreshException
Since:
1.442
See Also:
isRefreshable()

find

public abstract <T> Collection<ExtensionComponent<T>> find(Class<T> type,
                                                           Hudson jenkins)
Discover extensions of the given type.

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.

Type Parameters:
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.
Parameters:
jenkins - Jenkins whose behalf this extension finder is performing lookup.
Returns:
Can be empty but never null.
Since:
1.356 Older implementations provide findExtensions(Class,Hudson)

_find

public <T> Collection<ExtensionComponent<T>> _find(Class<T> type,
                                                   Hudson hudson)
A pointless function to work around what appears to be a HotSpot problem. See JENKINS-5756 and bug 6933067 on BugParade for more details.


scout

public void scout(Class extensionType,
                  Hudson hudson)
Performs class initializations without creating instances. If two threads try to initialize classes in the opposite order, a dead lock will ensue, and we can get into a similar situation with ExtensionFinders.

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 http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6459208 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-2013. All Rights Reserved.