From 352bc190e518301421970399cac57ec199daaf66 Mon Sep 17 00:00:00 2001 From: Vincent Latombe Date: Tue, 3 Oct 2023 12:32:50 +0200 Subject: [PATCH] [JENKINS-72111] Add Lifecycle#set --- .../main/java/hudson/lifecycle/Lifecycle.java | 20 +++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/hudson/lifecycle/Lifecycle.java b/core/src/main/java/hudson/lifecycle/Lifecycle.java index da629dce94e1..be4b03560a13 100644 --- a/core/src/main/java/hudson/lifecycle/Lifecycle.java +++ b/core/src/main/java/hudson/lifecycle/Lifecycle.java @@ -28,18 +28,22 @@ import edu.umd.cs.findbugs.annotations.NonNull; import hudson.ExtensionPoint; import hudson.Functions; +import hudson.PluginManager; import hudson.Util; import java.io.File; import java.io.IOException; import java.io.UncheckedIOException; import java.lang.reflect.InvocationTargetException; import java.nio.file.Files; +import java.util.Objects; import java.util.concurrent.TimeUnit; import java.util.logging.Level; import java.util.logging.Logger; import jenkins.model.Jenkins; import jenkins.util.SystemProperties; import org.apache.commons.io.FileUtils; +import org.kohsuke.accmod.Restricted; +import org.kohsuke.accmod.restrictions.Beta; /** * Provides the capability for starting/stopping/restarting/uninstalling Hudson. @@ -57,9 +61,8 @@ public abstract class Lifecycle implements ExtensionPoint { /** * Gets the singleton instance. - * - * @return never null */ + @NonNull public static synchronized Lifecycle get() { if (INSTANCE == null) { Lifecycle instance; @@ -136,6 +139,19 @@ public void verifyRestartable() throws RestartNotSupportedException { return INSTANCE; } + /** + * Sets the singleton instance. + * Appropriate for implementations defined in plugins, + * since {@link #get} may be called before plugins are initialized, + * and so it is not safe to pass a plugin-defined class to the system property {@code hudson.lifecycle} + * despite the use of {@link PluginManager#uberClassLoader}. + * @since TODO + */ + @Restricted(Beta.class) + public static synchronized void set(@NonNull Lifecycle lifecycle) { + INSTANCE = Objects.requireNonNull(lifecycle); + } + /** * If the location of {@code jenkins.war} is known in this life cycle, * return it location. Otherwise return null to indicate that it is unknown.