From 96150d3a465f428b5fbc5d03c8cd00115f4749c9 Mon Sep 17 00:00:00 2001 From: Stephen Connolly Date: Tue, 8 Mar 2016 21:14:36 +0000 Subject: [PATCH] Jenkins.getInstance() will be @Nonnull in Jenkins 2.0+ - Code that is running from a plugin and on the master's JVM is guaranteed to never get null from this method (any cases where you do get null are bugs in core) - Code that is running from a plugin and on a remote JVM should never be allowed to load the Jenkins class in their classloader, so should never use Jenkins.getInstance()... we are annotating the method with @Nullable so that such code can have some evolution time - Code that is running in core and on one of two special paths should use the Jenkins.getInstanceOrNull() method so that the UI can be presented to users before the singleton has been instantiated / after the singleton has been destroyed - The remaining 95% of uses in core (and 100% of uses in plugins) can safely assume that the instance is never null --- core/src/main/java/hudson/ExtensionList.java | 4 +-- core/src/main/java/hudson/FilePath.java | 2 +- core/src/main/java/hudson/Functions.java | 10 +++---- .../main/java/hudson/ProxyConfiguration.java | 4 +-- core/src/main/java/hudson/WebAppMain.java | 4 +-- .../diagnosis/NullIdDescriptorMonitor.java | 2 +- .../java/hudson/diagnosis/OldDataMonitor.java | 4 +-- .../diagnosis/ReverseProxySetupMonitor.java | 2 -- .../java/hudson/init/TaskMethodFinder.java | 4 +-- .../hudson/lifecycle/SolarisSMFLifecycle.java | 2 +- .../java/hudson/lifecycle/UnixLifecycle.java | 2 +- .../java/hudson/model/AbstractProject.java | 2 +- core/src/main/java/hudson/model/Computer.java | 7 +++-- core/src/main/java/hudson/model/Executor.java | 5 ++-- .../main/java/hudson/model/Fingerprint.java | 6 ++-- core/src/main/java/hudson/model/Hudson.java | 4 ++- core/src/main/java/hudson/model/Job.java | 2 +- core/src/main/java/hudson/model/Node.java | 11 +++++--- core/src/main/java/hudson/model/Queue.java | 14 +++++----- core/src/main/java/hudson/model/Run.java | 2 +- .../java/hudson/model/UsageStatistics.java | 2 +- core/src/main/java/hudson/model/User.java | 2 +- .../hudson/model/listeners/RunListener.java | 2 +- .../hudson/model/listeners/SCMListener.java | 6 ++-- .../java/hudson/security/HudsonFilter.java | 2 +- .../TokenBasedRememberMeServices2.java | 2 +- .../hudson/security/csrf/CrumbFilter.java | 2 +- .../java/hudson/slaves/SlaveComputer.java | 2 +- .../main/java/hudson/tools/JDKInstaller.java | 2 +- .../java/hudson/util/PluginServletFilter.java | 4 +-- .../java/hudson/util/ProcessKillingVeto.java | 2 +- .../java/hudson/util/SubClassGenerator.java | 2 +- core/src/main/java/hudson/util/XStream2.java | 4 +-- .../hudson/util/io/ParserConfigurator.java | 2 +- core/src/main/java/jenkins/model/Jenkins.java | 28 ++++++++++++++++--- .../model/UnlabeledLoadStatistics.java | 2 +- .../jenkins/security/ApiTokenProperty.java | 2 +- .../jenkins/security/ConfidentialStore.java | 3 -- .../QueueItemAuthenticatorProvider.java | 2 +- .../jenkins/triggers/ReverseBuildTrigger.java | 6 ++-- .../jenkins/util/JSONSignatureValidator.java | 2 +- .../java/hudson/util/BootFailureTest.java | 2 +- 42 files changed, 99 insertions(+), 77 deletions(-) diff --git a/core/src/main/java/hudson/ExtensionList.java b/core/src/main/java/hudson/ExtensionList.java index 46447fbcda..397f57030d 100644 --- a/core/src/main/java/hudson/ExtensionList.java +++ b/core/src/main/java/hudson/ExtensionList.java @@ -390,14 +390,14 @@ public class ExtensionList extends AbstractList { /** * Gets the extension list for a given type. * Normally calls {@link Jenkins#getExtensionList(Class)} but falls back to an empty list - * in case {@link Jenkins#getInstance} is null. + * in case {@link Jenkins#getInstanceOrNull()} is null. * Thus it is useful to call from {@code all()} methods which need to behave gracefully during startup or shutdown. * @param type the extension point type * @return some list * @since 1.572 */ public static @Nonnull ExtensionList lookup(Class type) { - Jenkins j = Jenkins.getInstance(); + Jenkins j = Jenkins.getInstanceOrNull(); return j == null ? create((Jenkins) null, type) : j.getExtensionList(type); } diff --git a/core/src/main/java/hudson/FilePath.java b/core/src/main/java/hudson/FilePath.java index 9690c39cd0..ec13085817 100644 --- a/core/src/main/java/hudson/FilePath.java +++ b/core/src/main/java/hudson/FilePath.java @@ -1133,7 +1133,7 @@ public final class FilePath implements Serializable { * @since 1.571 */ public @CheckForNull Computer toComputer() { - Jenkins j = Jenkins.getInstance(); + Jenkins j = Jenkins.getInstanceOrNull(); if (j != null) { for (Computer c : j.getComputers()) { if (getChannel()==c.getChannel()) { diff --git a/core/src/main/java/hudson/Functions.java b/core/src/main/java/hudson/Functions.java index 8b3f39f9fe..2208b9fb02 100644 --- a/core/src/main/java/hudson/Functions.java +++ b/core/src/main/java/hudson/Functions.java @@ -228,7 +228,7 @@ public class Functions { * @since 1.607 */ public static boolean isExtensionsAvailable() { - final Jenkins jenkins = Jenkins.getInstance(); + final Jenkins jenkins = Jenkins.getInstanceOrNull(); return jenkins != null && jenkins.getInitLevel().compareTo(InitMilestone.EXTENSIONS_AUGMENTED) >= 0 && !jenkins.isTerminating(); } @@ -1659,7 +1659,7 @@ public class Functions { */ public static List getPageDecorators() { // this method may be called to render start up errors, at which point Hudson doesn't exist yet. see HUDSON-3608 - if(Jenkins.getInstance()==null) return Collections.emptyList(); + if(Jenkins.getInstanceOrNull()==null) return Collections.emptyList(); return PageDecorator.all(); } @@ -1681,13 +1681,13 @@ public class Functions { } public static String getCrumb(StaplerRequest req) { - Jenkins h = Jenkins.getInstance(); + Jenkins h = Jenkins.getInstanceOrNull(); CrumbIssuer issuer = h != null ? h.getCrumbIssuer() : null; return issuer != null ? issuer.getCrumb(req) : ""; } public static String getCrumbRequestField() { - Jenkins h = Jenkins.getInstance(); + Jenkins h = Jenkins.getInstanceOrNull(); CrumbIssuer issuer = h != null ? h.getCrumbIssuer() : null; return issuer != null ? issuer.getDescriptor().getCrumbRequestField() : ""; } @@ -1917,7 +1917,7 @@ public class Functions { * discovery of Jenkins. */ public static void advertiseHeaders(HttpServletResponse rsp) { - Jenkins j = Jenkins.getInstance(); + Jenkins j = Jenkins.getInstanceOrNull(); if (j!=null) { rsp.setHeader("X-Hudson","1.395"); rsp.setHeader("X-Jenkins", Jenkins.VERSION); diff --git a/core/src/main/java/hudson/ProxyConfiguration.java b/core/src/main/java/hudson/ProxyConfiguration.java index 9b51990925..538a3a578b 100644 --- a/core/src/main/java/hudson/ProxyConfiguration.java +++ b/core/src/main/java/hudson/ProxyConfiguration.java @@ -215,7 +215,7 @@ public final class ProxyConfiguration extends AbstractDescribableImpl extends TaskBuilder { */ private Object lookUp(Class type) { if (type==Jenkins.class || type==Hudson.class) - return Jenkins.getInstance(); - Jenkins j = Jenkins.getInstance(); + return Jenkins.getInstanceOrNull(); + Jenkins j = Jenkins.getInstanceOrNull(); if (j!=null) { Injector i = j.getInjector(); if (i!=null) diff --git a/core/src/main/java/hudson/lifecycle/SolarisSMFLifecycle.java b/core/src/main/java/hudson/lifecycle/SolarisSMFLifecycle.java index 9da1505229..215e069b17 100644 --- a/core/src/main/java/hudson/lifecycle/SolarisSMFLifecycle.java +++ b/core/src/main/java/hudson/lifecycle/SolarisSMFLifecycle.java @@ -38,7 +38,7 @@ public class SolarisSMFLifecycle extends Lifecycle { */ @Override public void restart() throws IOException, InterruptedException { - Jenkins h = Jenkins.getInstance(); + Jenkins h = Jenkins.getInstanceOrNull(); if (h != null) h.cleanUp(); System.exit(0); diff --git a/core/src/main/java/hudson/lifecycle/UnixLifecycle.java b/core/src/main/java/hudson/lifecycle/UnixLifecycle.java index 0e489277e5..15cb5699b4 100644 --- a/core/src/main/java/hudson/lifecycle/UnixLifecycle.java +++ b/core/src/main/java/hudson/lifecycle/UnixLifecycle.java @@ -65,7 +65,7 @@ public class UnixLifecycle extends Lifecycle { @Override public void restart() throws IOException, InterruptedException { - Jenkins h = Jenkins.getInstance(); + Jenkins h = Jenkins.getInstanceOrNull(); if (h != null) h.cleanUp(); diff --git a/core/src/main/java/hudson/model/AbstractProject.java b/core/src/main/java/hudson/model/AbstractProject.java index d807695eb4..11962c4942 100644 --- a/core/src/main/java/hudson/model/AbstractProject.java +++ b/core/src/main/java/hudson/model/AbstractProject.java @@ -2077,7 +2077,7 @@ public abstract class AbstractProject

,R extends A return FormValidation.error(e, Messages.AbstractProject_AssignedLabelString_InvalidBooleanExpression(e.getMessage())); } - Jenkins j = Jenkins.getInstance(); + Jenkins j = Jenkins.getInstanceOrNull(); if (j == null) { return FormValidation.ok(); // ? } diff --git a/core/src/main/java/hudson/model/Computer.java b/core/src/main/java/hudson/model/Computer.java index 4ce4a3b7a3..e350644ab6 100644 --- a/core/src/main/java/hudson/model/Computer.java +++ b/core/src/main/java/hudson/model/Computer.java @@ -564,8 +564,9 @@ public /*transient*/ abstract class Computer extends Actionable implements Acces * null if the configuration has changed and the node is removed, yet the corresponding {@link Computer} * is not yet gone. */ - public @CheckForNull Node getNode() { - Jenkins j = Jenkins.getInstance(); + @CheckForNull + public Node getNode() { + Jenkins j = Jenkins.getInstanceOrNull(); if (j == null) { return null; } @@ -1011,7 +1012,7 @@ public /*transient*/ abstract class Computer extends Actionable implements Acces executors.remove(e); addNewExecutorIfNecessary(); if (!isAlive()) { - AbstractCIBase ciBase = Jenkins.getInstance(); + AbstractCIBase ciBase = Jenkins.getInstanceOrNull(); if (ciBase != null) { ciBase.removeComputer(Computer.this); } diff --git a/core/src/main/java/hudson/model/Executor.java b/core/src/main/java/hudson/model/Executor.java index 817166c60e..b46e7e6404 100644 --- a/core/src/main/java/hudson/model/Executor.java +++ b/core/src/main/java/hudson/model/Executor.java @@ -958,8 +958,9 @@ public class Executor extends Thread implements ModelObject { * or null if it could not be found (for example because the execution has already completed) * @since 1.607 */ - public static @CheckForNull Executor of(Executable executable) { - Jenkins jenkins = Jenkins.getInstance(); + @CheckForNull + public static Executor of(Executable executable) { + Jenkins jenkins = Jenkins.getInstanceOrNull(); if (jenkins == null) { return null; } diff --git a/core/src/main/java/hudson/model/Fingerprint.java b/core/src/main/java/hudson/model/Fingerprint.java index 8cb6347168..daf85fb902 100644 --- a/core/src/main/java/hudson/model/Fingerprint.java +++ b/core/src/main/java/hudson/model/Fingerprint.java @@ -128,7 +128,7 @@ public class Fingerprint implements ModelObject, Saveable { private boolean hasPermissionToDiscoverBuild() { // We expose the data to Jenkins administrators in order to // let them manage the data for deleted jobs (also works for SYSTEM) - final Jenkins instance = Jenkins.getInstance(); + final Jenkins instance = Jenkins.getInstanceOrNull(); if (instance != null && instance.hasPermission(Jenkins.ADMINISTER)) { return true; } @@ -941,7 +941,7 @@ public class Fingerprint implements ModelObject, Saveable { @Exported(name="usage") public @Nonnull List _getUsages() { List r = new ArrayList(); - final Jenkins instance = Jenkins.getInstance(); + final Jenkins instance = Jenkins.getInstanceOrNull(); if (instance == null) { return r; } @@ -1368,7 +1368,7 @@ public class Fingerprint implements ModelObject, Saveable { * @return {@code true} if the user can discover the item */ private static boolean canDiscoverItem(@Nonnull final String fullName) { - final Jenkins jenkins = Jenkins.getInstance(); + final Jenkins jenkins = Jenkins.getInstanceOrNull(); if (jenkins == null) { return false; } diff --git a/core/src/main/java/hudson/model/Hudson.java b/core/src/main/java/hudson/model/Hudson.java index 9792d38e1c..f41cae8299 100644 --- a/core/src/main/java/hudson/model/Hudson.java +++ b/core/src/main/java/hudson/model/Hudson.java @@ -34,6 +34,7 @@ import hudson.model.listeners.ItemListener; import hudson.slaves.ComputerListener; import hudson.util.CopyOnWriteList; import hudson.util.FormValidation; +import javax.annotation.Nonnull; import jenkins.model.Jenkins; import org.jvnet.hudson.reactor.ReactorException; import org.kohsuke.stapler.QueryParameter; @@ -71,7 +72,8 @@ public class Hudson extends Jenkins { /** @deprecated Here only for compatibility. Use {@link Jenkins#getInstance} instead. */ @Deprecated @CLIResolver - public static @CheckForNull Hudson getInstance() { + @Nonnull + public static Hudson getInstance() { return (Hudson)Jenkins.getInstance(); } diff --git a/core/src/main/java/hudson/model/Job.java b/core/src/main/java/hudson/model/Job.java index d60f144d55..64495ba006 100644 --- a/core/src/main/java/hudson/model/Job.java +++ b/core/src/main/java/hudson/model/Job.java @@ -848,7 +848,7 @@ public abstract class Job, RunT extends Run V withLock(hudson.remoting.Callable callable) throws T { - final Jenkins jenkins = Jenkins.getInstance(); + final Jenkins jenkins = Jenkins.getInstanceOrNull(); final Queue queue = jenkins == null ? null : jenkins.getQueue(); if (queue == null) { return callable.call(); @@ -1222,7 +1222,7 @@ public class Queue extends ResourceController implements Saveable { * @since 1.592 */ public static V withLock(java.util.concurrent.Callable callable) throws Exception { - final Jenkins jenkins = Jenkins.getInstance(); + final Jenkins jenkins = Jenkins.getInstanceOrNull(); final Queue queue = jenkins == null ? null : jenkins.getQueue(); if (queue == null) { return callable.call(); @@ -1239,7 +1239,7 @@ public class Queue extends ResourceController implements Saveable { * @since 1.618 */ public static boolean tryWithLock(Runnable runnable) { - final Jenkins jenkins = Jenkins.getInstance(); + final Jenkins jenkins = Jenkins.getInstanceOrNull(); final Queue queue = jenkins == null ? null : jenkins.getQueue(); if (queue == null) { runnable.run(); @@ -1255,7 +1255,7 @@ public class Queue extends ResourceController implements Saveable { * @since 1.618 */ public static Runnable wrapWithLock(Runnable runnable) { - final Jenkins jenkins = Jenkins.getInstance(); + final Jenkins jenkins = Jenkins.getInstanceOrNull(); final Queue queue = jenkins == null ? null : jenkins.getQueue(); return queue == null ? runnable : new LockedRunnable(runnable); } @@ -1267,7 +1267,7 @@ public class Queue extends ResourceController implements Saveable { * @since 1.618 */ public static hudson.remoting.Callable wrapWithLock(hudson.remoting.Callable callable) { - final Jenkins jenkins = Jenkins.getInstance(); + final Jenkins jenkins = Jenkins.getInstanceOrNull(); final Queue queue = jenkins == null ? null : jenkins.getQueue(); return queue == null ? callable : new LockedHRCallable<>(callable); } @@ -1279,7 +1279,7 @@ public class Queue extends ResourceController implements Saveable { * @since 1.618 */ public static java.util.concurrent.Callable wrapWithLock(java.util.concurrent.Callable callable) { - final Jenkins jenkins = Jenkins.getInstance(); + final Jenkins jenkins = Jenkins.getInstanceOrNull(); final Queue queue = jenkins == null ? null : jenkins.getQueue(); return queue == null ? callable : new LockedJUCCallable(callable); } diff --git a/core/src/main/java/hudson/model/Run.java b/core/src/main/java/hudson/model/Run.java index c4f64ccade..782821e36a 100644 --- a/core/src/main/java/hudson/model/Run.java +++ b/core/src/main/java/hudson/model/Run.java @@ -2275,7 +2275,7 @@ public abstract class Run ,RunT extends Run 0) { return false; diff --git a/core/src/main/java/hudson/model/User.java b/core/src/main/java/hudson/model/User.java index e2a09768f4..de2b54ab05 100644 --- a/core/src/main/java/hudson/model/User.java +++ b/core/src/main/java/hudson/model/User.java @@ -150,7 +150,7 @@ public class User extends AbstractModelObject implements AccessControlled, Descr */ @Nonnull public static IdStrategy idStrategy() { - Jenkins j = Jenkins.getInstance(); + Jenkins j = Jenkins.getInstanceOrNull(); if (j == null) { return IdStrategy.CASE_INSENSITIVE; } diff --git a/core/src/main/java/hudson/model/listeners/RunListener.java b/core/src/main/java/hudson/model/listeners/RunListener.java index e65347bc02..e8e1eca716 100644 --- a/core/src/main/java/hudson/model/listeners/RunListener.java +++ b/core/src/main/java/hudson/model/listeners/RunListener.java @@ -223,7 +223,7 @@ public abstract class RunListener implements ExtensionPoint { * Fires the {@link #onFinalized(Run)} event. */ public static void fireFinalized(Run r) { - if (Jenkins.getInstance() == null) { + if (Jenkins.getInstanceOrNull() == null) { return; } for (RunListener l : all()) { diff --git a/core/src/main/java/hudson/model/listeners/SCMListener.java b/core/src/main/java/hudson/model/listeners/SCMListener.java index 3f570aa24f..57425f7d73 100644 --- a/core/src/main/java/hudson/model/listeners/SCMListener.java +++ b/core/src/main/java/hudson/model/listeners/SCMListener.java @@ -126,7 +126,7 @@ public abstract class SCMListener implements ExtensionPoint { */ @SuppressWarnings("deprecation") public static Collection all() { - Jenkins j = Jenkins.getInstance(); + Jenkins j = Jenkins.getInstanceOrNull(); if (j == null) { return Collections.emptySet(); } @@ -140,7 +140,7 @@ public abstract class SCMListener implements ExtensionPoint { /** @deprecated Use {@link Extension} instead. */ @Deprecated public final void register() { - Jenkins j = Jenkins.getInstance(); + Jenkins j = Jenkins.getInstanceOrNull(); if (j != null) { j.getSCMListeners().add(this); } @@ -149,7 +149,7 @@ public abstract class SCMListener implements ExtensionPoint { /** @deprecated Use {@link Extension} instead. */ @Deprecated public final boolean unregister() { - Jenkins j = Jenkins.getInstance(); + Jenkins j = Jenkins.getInstanceOrNull(); if (j != null) { return j.getSCMListeners().remove(this); } else { diff --git a/core/src/main/java/hudson/security/HudsonFilter.java b/core/src/main/java/hudson/security/HudsonFilter.java index 3a1868344a..b37b2ea4ea 100644 --- a/core/src/main/java/hudson/security/HudsonFilter.java +++ b/core/src/main/java/hudson/security/HudsonFilter.java @@ -104,7 +104,7 @@ public class HudsonFilter implements Filter { // this is how we make us available to the rest of Hudson. filterConfig.getServletContext().setAttribute(HudsonFilter.class.getName(),this); try { - Jenkins hudson = Jenkins.getInstance(); + Jenkins hudson = Jenkins.getInstanceOrNull(); if (hudson != null) { // looks like we are initialized after Hudson came into being. initialize it now. See #3069 LOGGER.fine("Security wasn't initialized; Initializing it..."); diff --git a/core/src/main/java/hudson/security/TokenBasedRememberMeServices2.java b/core/src/main/java/hudson/security/TokenBasedRememberMeServices2.java index 6ae4d1c426..9b81ae5b19 100644 --- a/core/src/main/java/hudson/security/TokenBasedRememberMeServices2.java +++ b/core/src/main/java/hudson/security/TokenBasedRememberMeServices2.java @@ -93,7 +93,7 @@ public class TokenBasedRememberMeServices2 extends TokenBasedRememberMeServices return; } - Jenkins j = Jenkins.getInstance(); + Jenkins j = Jenkins.getInstanceOrNull(); if (j != null && j.isDisableRememberMe()) { if (logger.isDebugEnabled()) { logger.debug("Did not send remember-me cookie because 'Remember Me' is disabled in " + diff --git a/core/src/main/java/hudson/security/csrf/CrumbFilter.java b/core/src/main/java/hudson/security/csrf/CrumbFilter.java index 8e0fe64cb6..9080a54692 100644 --- a/core/src/main/java/hudson/security/csrf/CrumbFilter.java +++ b/core/src/main/java/hudson/security/csrf/CrumbFilter.java @@ -35,7 +35,7 @@ public class CrumbFilter implements Filter { * we cannot use Hudson to the CrumbIssuer into CrumbFilter eagerly. */ public CrumbIssuer getCrumbIssuer() { - Jenkins h = Jenkins.getInstance(); + Jenkins h = Jenkins.getInstanceOrNull(); if(h==null) return null; // before Jenkins is initialized? return h.getCrumbIssuer(); } diff --git a/core/src/main/java/hudson/slaves/SlaveComputer.java b/core/src/main/java/hudson/slaves/SlaveComputer.java index b51ea86df2..fef84d8dc8 100644 --- a/core/src/main/java/hudson/slaves/SlaveComputer.java +++ b/core/src/main/java/hudson/slaves/SlaveComputer.java @@ -835,7 +835,7 @@ public class SlaveComputer extends Computer { * @since 1.362 */ public static VirtualChannel getChannelToMaster() { - if (Jenkins.getInstance()!=null) + if (Jenkins.getInstanceOrNull()!=null) return FilePath.localChannel; // if this method is called from within the slave computation thread, this should work diff --git a/core/src/main/java/hudson/tools/JDKInstaller.java b/core/src/main/java/hudson/tools/JDKInstaller.java index d270769de1..31eeb41b90 100644 --- a/core/src/main/java/hudson/tools/JDKInstaller.java +++ b/core/src/main/java/hudson/tools/JDKInstaller.java @@ -448,7 +448,7 @@ public class JDKInstaller extends ToolInstaller { HttpClient hc = new HttpClient(); hc.getParams().setParameter("http.useragent","Mozilla/5.0 (Windows; U; MSIE 9.0; Windows NT 9.0; en-US)"); - Jenkins j = Jenkins.getInstance(); + Jenkins j = Jenkins.getInstanceOrNull(); ProxyConfiguration jpc = j!=null ? j.proxy : null; if(jpc != null) { hc.getHostConfiguration().setProxy(jpc.name, jpc.port); diff --git a/core/src/main/java/hudson/util/PluginServletFilter.java b/core/src/main/java/hudson/util/PluginServletFilter.java index 41d83899a5..9e20ea6b50 100644 --- a/core/src/main/java/hudson/util/PluginServletFilter.java +++ b/core/src/main/java/hudson/util/PluginServletFilter.java @@ -93,7 +93,7 @@ public class PluginServletFilter implements Filter, ExtensionPoint { } public static void addFilter(Filter filter) throws ServletException { - Jenkins j = Jenkins.getInstance(); + Jenkins j = Jenkins.getInstanceOrNull(); PluginServletFilter container = null; if(j != null) { @@ -111,7 +111,7 @@ public class PluginServletFilter implements Filter, ExtensionPoint { } public static void removeFilter(Filter filter) throws ServletException { - Jenkins j = Jenkins.getInstance(); + Jenkins j = Jenkins.getInstanceOrNull(); if (j==null || getInstance(j.servletContext) == null) { LEGACY.remove(filter); } else { diff --git a/core/src/main/java/hudson/util/ProcessKillingVeto.java b/core/src/main/java/hudson/util/ProcessKillingVeto.java index a410a610fd..0b52964c5a 100644 --- a/core/src/main/java/hudson/util/ProcessKillingVeto.java +++ b/core/src/main/java/hudson/util/ProcessKillingVeto.java @@ -74,7 +74,7 @@ public abstract class ProcessKillingVeto implements ExtensionPoint { * list if Jenkins is not available, never null. */ public static List all() { - Jenkins jenkins = Jenkins.getInstance(); + Jenkins jenkins = Jenkins.getInstanceOrNull(); if (jenkins == null) return Collections.emptyList(); return jenkins.getExtensionList(ProcessKillingVeto.class); diff --git a/core/src/main/java/hudson/util/SubClassGenerator.java b/core/src/main/java/hudson/util/SubClassGenerator.java index f6076ddda1..0dbb8d6dec 100644 --- a/core/src/main/java/hudson/util/SubClassGenerator.java +++ b/core/src/main/java/hudson/util/SubClassGenerator.java @@ -76,7 +76,7 @@ public class SubClassGenerator extends ClassLoader { Class c = defineClass(name, image, 0, image.length).asSubclass(base); - Jenkins h = Jenkins.getInstance(); + Jenkins h = Jenkins.getInstanceOrNull(); if (h!=null) // null only during tests. ((UberClassLoader)h.pluginManager.uberClassLoader).addNamedClass(name,c); // can't change the field type as it breaks binary compatibility diff --git a/core/src/main/java/hudson/util/XStream2.java b/core/src/main/java/hudson/util/XStream2.java index 8ea539fc25..4f3c7ba613 100644 --- a/core/src/main/java/hudson/util/XStream2.java +++ b/core/src/main/java/hudson/util/XStream2.java @@ -106,7 +106,7 @@ public class XStream2 extends XStream { public Object unmarshal(HierarchicalStreamReader reader, Object root, DataHolder dataHolder) { // init() is too early to do this // defensive because some use of XStream happens before plugins are initialized. - Jenkins h = Jenkins.getInstance(); + Jenkins h = Jenkins.getInstanceOrNull(); if(h!=null && h.pluginManager!=null && h.pluginManager.uberClassLoader!=null) { setClassLoader(h.pluginManager.uberClassLoader); } @@ -421,7 +421,7 @@ public class XStream2 extends XStream { return classOwnership.ownerOf(clazz); } if (pm == null) { - Jenkins j = Jenkins.getInstance(); + Jenkins j = Jenkins.getInstanceOrNull(); if (j != null) { pm = j.getPluginManager(); } diff --git a/core/src/main/java/hudson/util/io/ParserConfigurator.java b/core/src/main/java/hudson/util/io/ParserConfigurator.java index bac60c7e79..878fba535b 100644 --- a/core/src/main/java/hudson/util/io/ParserConfigurator.java +++ b/core/src/main/java/hudson/util/io/ParserConfigurator.java @@ -75,7 +75,7 @@ public abstract class ParserConfigurator implements ExtensionPoint, Serializable public static void applyConfiguration(SAXReader reader, Object context) throws IOException, InterruptedException { Collection all = Collections.emptyList(); - if (Jenkins.getInstance()==null) { + if (Jenkins.getInstanceOrNull()==null) { Channel ch = Channel.current(); if (ch!=null) all = ch.call(new SlaveToMasterCallable, IOException>() { diff --git a/core/src/main/java/jenkins/model/Jenkins.java b/core/src/main/java/jenkins/model/Jenkins.java index 7fcf37c7ca..2d22b3a79f 100644 --- a/core/src/main/java/jenkins/model/Jenkins.java +++ b/core/src/main/java/jenkins/model/Jenkins.java @@ -688,12 +688,15 @@ public class Jenkins extends AbstractCIBase implements DirectlyModifiableTopLeve /** * Gets the {@link Jenkins} singleton. - * {@link #getInstance()} provides the unchecked versions of the method. + * {@link #getInstanceOrNull()} provides the unchecked versions of the method. * @return {@link Jenkins} instance * @throws IllegalStateException {@link Jenkins} has not been started, or was already shut down * @since 1.590 + * @deprecated use {@link #getInstance()} */ - public static @Nonnull Jenkins getActiveInstance() throws IllegalStateException { + @Deprecated + @Nonnull + public static Jenkins getActiveInstance() throws IllegalStateException { Jenkins instance = HOLDER.getInstance(); if (instance == null) { throw new IllegalStateException("Jenkins has not been started, or was already shut down"); @@ -706,10 +709,27 @@ public class Jenkins extends AbstractCIBase implements DirectlyModifiableTopLeve * {@link #getActiveInstance()} provides the checked versions of the method. * @return The instance. Null if the {@link Jenkins} instance has not been started, * or was already shut down + * @since 1.653 + */ + @CheckForNull + public static Jenkins getInstanceOrNull() { + return HOLDER.getInstance(); + } + + /** + * Gets the {@link Jenkins} singleton. In certain rare cases you may have code that is intended to run before + * Jenkins starts or while Jenkins is being shut-down. For those rare cases use {@link #getInstanceOrNull()}. + * In other cases you may have code that might end up running on a remote JVM and not on the Jenkins master, + * for those cases you really should rewrite your code so that when the {@link Callable} is sent over the remoting + * channel it uses a {@code writeReplace} method or similar to ensure that the {@link Jenkins} class is not being + * loaded into the remote class loader + * @return The instance. + * @throws IllegalStateException {@link Jenkins} has not been started, or was already shut down */ @CLIResolver - @CheckForNull + @Nullable // TODO replace with non-null once Jenkins 2.0+ public static Jenkins getInstance() { + // TODO throw an IllegalStateException in Jenkins 2.0+ return HOLDER.getInstance(); } @@ -4115,7 +4135,7 @@ public class Jenkins extends AbstractCIBase implements DirectlyModifiableTopLeve * Shortcut for {@code Jenkins.getInstance().lookup.get(type)} */ public static @CheckForNull T lookup(Class type) { - Jenkins j = Jenkins.getInstance(); + Jenkins j = Jenkins.getInstanceOrNull(); return j != null ? j.lookup.get(type) : null; } diff --git a/core/src/main/java/jenkins/model/UnlabeledLoadStatistics.java b/core/src/main/java/jenkins/model/UnlabeledLoadStatistics.java index cf4abda281..1bf8165090 100644 --- a/core/src/main/java/jenkins/model/UnlabeledLoadStatistics.java +++ b/core/src/main/java/jenkins/model/UnlabeledLoadStatistics.java @@ -78,7 +78,7 @@ public class UnlabeledLoadStatistics extends LoadStatistics { @Override public int computeQueueLength() { - final Jenkins j = Jenkins.getInstance(); + final Jenkins j = Jenkins.getInstanceOrNull(); if (j == null) { // Consider queue as empty when Jenkins is inactive return 0; } diff --git a/core/src/main/java/jenkins/security/ApiTokenProperty.java b/core/src/main/java/jenkins/security/ApiTokenProperty.java index 82d3d9616e..03fb39e7fa 100644 --- a/core/src/main/java/jenkins/security/ApiTokenProperty.java +++ b/core/src/main/java/jenkins/security/ApiTokenProperty.java @@ -118,7 +118,7 @@ public class ApiTokenProperty extends UserProperty { } private boolean hasPermissionToSeeToken() { - final Jenkins jenkins = Jenkins.getInstance(); + final Jenkins jenkins = Jenkins.getInstanceOrNull(); if (jenkins == null) { return false; // Should not happen - we don't display UIs in this stage } diff --git a/core/src/main/java/jenkins/security/ConfidentialStore.java b/core/src/main/java/jenkins/security/ConfidentialStore.java index 1c747b32c8..9434035d2a 100644 --- a/core/src/main/java/jenkins/security/ConfidentialStore.java +++ b/core/src/main/java/jenkins/security/ConfidentialStore.java @@ -62,9 +62,6 @@ public abstract class ConfidentialStore { if (TEST!=null) return TEST.get(); Jenkins j = Jenkins.getInstance(); - if (j == null) { - throw new IllegalStateException("cannot initialize confidential key store until Jenkins has started"); - } Lookup lookup = j.lookup; ConfidentialStore cs = lookup.get(ConfidentialStore.class); if (cs==null) { diff --git a/core/src/main/java/jenkins/security/QueueItemAuthenticatorProvider.java b/core/src/main/java/jenkins/security/QueueItemAuthenticatorProvider.java index bb43c58f8a..787aae05cb 100644 --- a/core/src/main/java/jenkins/security/QueueItemAuthenticatorProvider.java +++ b/core/src/main/java/jenkins/security/QueueItemAuthenticatorProvider.java @@ -32,7 +32,7 @@ public abstract class QueueItemAuthenticatorProvider implements ExtensionPoint { private Iterator delegate = null; private IteratorImpl() { - final Jenkins jenkins = Jenkins.getInstance(); + final Jenkins jenkins = Jenkins.getInstanceOrNull(); providers = new ArrayList(jenkins == null ? Collections.emptyList() : jenkins.getExtensionList(QueueItemAuthenticatorProvider.class)).iterator(); diff --git a/core/src/main/java/jenkins/triggers/ReverseBuildTrigger.java b/core/src/main/java/jenkins/triggers/ReverseBuildTrigger.java index 530533dac6..cc5e3a8f14 100644 --- a/core/src/main/java/jenkins/triggers/ReverseBuildTrigger.java +++ b/core/src/main/java/jenkins/triggers/ReverseBuildTrigger.java @@ -106,7 +106,7 @@ public final class ReverseBuildTrigger extends Trigger implements Dependenc } private boolean shouldTrigger(Run upstreamBuild, TaskListener listener) { - Jenkins jenkins = Jenkins.getInstance(); + Jenkins jenkins = Jenkins.getInstanceOrNull(); if (jenkins == null || job == null) { return false; } @@ -202,7 +202,7 @@ public final class ReverseBuildTrigger extends Trigger implements Dependenc while(tokens.hasMoreTokens()) { String projectName = tokens.nextToken().trim(); if (StringUtils.isNotBlank(projectName)) { - Jenkins jenkins = Jenkins.getInstance(); + Jenkins jenkins = Jenkins.getInstanceOrNull(); if (jenkins == null) { return FormValidation.ok(); } @@ -253,7 +253,7 @@ public final class ReverseBuildTrigger extends Trigger implements Dependenc @Extension public static class ItemListenerImpl extends ItemListener { @Override public void onLocationChanged(Item item, String oldFullName, String newFullName) { - Jenkins jenkins = Jenkins.getInstance(); + Jenkins jenkins = Jenkins.getInstanceOrNull(); if (jenkins == null) { return; } diff --git a/core/src/main/java/jenkins/util/JSONSignatureValidator.java b/core/src/main/java/jenkins/util/JSONSignatureValidator.java index 76d422cd90..f04661256e 100644 --- a/core/src/main/java/jenkins/util/JSONSignatureValidator.java +++ b/core/src/main/java/jenkins/util/JSONSignatureValidator.java @@ -134,7 +134,7 @@ public class JSONSignatureValidator { // if we trust default root CAs, we end up trusting anyone who has a valid certificate, // which isn't useful at all Set anchors = new HashSet(); // CertificateUtil.getDefaultRootCAs(); - Jenkins j = Jenkins.getInstance(); + Jenkins j = Jenkins.getInstanceOrNull(); if (j == null) { return anchors; } diff --git a/test/src/test/java/hudson/util/BootFailureTest.java b/test/src/test/java/hudson/util/BootFailureTest.java index 5ab16ed0c9..aeaf88e7d0 100644 --- a/test/src/test/java/hudson/util/BootFailureTest.java +++ b/test/src/test/java/hudson/util/BootFailureTest.java @@ -74,7 +74,7 @@ public class BootFailureTest { @After public void tearDown() { - Jenkins j = Jenkins.getInstance(); + Jenkins j = Jenkins.getInstanceOrNull(); if (j != null) { j.cleanUp(); }