From 53d1e20f6252228c8fbe58c0fa24e92937122fa2 Mon Sep 17 00:00:00 2001 From: Jesse Glick Date: Thu, 2 May 2013 14:55:06 -0400 Subject: [PATCH] If an optional component cannot be loaded, print a polite one-line message, not a big scary stack trace. (To reproduce: BuildNowTextPropertyTest from cloudbees-template warns about FolderProxyGroupContainer.) --- .../src/main/java/hudson/ExtensionFinder.java | 31 ++++++++++++++----- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/core/src/main/java/hudson/ExtensionFinder.java b/core/src/main/java/hudson/ExtensionFinder.java index 72169a1791..c63c948898 100644 --- a/core/src/main/java/hudson/ExtensionFinder.java +++ b/core/src/main/java/hudson/ExtensionFinder.java @@ -413,7 +413,14 @@ public abstract class ExtensionFinder implements ExtensionPoint { * This is necessary as a failure to load one plugin shouldn't fail the startup of the entire Jenkins. * Instead, we should just drop the failing plugins. */ - public static final Scope FAULT_TOLERANT_SCOPE = new Scope() { + public static final Scope FAULT_TOLERANT_SCOPE = new FaultTolerantScope(true); + private static final Scope QUIET_FAULT_TOLERANT_SCOPE = new FaultTolerantScope(false); + + private static final class FaultTolerantScope implements Scope { + private final boolean verbose; + FaultTolerantScope(boolean verbose) { + this.verbose = verbose; + } public Provider scope(final Key key, final Provider unscoped) { final Provider base = Scopes.SINGLETON.scope(key,unscoped); return new Provider() { @@ -421,13 +428,21 @@ public abstract class ExtensionFinder implements ExtensionPoint { try { return base.get(); } catch (Exception e) { - LOGGER.log(Level.WARNING,"Failed to instantiate. Skipping this component",e); + error(key, e); return null; } catch (LinkageError e) { - LOGGER.log(Level.WARNING,"Failed to instantiate. Skipping this component",e); + error(key, e); return null; } } + void error(Key key, Throwable x) { + if (verbose) { + LOGGER.log(Level.WARNING, "Failed to instantiate " + key + "; skipping this component", x); + } else { + LOGGER.log(Level.WARNING, "Failed to instantiate optional component {0}; skipping", key.getTypeLiteral()); + LOGGER.log(Level.FINE, key.toString(), x); + } + } }; } }; @@ -484,16 +499,18 @@ public abstract class ExtensionFinder implements ExtensionPoint { for (final IndexItem item : index) { id++; + boolean optional = isOptional(item.annotation()); try { AnnotatedElement e = item.element(); Annotation a = item.annotation(); if (!isActive(a,e)) continue; + Scope scope = optional ? QUIET_FAULT_TOLERANT_SCOPE : FAULT_TOLERANT_SCOPE; if (e instanceof Class) { Key key = Key.get((Class)e); resolve((Class)e); annotations.put(key,a); - bind(key).in(FAULT_TOLERANT_SCOPE); + bind(key).in(scope); } else { Class extType; if (e instanceof Field) { @@ -513,15 +530,15 @@ public abstract class ExtensionFinder implements ExtensionPoint { public Object get() { return instantiate(item); } - }).in(FAULT_TOLERANT_SCOPE); + }).in(scope); } } catch (LinkageError e) { // sometimes the instantiation fails in an indirect classloading failure, // which results in a LinkageError - LOGGER.log(isOptional(item.annotation()) ? Level.FINE : Level.WARNING, + LOGGER.log(optional ? Level.FINE : Level.WARNING, "Failed to load "+item.className(), e); } catch (InstantiationException e) { - LOGGER.log(isOptional(item.annotation()) ? Level.FINE : Level.WARNING, + LOGGER.log(optional ? Level.FINE : Level.WARNING, "Failed to load "+item.className(), e); } }