diff --git a/core/src/main/java/hudson/lifecycle/Lifecycle.java b/core/src/main/java/hudson/lifecycle/Lifecycle.java index 6f77bd51ef1d2e408dbed3bff7e499ce68aea944..63f97bd13179490ee298f6d036b2a519092bfdfd 100644 --- a/core/src/main/java/hudson/lifecycle/Lifecycle.java +++ b/core/src/main/java/hudson/lifecycle/Lifecycle.java @@ -6,6 +6,9 @@ import hudson.model.Hudson; import java.io.File; import java.io.IOException; +import org.apache.commons.io.IOUtils; +import org.apache.commons.io.FileUtils; + /** * Provides the capability for starting/stopping/restarting/uninstalling Hudson. * @@ -72,9 +75,19 @@ public abstract class Lifecycle implements ExtensionPoint { /** * Replaces hudson.war by the given file. + * + *

+ * On some system, most notably Windows, a file being in use cannot be changed, + * so rewriting hudson.war requires some special trick. Override this method + * to do so. */ public void rewriteHudsonWar(File by) throws IOException { - throw new UnsupportedOperationException(); + File dest = getHudsonWar(); + // this should be impossible given the canRewriteHudsonWar method, + // but let's be defensive + if(dest==null) throw new IOException("hudson.war location is not known."); + + FileUtils.copyFile(by, dest); } /** @@ -82,8 +95,7 @@ public abstract class Lifecycle implements ExtensionPoint { */ public boolean canRewriteHudsonWar() { // if we don't know where hudson.war is, it's impossible to replace. - if(getHudsonWar()==null) return false; - return isOverridden("rewriteHudsonWar",File.class); + return getHudsonWar()!=null; } private boolean isOverridden(String methodName, Class... types) { diff --git a/core/src/main/java/hudson/lifecycle/SolarisSMFLifecycle.java b/core/src/main/java/hudson/lifecycle/SolarisSMFLifecycle.java new file mode 100644 index 0000000000000000000000000000000000000000..3bb17f5289c6954e6dbf506eef61a173df0b0f6b --- /dev/null +++ b/core/src/main/java/hudson/lifecycle/SolarisSMFLifecycle.java @@ -0,0 +1,18 @@ +package hudson.lifecycle; + +import java.io.IOException; + +/** + * {@link Lifecycle} for Hudson installed as SMF service. + * + * @author Kohsuke Kawaguchi + */ +public class SolarisSMFLifecycle extends Lifecycle { + /** + * In SMF managed environment, just commit a suicide and the service will be restarted by SMF. + */ + @Override + public void restart() throws IOException, InterruptedException { + System.exit(0); + } +} diff --git a/core/src/main/java/hudson/lifecycle/WindowsServiceLifecycle.java b/core/src/main/java/hudson/lifecycle/WindowsServiceLifecycle.java index 6e1f58733757cc0646a53bfcbed086e2f9f9f338..f92e79b37ada94ff0bad58e9a7f14a60b4b1c683 100644 --- a/core/src/main/java/hudson/lifecycle/WindowsServiceLifecycle.java +++ b/core/src/main/java/hudson/lifecycle/WindowsServiceLifecycle.java @@ -57,6 +57,10 @@ public class WindowsServiceLifecycle extends Lifecycle { } } + /** + * On Windows, hudson.war is locked, so we place a new version under a special name, + * which is picked up by the service wrapper upon restart. + */ @Override public void rewriteHudsonWar(File by) throws IOException { File rootDir = Hudson.getInstance().getRootDir(); @@ -67,6 +71,7 @@ public class WindowsServiceLifecycle extends Lifecycle { w.close(); } + @Override public void restart() throws IOException, InterruptedException { File me = getHudsonWar(); File home = me.getParentFile();