diff --git c/core/modules/system/lib/Drupal/system/Controller/BatchController.php w/core/modules/system/lib/Drupal/system/Controller/BatchController.php
new file mode 100644
index 0000000..718fec4
--- /dev/null
+++ w/core/modules/system/lib/Drupal/system/Controller/BatchController.php
@@ -0,0 +1,48 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\system\Controller\BatchController.
+ */
+
+namespace Drupal\system\Controller;
+
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\HttpFoundation\Response;
+use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
+
+/**
+ * Controller routines for batch routes.
+ */
+class BatchController {
+
+  /**
+   * Returns a system batch page.
+   *
+   * @param \Symfony\Component\HttpFoundation\Request
+   *   The current request object.
+   *
+   * @return mixed
+   *   A \Symfony\Component\HttpFoundation\Response object or page element.
+   */
+  public function batchPage(Request $request) {
+    require_once DRUPAL_ROOT . '/core/includes/batch.inc';
+    $output = _batch_page();
+
+    if ($output === FALSE) {
+      throw new AccessDeniedHttpException();
+    }
+    elseif ($output instanceof Response) {
+      return $output;
+    }
+    elseif (isset($output)) {
+      // Force a page without blocks or messages to
+      // display a list of collected messages later.
+      drupal_set_page_content($output);
+      $page = element_info('page');
+      $page['#show_messages'] = FALSE;
+      return $page;
+    }
+  }
+
+}
diff --git c/core/modules/system/system.admin.inc w/core/modules/system/system.admin.inc
index 9db20be..cefffd1 100644
--- c/core/modules/system/system.admin.inc
+++ w/core/modules/system/system.admin.inc
@@ -274,29 +274,6 @@ function system_sort_themes($a, $b) {
 }
 
 /**
- * Default page callback for batches.
- */
-function system_batch_page() {
-  require_once DRUPAL_ROOT . '/core/includes/batch.inc';
-  $output = _batch_page();
-
-  if ($output === FALSE) {
-    throw new AccessDeniedHttpException();
-  }
-  elseif ($output instanceof Response) {
-    return $output;
-  }
-  elseif (isset($output)) {
-    // Force a page without blocks or messages to
-    // display a list of collected messages later.
-    drupal_set_page_content($output);
-    $page = element_info('page');
-    $page['#show_messages'] = FALSE;
-    return $page;
-  }
-}
-
-/**
  * Returns HTML for an administrative block for display.
  *
  * @param $variables
diff --git c/core/modules/system/system.module w/core/modules/system/system.module
index 358d332..88e7da2 100644
--- c/core/modules/system/system.module
+++ w/core/modules/system/system.module
@@ -894,11 +894,9 @@ function system_menu() {
 
   // Default page for batch operations.
   $items['batch'] = array(
-    'page callback' => 'system_batch_page',
-    'access callback' => TRUE,
+    'route_name' => 'system_batch_page',
     'theme callback' => '_system_batch_theme',
     'type' => MENU_CALLBACK,
-    'file' => 'system.admin.inc',
   );
 
   // Localize date formats.
diff --git c/core/modules/system/system.routing.yml w/core/modules/system/system.routing.yml
index a3bf62b..b014b09 100644
--- c/core/modules/system/system.routing.yml
+++ w/core/modules/system/system.routing.yml
@@ -326,3 +326,10 @@ system_admin_config:
     _content: '\Drupal\system\Controller\SystemController::overview'
   requirements:
     _permission: 'access administration pages'
+
+system_batch_page:
+  pattern: '/batch'
+  defaults:
+    _controller: '\Drupal\system\Controller\BatchController::batchPage'
+  requirements:
+    _access: 'TRUE'
