提交 4ed803ce 编写于 作者: J Jesse Glick 提交者: Oleg Nenashev

[JENKINS-36666] Defend against some fatal startup errors (#2453)

* [JENKINS-36666] Properly report the reason for a failed call to Task.getDisplayName.

* [JENKINS-36666] Even without passing fatal=false to @Initializer, recover gracefully from a LinkageError in a task.

* Comment.
上级 40687bdc
......@@ -465,7 +465,7 @@ public abstract class PluginManager extends AbstractModelObject implements OnMas
if(p.isActive())
activePlugins.add(p);
}
} catch (CycleDetectedException e) {
} catch (CycleDetectedException e) { // TODO this should be impossible, since we override reactOnCycle to not throw the exception
stop(); // disable all plugins since classloading from them can lead to StackOverflow
throw e; // let Hudson fail
}
......
......@@ -25,6 +25,8 @@ import java.util.logging.Level;
import java.util.logging.Logger;
import static java.util.logging.Level.SEVERE;
import org.kohsuke.accmod.Restricted;
import org.kohsuke.accmod.restrictions.NoExternalUse;
/**
* Executes the {@link Reactor} for the purpose of bootup.
......@@ -61,15 +63,15 @@ public class InitReactorRunner {
r.add(new ReactorListener() {
final Level level = Level.parse( Configuration.getStringConfigParameter("initLogLevel", "FINE") );
public void onTaskStarted(Task t) {
LOGGER.log(level,"Started "+t.getDisplayName());
LOGGER.log(level, "Started {0}", getDisplayName(t));
}
public void onTaskCompleted(Task t) {
LOGGER.log(level,"Completed "+t.getDisplayName());
LOGGER.log(level, "Completed {0}", getDisplayName(t));
}
public void onTaskFailed(Task t, Throwable err, boolean fatal) {
LOGGER.log(SEVERE, "Failed "+t.getDisplayName(),err);
LOGGER.log(SEVERE, "Failed " + getDisplayName(t), err);
}
public void onAttained(Milestone milestone) {
......@@ -86,6 +88,17 @@ public class InitReactorRunner {
return new ReactorListener.Aggregator(r);
}
/** Like {@link Task#getDisplayName} but more robust. */
@Restricted(NoExternalUse.class)
public static String getDisplayName(Task t) {
try {
return t.getDisplayName();
} catch (RuntimeException | Error x) {
LOGGER.log(Level.WARNING, "failed to find displayName of " + t, x);
return t.toString();
}
}
/**
* Called when the init milestone is attained.
*/
......
......@@ -987,7 +987,7 @@ public class Jenkins extends AbstractCIBase implements DirectlyModifiableTopLeve
if (is!=null && is.skipInitTask(task)) return;
ACL.impersonate(ACL.SYSTEM); // full access in the initialization thread
String taskName = task.getDisplayName();
String taskName = InitReactorRunner.getDisplayName(task);
Thread t = Thread.currentThread();
String name = t.getName();
......@@ -999,11 +999,24 @@ public class Jenkins extends AbstractCIBase implements DirectlyModifiableTopLeve
if(LOG_STARTUP_PERFORMANCE)
LOGGER.info(String.format("Took %dms for %s by %s",
System.currentTimeMillis()-start, taskName, name));
} catch (Exception | Error x) {
if (containsLinkageError(x)) {
LOGGER.log(Level.WARNING, taskName + " failed perhaps due to plugin dependency issues", x);
} else {
throw x;
}
} finally {
t.setName(name);
SecurityContextHolder.clearContext();
}
}
private boolean containsLinkageError(Throwable x) {
if (x instanceof LinkageError) {
return true;
}
Throwable x2 = x.getCause();
return x2 != null && containsLinkageError(x2);
}
};
new InitReactorRunner() {
......@@ -3022,15 +3035,15 @@ public class Jenkins extends AbstractCIBase implements DirectlyModifiableTopLeve
final Level level = Level.parse(Configuration.getStringConfigParameter("termLogLevel", "FINE"));
public void onTaskStarted(Task t) {
LOGGER.log(level, "Started " + t.getDisplayName());
LOGGER.log(level, "Started {0}", InitReactorRunner.getDisplayName(t));
}
public void onTaskCompleted(Task t) {
LOGGER.log(level, "Completed " + t.getDisplayName());
LOGGER.log(level, "Completed {0}", InitReactorRunner.getDisplayName(t));
}
public void onTaskFailed(Task t, Throwable err, boolean fatal) {
LOGGER.log(SEVERE, "Failed " + t.getDisplayName(), err);
LOGGER.log(SEVERE, "Failed " + InitReactorRunner.getDisplayName(t), err);
}
public void onAttained(Milestone milestone) {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册