From 3e1bc969f4eca2ae243f35e72a0a577a40cf2a0c Mon Sep 17 00:00:00 2001 From: Carlos Sanchez Date: Mon, 9 May 2016 16:34:26 +0200 Subject: [PATCH] [JENKINS-34683] Do not print stack trace if plugin is missing dependencies (#2048) [JENKINS-34683] - Do not print stack trace if plugin is missing dependencies --- core/src/main/java/hudson/PluginManager.java | 7 +++ core/src/main/java/hudson/PluginWrapper.java | 7 ++- .../main/java/hudson/model/UpdateCenter.java | 5 ++ .../jenkins/MissingDependencyException.java | 60 +++++++++++++++++++ 4 files changed, 76 insertions(+), 3 deletions(-) create mode 100644 core/src/main/java/jenkins/MissingDependencyException.java diff --git a/core/src/main/java/hudson/PluginManager.java b/core/src/main/java/hudson/PluginManager.java index b3974a5b74..a55d8f04c8 100644 --- a/core/src/main/java/hudson/PluginManager.java +++ b/core/src/main/java/hudson/PluginManager.java @@ -48,6 +48,7 @@ import hudson.util.VersionNumber; import hudson.util.XStream2; import jenkins.ClassLoaderReflectionToolkit; import jenkins.InitReactorRunner; +import jenkins.MissingDependencyException; import jenkins.RestartRequiredException; import jenkins.YesNoMaybe; import jenkins.install.InstallState; @@ -413,6 +414,12 @@ public abstract class PluginManager extends AbstractModelObject implements OnMas try { p.resolvePluginDependencies(); strategy.load(p); + } catch (MissingDependencyException e) { + failedPlugins.add(new FailedPlugin(p.getShortName(), e)); + activePlugins.remove(p); + plugins.remove(p); + LOGGER.log(Level.SEVERE, "Failed to install {0}: {1}", new Object[] { p.getShortName(), e.getMessage() }); + return; } catch (IOException e) { failedPlugins.add(new FailedPlugin(p.getShortName(), e)); activePlugins.remove(p); diff --git a/core/src/main/java/hudson/PluginWrapper.java b/core/src/main/java/hudson/PluginWrapper.java index cdfecff910..b11662f134 100644 --- a/core/src/main/java/hudson/PluginWrapper.java +++ b/core/src/main/java/hudson/PluginWrapper.java @@ -28,6 +28,7 @@ import com.google.common.collect.ImmutableSet; import hudson.PluginManager.PluginInstanceStore; import hudson.model.Api; import hudson.model.ModelObject; +import jenkins.MissingDependencyException; import jenkins.YesNoMaybe; import jenkins.model.Jenkins; import hudson.model.UpdateCenter; @@ -513,14 +514,14 @@ public class PluginWrapper implements Comparable, ModelObject { * thrown if one or several mandatory dependencies doesn't exists. */ /*package*/ void resolvePluginDependencies() throws IOException { - List missingDependencies = new ArrayList(); + List missingDependencies = new ArrayList<>(); // make sure dependencies exist for (Dependency d : dependencies) { if (parent.getPlugin(d.shortName) == null) - missingDependencies.add(d.toString()); + missingDependencies.add(d); } if (!missingDependencies.isEmpty()) - throw new IOException("Dependency "+Util.join(missingDependencies, ", ")+" doesn't exist"); + throw new MissingDependencyException(this.shortName, missingDependencies); // add the optional dependencies that exists for (Dependency d : optionalDependencies) { diff --git a/core/src/main/java/hudson/model/UpdateCenter.java b/core/src/main/java/hudson/model/UpdateCenter.java index d8aaa4d524..4332ff0d0b 100644 --- a/core/src/main/java/hudson/model/UpdateCenter.java +++ b/core/src/main/java/hudson/model/UpdateCenter.java @@ -52,6 +52,7 @@ import hudson.util.IOException2; import hudson.util.IOUtils; import hudson.util.PersistedList; import hudson.util.XStream2; +import jenkins.MissingDependencyException; import jenkins.RestartRequiredException; import jenkins.install.InstallUtil; import jenkins.model.Jenkins; @@ -1518,6 +1519,10 @@ public class UpdateCenter extends AbstractModelObject implements Saveable, OnMas status = e; if (status.isSuccess()) onSuccess(); requiresRestart |= status.requiresRestart(); + } catch (MissingDependencyException e) { + LOGGER.log(Level.SEVERE, "Failed to install {0}: {1}", new Object[] { getName(), e.getMessage() }); + status = new Failure(e); + error = e; } catch (Throwable e) { LOGGER.log(Level.SEVERE, "Failed to install "+getName(),e); status = new Failure(e); diff --git a/core/src/main/java/jenkins/MissingDependencyException.java b/core/src/main/java/jenkins/MissingDependencyException.java new file mode 100644 index 0000000000..c1b25673ef --- /dev/null +++ b/core/src/main/java/jenkins/MissingDependencyException.java @@ -0,0 +1,60 @@ +/* + * The MIT License + * + * Copyright (c) 2016, CloudBees, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package jenkins; + +import java.io.IOException; +import java.util.List; + +import hudson.PluginWrapper.Dependency; +import hudson.Util; + +/** + * Exception thrown if plugin resolution fails due to missing dependencies + * + * @author Carlos Sanchez + * @since TODO + * + */ +public class MissingDependencyException extends IOException { + + private String pluginShortName; + private List missingDependencies; + + public MissingDependencyException(String pluginShortName, List missingDependencies) { + super("One or more dependencies could not be resolved for " + pluginShortName + " : " + + Util.join(missingDependencies, ", ")); + this.pluginShortName = pluginShortName; + this.missingDependencies = missingDependencies; + } + + public List getMissingDependencies() { + return missingDependencies; + } + + public String getPluginShortName() { + return pluginShortName; + } + +}