Skip to content

Commit

Permalink
[JENKINS-72998] call refresh on the Extension providers again (jenkin…
Browse files Browse the repository at this point in the history
…sci#9157)

[JENKINS-58302] call refresh on the Extension providers again

In the case the ExtensionFinder is itself extensible we refresh it again
to catch extensions that would be discovered by a newly installed
extension.

This seems a little overzerlous, as there is only the variant plugin
that I know of, however calling `Jenkins.get().refreshExtensions() from
any point in the `variant` plugin would seem to be a little bit
dangerous as it would call back into a place where the reactor is
already calling back from.
  • Loading branch information
jtnord committed Apr 14, 2024
1 parent ba61b88 commit cb89cad
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 0 deletions.
3 changes: 3 additions & 0 deletions core/src/main/java/hudson/ExtensionFinder.java
Original file line number Diff line number Diff line change
Expand Up @@ -298,9 +298,11 @@ protected Injector resolve() {
}

private void refreshExtensionAnnotations() {
LOGGER.finer(() -> "refreshExtensionAnnotations()");
for (ExtensionComponent<GuiceExtensionAnnotation> ec : moduleFinder.find(GuiceExtensionAnnotation.class, Hudson.getInstance())) {
GuiceExtensionAnnotation gea = ec.getInstance();
extensionAnnotations.put(gea.annotationType, gea);
LOGGER.finer(() -> "found " + gea.getClass());
}
}

Expand Down Expand Up @@ -328,6 +330,7 @@ public Injector getContainer() {
*/
@Override
public synchronized ExtensionComponentSet refresh() throws ExtensionRefreshException {
LOGGER.finer(() -> "refresh()");
refreshExtensionAnnotations();
// figure out newly discovered sezpoz components
List<IndexItem<?, Object>> delta = new ArrayList<>();
Expand Down
12 changes: 12 additions & 0 deletions core/src/main/java/jenkins/model/Jenkins.java
Original file line number Diff line number Diff line change
Expand Up @@ -2897,13 +2897,16 @@ public ExtensionList getExtensionList(String extensionType) throws ClassNotFound
*/
public void refreshExtensions() throws ExtensionRefreshException {
ExtensionList<ExtensionFinder> finders = getExtensionList(ExtensionFinder.class);
LOGGER.finer(() -> "refreshExtensions " + finders);
for (ExtensionFinder ef : finders) {
if (!ef.isRefreshable())
throw new ExtensionRefreshException(ef + " doesn't support refresh");
}

List<ExtensionComponentSet> fragments = new ArrayList<>();

for (ExtensionFinder ef : finders) {
LOGGER.finer(() -> "searching " + ef);
fragments.add(ef.refresh());
}
ExtensionComponentSet delta = ExtensionComponentSet.union(fragments).filtered();
Expand All @@ -2912,12 +2915,21 @@ public void refreshExtensions() throws ExtensionRefreshException {
List<ExtensionComponent<ExtensionFinder>> newFinders = new ArrayList<>(delta.find(ExtensionFinder.class));
while (!newFinders.isEmpty()) {
ExtensionFinder f = newFinders.remove(newFinders.size() - 1).getInstance();
LOGGER.finer(() -> "found new ExtensionFinder " + f);

ExtensionComponentSet ecs = ExtensionComponentSet.allOf(f).filtered();
newFinders.addAll(ecs.find(ExtensionFinder.class));
delta = ExtensionComponentSet.union(delta, ecs);
}

// we may not have found a new Extension finder but we may be using an extension finder that is extensible
// e.g. hudson.ExtensionFinder.GuiceFinder is extensible by GuiceExtensionAnnotation which is done by the variant plugin
// so lets give it one more chance.
for (ExtensionFinder ef : finders) {
LOGGER.finer(() -> "searching again in " + ef);
delta = ExtensionComponentSet.union(delta, ef.refresh().filtered());
}

for (ExtensionList el : extensionLists.values()) {
el.refresh(delta);
}
Expand Down

0 comments on commit cb89cad

Please sign in to comment.