diff --git a/core/pom.xml b/core/pom.xml index d408b79d3bf2a98470ad7d87c64275bc0cae766c..4ff8e34e4b27df992c3424dea4c4112fb3396022 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -222,7 +222,7 @@ org.kohsuke.stapler stapler - 1.42 + 1.43 org.kohsuke diff --git a/core/src/main/java/hudson/WebAppMain.java b/core/src/main/java/hudson/WebAppMain.java index b6c84bb74510a819941838de1f449e7237477e57..e12a1fb2e76417cafcec323ca79c28843ce79421 100644 --- a/core/src/main/java/hudson/WebAppMain.java +++ b/core/src/main/java/hudson/WebAppMain.java @@ -6,11 +6,7 @@ import hudson.model.Hudson; import hudson.model.User; import hudson.triggers.Trigger; import hudson.triggers.SafeTimerTask; -import hudson.util.IncompatibleServletVersionDetected; -import hudson.util.IncompatibleVMDetected; -import hudson.util.RingBufferLogHandler; -import hudson.util.NoHomeDir; -import hudson.util.InsufficientPermissionDetected; +import hudson.util.*; import javax.naming.Context; import javax.naming.InitialContext; @@ -42,7 +38,7 @@ public class WebAppMain implements ServletContextListener { * Creates the sole instance of {@link Hudson} and register it to the {@link ServletContext}. */ public void contextInitialized(ServletContextEvent event) { - ServletContext context = event.getServletContext(); + final ServletContext context = event.getServletContext(); // quick check to see if we (seem to) have enough permissions to run. (see #719) JVM jvm; @@ -56,7 +52,7 @@ public class WebAppMain implements ServletContextListener { installLogger(); - File home = getHomeDir(event).getAbsoluteFile(); + final File home = getHomeDir(event).getAbsoluteFile(); home.mkdirs(); System.out.println("hudson home directory: "+home); @@ -100,43 +96,47 @@ public class WebAppMain implements ServletContextListener { } } - - try { - context.setAttribute("app",new Hudson(home,context)); - } catch( IOException e ) { - throw new Error(e); - } - - // set the version - Properties props = new Properties(); - try { - InputStream is = getClass().getResourceAsStream("hudson-version.properties"); - if(is!=null) - props.load(is); - } catch (IOException e) { - e.printStackTrace(); // if the version properties is missing, that's OK. - } - String ver = props.getProperty("version"); - if(ver==null) ver="?"; - Hudson.VERSION = ver; - context.setAttribute("version",ver); - - if(ver.equals("?")) - Hudson.RESOURCE_PATH = ""; - else - Hudson.RESOURCE_PATH = "/static/"+Util.getDigestOf(ver).substring(0,8); - - Trigger.init(); // start running trigger - - // trigger the loading of changelogs in the background, - // but give the system 10 seconds so that the first page - // can be served quickly - Trigger.timer.schedule(new SafeTimerTask() { - public void doRun() { - User.get("nobody").getBuilds(); + context.setAttribute("app",new HudsonIsLoading()); + + new Thread("hudson initialization thread") { + public void run() { + try { + context.setAttribute("app",new Hudson(home,context)); + } catch( IOException e ) { + throw new Error(e); + } + + // set the version + Properties props = new Properties(); + try { + InputStream is = getClass().getResourceAsStream("hudson-version.properties"); + if(is!=null) + props.load(is); + } catch (IOException e) { + e.printStackTrace(); // if the version properties is missing, that's OK. + } + String ver = props.getProperty("version"); + if(ver==null) ver="?"; + Hudson.VERSION = ver; + context.setAttribute("version",ver); + + if(ver.equals("?")) + Hudson.RESOURCE_PATH = ""; + else + Hudson.RESOURCE_PATH = "/static/"+Util.getDigestOf(ver).substring(0,8); + + Trigger.init(); // start running trigger + + // trigger the loading of changelogs in the background, + // but give the system 10 seconds so that the first page + // can be served quickly + Trigger.timer.schedule(new SafeTimerTask() { + public void doRun() { + User.get("nobody").getBuilds(); + } + }, 1000*10); } - }, 1000*10); - + }.start(); } /** diff --git a/core/src/main/java/hudson/model/Hudson.java b/core/src/main/java/hudson/model/Hudson.java index 6bcccbfc8f48faa325dfb0eb0305fd8106719bbe..808999f85b5cf9bc40898ab199c0d5da842fe260 100644 --- a/core/src/main/java/hudson/model/Hudson.java +++ b/core/src/main/java/hudson/model/Hudson.java @@ -41,13 +41,7 @@ import hudson.tasks.Publisher; import hudson.triggers.Trigger; import hudson.triggers.TriggerDescriptor; import hudson.triggers.Triggers; -import hudson.util.ClockDifference; -import hudson.util.CopyOnWriteList; -import hudson.util.CopyOnWriteMap; -import hudson.util.DaemonThreadFactory; -import hudson.util.FormFieldValidator; -import hudson.util.MultipartFormDataParser; -import hudson.util.XStream2; +import hudson.util.*; import org.apache.commons.fileupload.FileItem; import org.apache.commons.fileupload.disk.DiskFileItemFactory; import org.apache.commons.fileupload.servlet.ServletFileUpload; @@ -1476,9 +1470,23 @@ public final class Hudson extends View implements ItemGroup, Node if(!Hudson.adminCheck(req,rsp)) return; - load(); - User.reload(); + // engage "loading ..." UI and then run the actual task in a separate thread + final ServletContext context = req.getServletContext(); + context.setAttribute("app",new HudsonIsLoading()); + rsp.sendRedirect2(req.getContextPath()+"/"); + + new Thread("Hudson config reload thread") { + public void run() { + try { + load(); + User.reload(); + context.setAttribute("app",Hudson.this); + } catch (IOException e) { + LOGGER.log(Level.SEVERE,"Failed to reload Hudson config",e); + } + } + }.start(); } public boolean isPluginUploaded() { diff --git a/core/src/main/java/hudson/util/HudsonIsLoading.java b/core/src/main/java/hudson/util/HudsonIsLoading.java new file mode 100644 index 0000000000000000000000000000000000000000..1cfa785869fce75ebd973061881bb3ebb483a5eb --- /dev/null +++ b/core/src/main/java/hudson/util/HudsonIsLoading.java @@ -0,0 +1,20 @@ +package hudson.util; + +import static javax.servlet.http.HttpServletResponse.SC_SERVICE_UNAVAILABLE; + +import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerResponse; + +import javax.servlet.ServletException; +import java.io.IOException; + +/** + * Model object used to display "Hudson is loading data" + * @author Kohsuke Kawaguchi + */ +public class HudsonIsLoading { + public void doDynamic(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException, InterruptedException { + rsp.setStatus(SC_SERVICE_UNAVAILABLE); + req.getView(this,"index.jelly").forward(req,rsp); + } +} diff --git a/core/src/main/resources/hudson/util/HudsonIsLoading/index.jelly b/core/src/main/resources/hudson/util/HudsonIsLoading/index.jelly new file mode 100644 index 0000000000000000000000000000000000000000..32bc803070af483b12703d1a7d2e323a9ae769a8 --- /dev/null +++ b/core/src/main/resources/hudson/util/HudsonIsLoading/index.jelly @@ -0,0 +1,43 @@ + + + + + + + +

Please wait while Hudson is getting ready to work...

+

+ Your browser will reload automatically when Hudson is ready. +

+ + +
+
+
\ No newline at end of file