提交 42de07bb 编写于 作者: J Jesse Glick

[FIXED JENKINS-24696] Cannot assume that Jenkins.getInstance() != null when we...

[FIXED JENKINS-24696] Cannot assume that Jenkins.getInstance() != null when we are running a boot failure script.
上级 09722a98
......@@ -38,6 +38,6 @@ import static hudson.init.InitMilestone.*;
public class GroovyInitScript {
@Initializer(after=JOB_LOADED)
public static void init(Jenkins j) {
new GroovyHookScript("init").run();
new GroovyHookScript("init", j.servletContext, j.getRootDir(), j.getPluginManager().uberClassLoader).run();
}
}
......@@ -40,7 +40,10 @@ public abstract class BootFailure extends ErrorObject {
LOGGER.log(Level.SEVERE, "Failed to initialize Jenkins",this);
WebApp.get(context).setApp(this);
new GroovyHookScript("boot-failure")
if (home == null) {
return;
}
new GroovyHookScript("boot-failure", context, home, BootFailure.class.getClassLoader())
.bind("exception",this)
.bind("home",home)
.bind("servletContext", context)
......
......@@ -3,8 +3,6 @@ package jenkins.util.groovy;
import groovy.lang.Binding;
import groovy.lang.GroovyCodeSource;
import groovy.lang.GroovyShell;
import jenkins.model.Jenkins;
import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
......@@ -12,9 +10,10 @@ import java.net.URL;
import java.util.Arrays;
import java.util.Set;
import java.util.TreeSet;
import java.util.logging.Logger;
import static java.util.logging.Level.WARNING;
import java.util.logging.Logger;
import javax.annotation.Nonnull;
import javax.servlet.ServletContext;
/**
* A collection of Groovy scripts that are executed as various hooks.
......@@ -40,9 +39,15 @@ import static java.util.logging.Level.WARNING;
public class GroovyHookScript {
private final String hook;
private final Binding bindings = new Binding();
private final ServletContext servletContext;
private final File home;
private final ClassLoader loader;
public GroovyHookScript(String hook) {
public GroovyHookScript(String hook, @Nonnull ServletContext servletContext, @Nonnull File home, @Nonnull ClassLoader loader) {
this.hook = hook;
this.servletContext = servletContext;
this.home = home;
this.loader = loader;
}
public GroovyHookScript bind(String name, Object o) {
......@@ -55,23 +60,22 @@ public class GroovyHookScript {
}
public void run() {
Jenkins j = Jenkins.getInstance();
final String hookGroovy = hook+".groovy";
final String hookGroovyD = hook+".groovy.d";
try {
URL bundled = j.servletContext.getResource("/WEB-INF/"+ hookGroovy);
URL bundled = servletContext.getResource("/WEB-INF/"+ hookGroovy);
execute(bundled);
} catch (IOException e) {
LOGGER.log(WARNING, "Failed to execute /WEB-INF/"+hookGroovy,e);
}
Set<String> resources = j.servletContext.getResourcePaths("/WEB-INF/"+ hookGroovyD +"/");
Set<String> resources = servletContext.getResourcePaths("/WEB-INF/"+ hookGroovyD +"/");
if (resources!=null) {
// sort to execute them in a deterministic order
for (String res : new TreeSet<String>(resources)) {
try {
URL bundled = j.servletContext.getResource(res);
URL bundled = servletContext.getResource(res);
execute(bundled);
} catch (IOException e) {
LOGGER.log(WARNING, "Failed to execute " + res, e);
......@@ -79,10 +83,10 @@ public class GroovyHookScript {
}
}
File script = new File(j.getRootDir(), hookGroovy);
File script = new File(home, hookGroovy);
execute(script);
File scriptD = new File(j.getRootDir(), hookGroovyD);
File scriptD = new File(home, hookGroovyD);
if (scriptD.isDirectory()) {
File[] scripts = scriptD.listFiles(new FileFilter() {
public boolean accept(File f) {
......@@ -129,7 +133,7 @@ public class GroovyHookScript {
* Can be used to customize the environment in which the script runs.
*/
protected GroovyShell createShell() {
return new GroovyShell(Jenkins.getInstance().getPluginManager().uberClassLoader, bindings);
return new GroovyShell(loader, bindings);
}
private static final Logger LOGGER = Logger.getLogger(GroovyHookScript.class.getName());
......
......@@ -8,6 +8,7 @@ import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
......@@ -19,6 +20,7 @@ import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.jvnet.hudson.test.HudsonHomeLoader;
import org.jvnet.hudson.test.Issue;
import org.jvnet.hudson.test.JenkinsRule;
import org.jvnet.hudson.test.TestEnvironment;
import org.jvnet.hudson.test.TestExtension;
......@@ -34,6 +36,7 @@ public class BootFailureTest {
public TemporaryFolder tmpDir = new TemporaryFolder();
static boolean makeBootFail = true;
static WebAppMain wa;
static class CustomRule extends JenkinsRule {
@Override
......@@ -46,7 +49,7 @@ public class BootFailureTest {
@Override
public Hudson newHudson() throws Exception {
ServletContext ws = createWebServer();
WebAppMain wa = new WebAppMain() {
wa = new WebAppMain() {
@Override
public WebAppMain.FileAndDescription getHomeDir(ServletContextEvent event) {
try {
......@@ -130,6 +133,30 @@ public class BootFailureTest {
return FileUtils.readLines(BootFailure.getBootFailureFile(home)).size();
}
@Issue("JENKINS-24696")
@Test
public void interruptedStartup() throws Exception {
final File home = tmpDir.newFolder();
j.with(new HudsonHomeLoader() {
@Override
public File allocate() throws Exception {
return home;
}
});
File d = new File(home, "boot-failure.groovy.d");
d.mkdirs();
FileUtils.write(new File(d, "1.groovy"), "hudson.util.BootFailureTest.runRecord << '1'");
j.newHudson();
assertEquals(Collections.singletonList("1"), runRecord);
}
@TestExtension("interruptedStartup")
public static class PauseBoot extends ItemListener {
@Override
public void onLoaded() {
wa.contextDestroyed(null);
}
}
// to be set by the script
public static Exception problem;
public static List<String> runRecord = new ArrayList<String>();
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册