From cb89cad9df70bc7f90f3e20160404909bf255cfc Mon Sep 17 00:00:00 2001 From: James Nord Date: Sun, 14 Apr 2024 08:29:51 +0100 Subject: [PATCH] [JENKINS-72998] call refresh on the Extension providers again (#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. --- core/src/main/java/hudson/ExtensionFinder.java | 3 +++ core/src/main/java/jenkins/model/Jenkins.java | 12 ++++++++++++ 2 files changed, 15 insertions(+) diff --git a/core/src/main/java/hudson/ExtensionFinder.java b/core/src/main/java/hudson/ExtensionFinder.java index 801735835c0f..7301bcc39988 100644 --- a/core/src/main/java/hudson/ExtensionFinder.java +++ b/core/src/main/java/hudson/ExtensionFinder.java @@ -298,9 +298,11 @@ protected Injector resolve() { } private void refreshExtensionAnnotations() { + LOGGER.finer(() -> "refreshExtensionAnnotations()"); for (ExtensionComponent ec : moduleFinder.find(GuiceExtensionAnnotation.class, Hudson.getInstance())) { GuiceExtensionAnnotation gea = ec.getInstance(); extensionAnnotations.put(gea.annotationType, gea); + LOGGER.finer(() -> "found " + gea.getClass()); } } @@ -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> delta = new ArrayList<>(); diff --git a/core/src/main/java/jenkins/model/Jenkins.java b/core/src/main/java/jenkins/model/Jenkins.java index 77e6f69ec875..b08ac6c8941d 100644 --- a/core/src/main/java/jenkins/model/Jenkins.java +++ b/core/src/main/java/jenkins/model/Jenkins.java @@ -2897,13 +2897,16 @@ public ExtensionList getExtensionList(String extensionType) throws ClassNotFound */ public void refreshExtensions() throws ExtensionRefreshException { ExtensionList finders = getExtensionList(ExtensionFinder.class); + LOGGER.finer(() -> "refreshExtensions " + finders); for (ExtensionFinder ef : finders) { if (!ef.isRefreshable()) throw new ExtensionRefreshException(ef + " doesn't support refresh"); } List fragments = new ArrayList<>(); + for (ExtensionFinder ef : finders) { + LOGGER.finer(() -> "searching " + ef); fragments.add(ef.refresh()); } ExtensionComponentSet delta = ExtensionComponentSet.union(fragments).filtered(); @@ -2912,12 +2915,21 @@ public void refreshExtensions() throws ExtensionRefreshException { List> 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); }