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.)
This commit is contained in:
Jesse Glick committed 2013-05-02 14:55:06 -04:00
1 parent 21bf5c45d4
commit 53d1e20f62
1 file changed
+24 -7
+24 -7
View File
@@ -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 <T> Provider<T> scope(final Key<T> key, final Provider<T> unscoped) {
final Provider<T> base = Scopes.SINGLETON.scope(key,unscoped);
return new Provider<T>() {
@@ -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<T> 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<?,Object> 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);
}
}