diff --git a/changelog.html b/changelog.html index 721f5e71e5..154d84209c 100644 --- a/changelog.html +++ b/changelog.html @@ -63,6 +63,9 @@ Upcoming changes (issue 22262)
  • identity.key, used to secure some communications with Jenkins, now stored encrypted with the master key. +
  • + When dynamically loading a plugin which another loaded plugin already had an optional dependency on, class loading errors could result before restart. + (issue 19976)
  • Memory leaks in the old data monitor. (issue 19544) diff --git a/core/src/main/java/hudson/ClassicPluginStrategy.java b/core/src/main/java/hudson/ClassicPluginStrategy.java index 18cbb3e0fa..f321605afe 100644 --- a/core/src/main/java/hudson/ClassicPluginStrategy.java +++ b/core/src/main/java/hudson/ClassicPluginStrategy.java @@ -377,15 +377,6 @@ public class ClassicPluginStrategy implements PluginStrategy { plugin.getPlugin().start(); } - /** - * Called when a plugin is deployed, and there is a plugin optionally depending on that plugin. - * The class loader of the existing depending plugin should be updated - * to load classes from the newly deployed plugin. - * - * @param depender the plugin to update its class loader - * @param dependee - * @see hudson.PluginStrategy#updateDependency(hudson.PluginWrapper, hudson.PluginWrapper) - */ @Override public void updateDependency(PluginWrapper depender, PluginWrapper dependee) { DependencyClassLoader classLoader = findAncestorDependencyClassLoader(depender.classLoader); diff --git a/core/src/main/java/hudson/PluginManager.java b/core/src/main/java/hudson/PluginManager.java index d77f12087d..17900b6309 100644 --- a/core/src/main/java/hudson/PluginManager.java +++ b/core/src/main/java/hudson/PluginManager.java @@ -464,7 +464,11 @@ public abstract class PluginManager extends AbstractModelObject implements OnMas if (d.shortName.equals(p.getShortName())) { // this plugin depends on the newly loaded one! // recalculate dependencies! - getPluginStrategy().updateDependency(depender, p); + try { + getPluginStrategy().updateDependency(depender, p); + } catch (AbstractMethodError x) { + LOGGER.log(WARNING, "{0} does not yet implement updateDependency", getPluginStrategy().getClass()); + } break; } } diff --git a/core/src/main/java/hudson/PluginStrategy.java b/core/src/main/java/hudson/PluginStrategy.java index d61e23732a..e599812e4a 100644 --- a/core/src/main/java/hudson/PluginStrategy.java +++ b/core/src/main/java/hudson/PluginStrategy.java @@ -79,10 +79,12 @@ public interface PluginStrategy extends ExtensionPoint { List> findComponents(Class type, Hudson hudson); /** - * Called when a plugin that is depended by another plugin is newly deployed. - * + * Called when a plugin is installed, but there was already a plugin installed which optionally depended on that plugin. + * The class loader of the existing depending plugin should be updated + * to load classes from the newly installed plugin. * @param depender plugin depending on dependee. * @param dependee newly loaded plugin. + * @since 1.557 */ void updateDependency(PluginWrapper depender, PluginWrapper dependee); } diff --git a/test/src/test/java/hudson/PluginManagerTest.java b/test/src/test/java/hudson/PluginManagerTest.java index b068598c94..4f50aec47f 100644 --- a/test/src/test/java/hudson/PluginManagerTest.java +++ b/test/src/test/java/hudson/PluginManagerTest.java @@ -33,13 +33,6 @@ import hudson.model.UpdateSite; import hudson.scm.SubversionSCM; import hudson.util.FormValidation; import hudson.util.PersistedList; -import org.apache.commons.io.FileUtils; -import org.apache.tools.ant.filters.StringInputStream; -import org.jvnet.hudson.test.HudsonTestCase; -import org.jvnet.hudson.test.Url; -import org.jvnet.hudson.test.recipes.WithPlugin; -import org.jvnet.hudson.test.recipes.WithPluginManager; - import java.io.File; import java.lang.reflect.Method; import java.net.URL; @@ -47,6 +40,13 @@ import java.net.URLClassLoader; import java.util.Collections; import java.util.List; import java.util.concurrent.Future; +import org.apache.commons.io.FileUtils; +import org.apache.tools.ant.filters.StringInputStream; +import org.jvnet.hudson.test.Bug; +import org.jvnet.hudson.test.HudsonTestCase; +import org.jvnet.hudson.test.Url; +import org.jvnet.hudson.test.recipes.WithPlugin; +import org.jvnet.hudson.test.recipes.WithPluginManager; /** * @author Kohsuke Kawaguchi @@ -310,6 +310,7 @@ public class PluginManagerTest extends HudsonTestCase { * * @throws Exception */ + @Bug(19976) public void testInstallDependedPluginWithoutRestart() throws Exception { // Load depender. {