diff --git a/core/includes/bootstrap.inc b/core/includes/bootstrap.inc
index 6fae299..13f7107 100644
--- a/core/includes/bootstrap.inc
+++ b/core/includes/bootstrap.inc
@@ -733,7 +733,7 @@ function drupal_bootstrap($phase = NULL) {
     $boot_level = $phase;
   }
 
-  return \Drupal::getContainer() ? DRUPAL_BOOTSTRAP_CODE : DRUPAL_BOOTSTRAP_CONFIGURATION;
+  return \Drupal::hasContainer() ? DRUPAL_BOOTSTRAP_CODE : DRUPAL_BOOTSTRAP_CONFIGURATION;
 }
 
 /**
diff --git a/core/lib/Drupal.php b/core/lib/Drupal.php
index 7b52d13..1bc06ea 100644
--- a/core/lib/Drupal.php
+++ b/core/lib/Drupal.php
@@ -5,6 +5,7 @@
  * Contains Drupal.
  */
 
+use Drupal\Core\DependencyInjection\ContainerNotInitializedException;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 use Drupal\Core\Url;
 
@@ -103,27 +104,53 @@ class Drupal {
    * Sets a new global container.
    *
    * @param \Symfony\Component\DependencyInjection\ContainerInterface $container
-   *   A new container instance to replace the current. NULL may be passed by
-   *   testing frameworks to ensure that the global state of a previous
-   *   environment does not leak into a test.
+   *   A new container instance to replace the current.
    */
-  public static function setContainer(ContainerInterface $container = NULL) {
+  public static function setContainer(ContainerInterface $container) {
     static::$container = $container;
   }
 
   /**
+   * Unsets the global container.
+   */
+  public static function unsetContainer() {
+    static::$container = NULL;
+  }
+
+  /**
    * Returns the currently active global container.
    *
-   * @deprecated This method is only useful for the testing environment. It
-   * should not be used otherwise.
+   * @deprecated This method currently returns NULL when the container is not
+   *   initialized. This behavior is deprecated, before 8.0.0 it will instead
+   *   throw an exception. An additional parameter was added to simulate the
+   *   future behavior.
+   *
+   * @throws \Drupal\Core\DependencyInjection\ContainerNotInitializedException
+   *
+   * @param bool $exception_on_invalid
+   *   (optional) If TRUE and the container is not initialized, an exception
+   *   will be thrown. Defaults to FALSE.
    *
    * @return \Symfony\Component\DependencyInjection\ContainerInterface|null
    */
-  public static function getContainer() {
+  public static function getContainer($exception_on_invalid = FALSE) {
+    if (static::$container === NULL && $exception_on_invalid) {
+      throw new ContainerNotInitializedException('\Drupal::$container is not initialized yet. \Drupal::setContainer() must be called with a real container.');
+    }
     return static::$container;
   }
 
   /**
+   * Returns TRUE if the container has been initialized, FALSE otherwise.
+   *
+   * @return bool
+   */
+  public static function hasContainer() {
+    return static::$container !== NULL;
+  }
+
+
+  /**
    * Retrieves a service from the container.
    *
    * Use this method if the desired service is not one of those with a dedicated
@@ -136,7 +163,7 @@ public static function getContainer() {
    *   The specified service.
    */
   public static function service($id) {
-    return static::$container->get($id);
+    return static::getContainer(TRUE)->get($id);
   }
 
   /**
@@ -149,7 +176,8 @@ public static function service($id) {
    *   TRUE if the specified service exists, FALSE otherwise.
    */
   public static function hasService($id) {
-    return static::$container && static::$container->has($id);
+    // Check hasContainer() first in order to always return a Boolean.
+    return static::hasContainer() && static::getContainer()->has($id);
   }
 
   /**
@@ -158,7 +186,7 @@ public static function hasService($id) {
    * @return string
    */
   public static function root() {
-    return static::$container->get('app.root');
+    return static::getContainer(TRUE)->get('app.root');
   }
 
   /**
@@ -168,7 +196,8 @@ public static function root() {
    *   TRUE if there is a currently active request object, FALSE otherwise.
    */
   public static function hasRequest() {
-    return static::$container && static::$container->has('request_stack') && static::$container->get('request_stack')->getCurrentRequest() !== NULL;
+    // Check hasContainer() first in order to always return a Boolean.
+    return static::hasContainer() && static::getContainer()->has('request_stack') && static::getContainer()->get('request_stack')->getCurrentRequest() !== NULL;
   }
 
   /**
@@ -194,7 +223,7 @@ public static function hasRequest() {
    *   The currently active request object.
    */
   public static function request() {
-    return static::$container->get('request_stack')->getCurrentRequest();
+    return static::getContainer(TRUE)->get('request_stack')->getCurrentRequest();
   }
 
   /**
@@ -204,7 +233,7 @@ public static function request() {
    *   The request stack
    */
   public static function requestStack() {
-    return static::$container->get('request_stack');
+    return static::getContainer(TRUE)->get('request_stack');
   }
 
   /**
@@ -214,7 +243,7 @@ public static function requestStack() {
    *   The currently active route match object.
    */
   public static function routeMatch() {
-    return static::$container->get('current_route_match');
+    return static::getContainer(TRUE)->get('current_route_match');
   }
 
   /**
@@ -223,7 +252,7 @@ public static function routeMatch() {
    * @return \Drupal\Core\Session\AccountProxyInterface
    */
   public static function currentUser() {
-    return static::$container->get('current_user');
+    return static::getContainer(TRUE)->get('current_user');
   }
 
   /**
@@ -233,7 +262,7 @@ public static function currentUser() {
    *   The entity manager service.
    */
   public static function entityManager() {
-    return static::$container->get('entity.manager');
+    return static::getContainer(TRUE)->get('entity.manager');
   }
 
   /**
@@ -243,7 +272,7 @@ public static function entityManager() {
    *   The current active database's master connection.
    */
   public static function database() {
-    return static::$container->get('database');
+    return static::getContainer(TRUE)->get('database');
   }
 
   /**
@@ -259,7 +288,7 @@ public static function database() {
    * @ingroup cache
    */
   public static function cache($bin = 'default') {
-    return static::$container->get('cache.' . $bin);
+    return static::getContainer(TRUE)->get('cache.' . $bin);
   }
 
   /**
@@ -272,7 +301,7 @@ public static function cache($bin = 'default') {
    *   An expirable key value store collection.
    */
   public static function keyValueExpirable($collection) {
-    return static::$container->get('keyvalue.expirable')->get($collection);
+    return static::getContainer(TRUE)->get('keyvalue.expirable')->get($collection);
   }
 
   /**
@@ -283,7 +312,7 @@ public static function keyValueExpirable($collection) {
    * @ingroup lock
    */
   public static function lock() {
-    return static::$container->get('lock');
+    return static::getContainer(TRUE)->get('lock');
   }
 
   /**
@@ -302,7 +331,7 @@ public static function lock() {
    *   An immutable configuration object.
    */
   public static function config($name) {
-    return static::$container->get('config.factory')->get($name);
+    return static::getContainer(TRUE)->get('config.factory')->get($name);
   }
 
   /**
@@ -316,7 +345,7 @@ public static function config($name) {
    *   The configuration factory service.
    */
   public static function configFactory() {
-    return static::$container->get('config.factory');
+    return static::getContainer(TRUE)->get('config.factory');
   }
 
   /**
@@ -342,7 +371,7 @@ public static function configFactory() {
    *   The queue object for a given name.
    */
   public static function queue($name, $reliable = FALSE) {
-    return static::$container->get('queue')->get($name, $reliable);
+    return static::getContainer(TRUE)->get('queue')->get($name, $reliable);
   }
 
   /**
@@ -354,7 +383,7 @@ public static function queue($name, $reliable = FALSE) {
    * @return \Drupal\Core\KeyValueStore\KeyValueStoreInterface
    */
   public static function keyValue($collection) {
-    return static::$container->get('keyvalue')->get($collection);
+    return static::getContainer(TRUE)->get('keyvalue')->get($collection);
   }
 
   /**
@@ -369,7 +398,7 @@ public static function keyValue($collection) {
    * @return \Drupal\Core\State\StateInterface
    */
   public static function state() {
-    return static::$container->get('state');
+    return static::getContainer(TRUE)->get('state');
   }
 
   /**
@@ -379,7 +408,7 @@ public static function state() {
    *   A guzzle http client instance.
    */
   public static function httpClient() {
-    return static::$container->get('http_client');
+    return static::getContainer(TRUE)->get('http_client');
   }
 
   /**
@@ -396,7 +425,7 @@ public static function httpClient() {
    *   The query object that can query the given entity type.
    */
   public static function entityQuery($entity_type, $conjunction = 'AND') {
-    return static::$container->get('entity.query')->get($entity_type, $conjunction);
+    return static::getContainer(TRUE)->get('entity.query')->get($entity_type, $conjunction);
   }
 
   /**
@@ -413,7 +442,7 @@ public static function entityQuery($entity_type, $conjunction = 'AND') {
    *   The query object that can query the given entity type.
    */
   public static function entityQueryAggregate($entity_type, $conjunction = 'AND') {
-    return static::$container->get('entity.query')->getAggregate($entity_type, $conjunction);
+    return static::getContainer(TRUE)->get('entity.query')->getAggregate($entity_type, $conjunction);
   }
 
   /**
@@ -422,7 +451,7 @@ public static function entityQueryAggregate($entity_type, $conjunction = 'AND')
    * @return \Drupal\Core\Flood\FloodInterface
    */
   public static function flood() {
-    return static::$container->get('flood');
+    return static::getContainer(TRUE)->get('flood');
   }
 
   /**
@@ -431,7 +460,7 @@ public static function flood() {
    * @return \Drupal\Core\Extension\ModuleHandlerInterface
    */
   public static function moduleHandler() {
-    return static::$container->get('module_handler');
+    return static::getContainer(TRUE)->get('module_handler');
   }
 
   /**
@@ -445,7 +474,7 @@ public static function moduleHandler() {
    * @see \Drupal\Core\TypedData\TypedDataManager::create()
    */
   public static function typedDataManager() {
-    return static::$container->get('typed_data_manager');
+    return static::getContainer(TRUE)->get('typed_data_manager');
   }
 
   /**
@@ -455,7 +484,7 @@ public static function typedDataManager() {
    *   The token service.
    */
   public static function token() {
-    return static::$container->get('token');
+    return static::getContainer(TRUE)->get('token');
   }
 
   /**
@@ -465,7 +494,7 @@ public static function token() {
    *   The url generator service.
    */
   public static function urlGenerator() {
-    return static::$container->get('url_generator');
+    return static::getContainer(TRUE)->get('url_generator');
   }
 
   /**
@@ -494,7 +523,7 @@ public static function urlGenerator() {
    * @see \Drupal\Core\Url::fromUri()
    */
   public static function url($route_name, $route_parameters = array(), $options = array()) {
-    return static::$container->get('url_generator')->generateFromRoute($route_name, $route_parameters, $options);
+    return static::getContainer(TRUE)->get('url_generator')->generateFromRoute($route_name, $route_parameters, $options);
   }
 
   /**
@@ -503,7 +532,7 @@ public static function url($route_name, $route_parameters = array(), $options =
    * @return \Drupal\Core\Utility\LinkGeneratorInterface
    */
   public static function linkGenerator() {
-    return static::$container->get('link_generator');
+    return static::getContainer(TRUE)->get('link_generator');
   }
 
   /**
@@ -525,7 +554,7 @@ public static function linkGenerator() {
    * @see \Drupal\Core\Url
    */
   public static function l($text, Url $url) {
-    return static::$container->get('link_generator')->generate($text, $url);
+    return static::getContainer(TRUE)->get('link_generator')->generate($text, $url);
   }
 
   /**
@@ -535,7 +564,7 @@ public static function l($text, Url $url) {
    *   The string translation manager.
    */
   public static function translation() {
-    return static::$container->get('string_translation');
+    return static::getContainer(TRUE)->get('string_translation');
   }
 
   /**
@@ -545,7 +574,7 @@ public static function translation() {
    *   The language manager.
    */
   public static function languageManager() {
-    return static::$container->get('language_manager');
+    return static::getContainer(TRUE)->get('language_manager');
   }
 
   /**
@@ -562,7 +591,7 @@ public static function languageManager() {
    * @see \Drupal\Core\Session\SessionManager::start()
    */
   public static function csrfToken() {
-    return static::$container->get('csrf_token');
+    return static::getContainer(TRUE)->get('csrf_token');
   }
 
   /**
@@ -572,7 +601,7 @@ public static function csrfToken() {
    *   The transliteration manager.
    */
   public static function transliteration() {
-    return static::$container->get('transliteration');
+    return static::getContainer(TRUE)->get('transliteration');
   }
 
   /**
@@ -582,7 +611,7 @@ public static function transliteration() {
    *   The form builder.
    */
   public static function formBuilder() {
-    return static::$container->get('form_builder');
+    return static::getContainer(TRUE)->get('form_builder');
   }
 
   /**
@@ -591,7 +620,7 @@ public static function formBuilder() {
    * @return \Drupal\Core\Theme\ThemeManagerInterface
    */
   public static function theme() {
-    return static::$container->get('theme.manager');
+    return static::getContainer(TRUE)->get('theme.manager');
   }
 
   /**
@@ -601,7 +630,7 @@ public static function theme() {
    *   Returns TRUE is syncing flag set.
    */
   public static function isConfigSyncing() {
-    return static::$container->get('config.installer')->isSyncing();
+    return static::getContainer(TRUE)->get('config.installer')->isSyncing();
   }
 
   /**
@@ -615,7 +644,7 @@ public static function isConfigSyncing() {
    *   The logger for this channel.
    */
   public static function logger($channel) {
-    return static::$container->get('logger.factory')->get($channel);
+    return static::getContainer(TRUE)->get('logger.factory')->get($channel);
   }
 
   /**
@@ -625,7 +654,7 @@ public static function logger($channel) {
    *   The menu tree.
    */
   public static function menuTree() {
-    return static::$container->get('menu.link_tree');
+    return static::getContainer(TRUE)->get('menu.link_tree');
   }
 
   /**
@@ -634,7 +663,7 @@ public static function menuTree() {
    * @return \Drupal\Core\Path\PathValidatorInterface
    */
   public static function pathValidator() {
-    return static::$container->get('path.validator');
+    return static::getContainer(TRUE)->get('path.validator');
   }
 
   /**
@@ -644,7 +673,7 @@ public static function pathValidator() {
    *   The access manager service.
    */
   public static function accessManager() {
-    return static::$container->get('access_manager');
+    return static::getContainer(TRUE)->get('access_manager');
   }
 
 }
diff --git a/core/lib/Drupal/Core/DependencyInjection/ContainerNotInitializedException.php b/core/lib/Drupal/Core/DependencyInjection/ContainerNotInitializedException.php
new file mode 100644
index 0000000..1ef7ebd
--- /dev/null
+++ b/core/lib/Drupal/Core/DependencyInjection/ContainerNotInitializedException.php
@@ -0,0 +1,18 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\DependencyInjection\ContainerNotInitializedException.
+ */
+
+namespace Drupal\Core\DependencyInjection;
+
+/**
+ * Exception thrown when a method is called that requires a container, but the
+ * container is not initialized yet.
+ *
+ * @see \Drupal
+ */
+class ContainerNotInitializedException extends \RuntimeException {
+
+}
diff --git a/core/modules/simpletest/src/TestBase.php b/core/modules/simpletest/src/TestBase.php
index b4901af..a6d1bf2 100644
--- a/core/modules/simpletest/src/TestBase.php
+++ b/core/modules/simpletest/src/TestBase.php
@@ -1187,7 +1187,7 @@ private function prepareEnvironment() {
 
     // Ensure there is no service container.
     $this->container = NULL;
-    \Drupal::setContainer(NULL);
+    \Drupal::unsetContainer();
 
     // Unset globals.
     unset($GLOBALS['config_directories']);
diff --git a/core/modules/system/src/Tests/Bootstrap/GetFilenameUnitTest.php b/core/modules/system/src/Tests/Bootstrap/GetFilenameUnitTest.php
index a7bcca7..43dee4f 100644
--- a/core/modules/system/src/Tests/Bootstrap/GetFilenameUnitTest.php
+++ b/core/modules/system/src/Tests/Bootstrap/GetFilenameUnitTest.php
@@ -19,7 +19,7 @@ class GetFilenameUnitTest extends KernelTestBase {
   protected function setUp() {
     parent::setUp();
     $this->container = NULL;
-    \Drupal::setContainer(NULL);
+    \Drupal::unsetContainer();
   }
 
   /**
diff --git a/core/tests/Drupal/Tests/Core/DrupalContainerNotInitializedTest.php b/core/tests/Drupal/Tests/Core/DrupalContainerNotInitializedTest.php
new file mode 100644
index 0000000..9bdf238
--- /dev/null
+++ b/core/tests/Drupal/Tests/Core/DrupalContainerNotInitializedTest.php
@@ -0,0 +1,112 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Tests\Core\DrupalTest.
+ */
+
+namespace Drupal\Tests\Core;
+
+use Drupal\Core\DependencyInjection\ContainerNotInitializedException;
+use Drupal\Core\Url;
+
+/**
+ * Tests the case where Drupal::$container is not initialized.
+ *
+ * @group DrupalTest
+ */
+class DrupalContainerNotInitializedTest extends \PHPUnit_Framework_TestCase {
+
+  /**
+   * Tests the case where \Drupal::$container is not initialized.
+   *
+   * @dataProvider methodsWithExceptionProvider
+   *
+   * @param string $method
+   *   The static method to call on \Drupal::
+   * @param array $args
+   *   Arguments to pass into \Drupal::$method(..)
+   *
+   * @expectedException \Drupal\Core\DependencyInjection\ContainerNotInitializedException
+   * @expectedExceptionMessage \Drupal::$container is not initialized yet. \Drupal::setContainer() must be called with a real container.
+   */
+  public function testContainerNotInitializedException($method, $args = array()) {
+    call_user_func_array(['Drupal', $method], $args);
+  }
+
+  /**
+   * Tests the case where \Drupal::$container was unset.
+   *
+   * @dataProvider methodsWithExceptionProvider
+   *
+   * @param string $method
+   *   The static method to call on \Drupal::
+   * @param array $args
+   *   Arguments to pass into \Drupal::$method(..)
+   *
+   * @expectedException \Drupal\Core\DependencyInjection\ContainerNotInitializedException
+   * @expectedExceptionMessage \Drupal::$container is not initialized yet. \Drupal::setContainer() must be called with a real container.
+   */
+  public function testUnsetContainerException($method, $args = array()) {
+    \Drupal::unsetContainer();
+    call_user_func_array(['Drupal', $method], $args);
+  }
+
+  /**
+   * Data provider for two methods, see "@see" below.
+   *
+   * @return array[]
+   *
+   * @see testContainerNotInitializedException()
+   * @see testUnsetContainerException()
+   */
+  public function methodsWithExceptionProvider() {
+    return array(
+      ['service', ['test_service']],
+      ['request'],
+      ['requestStack'],
+      ['routeMatch'],
+      ['currentUser'],
+      ['entityManager'],
+      ['database'],
+      ['cache', ['test']],
+      ['keyValueExpirable', ['test_collection']],
+      ['lock'],
+      ['config', ['test_config']],
+      ['configFactory'],
+      ['queue', ['test_queue', TRUE]],
+      ['keyValue', ['test_collection']],
+      ['state'],
+      ['httpClient'],
+      ['entityQuery', ['OR']],
+      ['entityQueryAggregate', ['test_entity', 'OR']],
+      ['flood', ['test_service']],
+      ['moduleHandler', ['test_service']],
+      ['typedDataManager', ['test_service']],
+      ['token'],
+      ['urlGenerator'],
+      ['url', ['test_route']],
+      ['linkGenerator'],
+      ['l', ['Test title', new Url('test_route')]],
+      ['translation'],
+      ['languageManager'],
+      ['csrfToken'],
+      ['transliteration'],
+      ['formBuilder'],
+      ['theme'],
+      ['isConfigSyncing'],
+      ['logger', ['test_channel']],
+      ['menuTree'],
+      ['pathValidator'],
+      ['accessManager'],
+    );
+  }
+
+  /**
+   * @expectedException \Drupal\Core\DependencyInjection\ContainerNotInitializedException
+   */
+  public function testGetContainerException() {
+    \Drupal::getContainer(TRUE);
+  }
+
+}
diff --git a/core/tests/Drupal/Tests/UnitTestCase.php b/core/tests/Drupal/Tests/UnitTestCase.php
index d6deb9e..e82c3a9 100644
--- a/core/tests/Drupal/Tests/UnitTestCase.php
+++ b/core/tests/Drupal/Tests/UnitTestCase.php
@@ -39,7 +39,7 @@ protected function setUp() {
     parent::setUp();
     // Ensure that an instantiated container in the global state of \Drupal from
     // a previous test does not leak into this test.
-    \Drupal::setContainer(NULL);
+    \Drupal::unsetContainer();
 
     $this->root = dirname(dirname(substr(__DIR__, 0, -strlen(__NAMESPACE__))));
   }
