Skip to content

Commit

Permalink
[JENKINS-58302] call refresh on the Extension providers again
Browse files Browse the repository at this point in the history
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 11, 2024
1 parent 16a6575 commit ddf53dc
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 ddf53dc

Please sign in to comment.