diff --git a/composer.json b/composer.json
index eb68ef66c17cb125e879cbebd3a351cad37cb3d2..f64b56ec43bce802f87ea360a8326f4a94a10b94 100644
--- a/composer.json
+++ b/composer.json
@@ -29,8 +29,8 @@
         "ezyang/htmlpurifier": "^4.13",
         "davefx/phplot": "^6.2",
         "jasig/phpcas": "1.5",
-        "phpxmlrpc/phpxmlrpc": "^4.4",
-        "phpxmlrpc/extras": "^0.6.2",
+        "phpxmlrpc/phpxmlrpc": "^4.9.0",
+        "phpxmlrpc/extras": "^1.0.0-beta2",
         "algo26-matthias/idna-convert": "^3.0",
         "caxy/php-htmldiff": "^0.1.9",
         "phpseclib/phpseclib": "^3",
diff --git a/composer.lock b/composer.lock
index 8728c585ed7ebd5e2eb37eb919e06190dd05ca26..b078b59467b2de25ec7fce5df10792901d7e27a0 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,7 +4,7 @@
         "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
         "This file is @generated automatically"
     ],
-    "content-hash": "22c8ced6418b6f7255376553aa8bac48",
+    "content-hash": "b39a0d6902b667c47851b3899c5884fc",
     "packages": [
         {
             "name": "algo26-matthias/idna-convert",
@@ -2183,42 +2183,44 @@
         },
         {
             "name": "phpxmlrpc/extras",
-            "version": "0.6.3",
+            "version": "1.0.0-beta2",
             "source": {
                 "type": "git",
                 "url": "https://github.com/gggeek/phpxmlrpc-extras.git",
-                "reference": "63b53c9bece968f87ddfc058d4bf9e3cd5ae9930"
+                "reference": "4bf48852955f7b4698b37ae91cce83c49f658b4c"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/gggeek/phpxmlrpc-extras/zipball/63b53c9bece968f87ddfc058d4bf9e3cd5ae9930",
-                "reference": "63b53c9bece968f87ddfc058d4bf9e3cd5ae9930",
+                "url": "https://api.github.com/repos/gggeek/phpxmlrpc-extras/zipball/4bf48852955f7b4698b37ae91cce83c49f658b4c",
+                "reference": "4bf48852955f7b4698b37ae91cce83c49f658b4c",
                 "shasum": ""
             },
             "require": {
-                "phpxmlrpc/phpxmlrpc": ">=2.1.0"
+                "php": "^5.3.0 || ^7.0 || ^8.0",
+                "phpxmlrpc/phpxmlrpc": "^4.6.0"
             },
             "require-dev": {
-                "phpunit/phpunit": ">=4.0.0"
+                "ext-curl": "*",
+                "phpunit/phpunit": "^4.8 || ^5.0 || ^8.5.12",
+                "phpunit/phpunit-selenium": "*",
+                "phpxmlrpc/jsonrpc": "^1.0.0-beta1",
+                "yoast/phpunit-polyfills": "*"
+            },
+            "suggest": {
+                "phpxmlrpc/jsonrpc": "Needed for the SonOfAjax demo",
+                "phpxmlrpc/jsxmlrpc": "Used the Ajax Server component. NB: better installed via NPM or used directly from CDN!"
             },
             "type": "library",
             "autoload": {
-                "classmap": [
-                    "adodb/drivers/",
-                    "adodb/lib/",
-                    "ajax/ajaxmlrpc.inc",
-                    "jsonrpc/jsonrpc.inc",
-                    "jsonrpc/jsonrpcs.inc",
-                    "proxy/proxyxmlrpcs.inc",
-                    "xmlrpc_extension_api/xmlrpc_extension_api.inc",
-                    "docxmlrpcserver/docxmlrpcs.inc"
-                ]
+                "psr-4": {
+                    "PhpXmlRpc\\Extras\\": "src/"
+                }
             },
             "notification-url": "https://packagist.org/downloads/",
             "license": [
                 "BSD-3-Clause"
             ],
-            "description": "A collection of extensions, addons and other stuff that might be of use for development of xml-rpc (and jsonrpc, soap) based applications",
+            "description": "A collection of server-side addons that might be of use for development of xml-rpc (and json-rpc) based applications",
             "homepage": "https://github.com/gggeek/phpxmlrpc-extras",
             "keywords": [
                 "jsonrpc",
@@ -2227,44 +2229,45 @@
             ],
             "support": {
                 "issues": "https://github.com/gggeek/phpxmlrpc-extras/issues",
-                "source": "https://github.com/gggeek/phpxmlrpc-extras/tree/0.6.3"
+                "source": "https://github.com/gggeek/phpxmlrpc-extras/tree/1.0.0-beta2"
             },
-            "time": "2020-12-23T16:41:17+00:00"
+            "time": "2023-01-19T14:20:38+00:00"
         },
         {
             "name": "phpxmlrpc/phpxmlrpc",
-            "version": "4.4.3",
+            "version": "4.10.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/gggeek/phpxmlrpc.git",
-                "reference": "eea038c58b32b35df93cbf5e96cf186321dd09d7"
+                "reference": "7103864975ca0b930574cabc8b4593093ee4432e"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/gggeek/phpxmlrpc/zipball/eea038c58b32b35df93cbf5e96cf186321dd09d7",
-                "reference": "eea038c58b32b35df93cbf5e96cf186321dd09d7",
+                "url": "https://api.github.com/repos/gggeek/phpxmlrpc/zipball/7103864975ca0b930574cabc8b4593093ee4432e",
+                "reference": "7103864975ca0b930574cabc8b4593093ee4432e",
                 "shasum": ""
             },
             "require": {
                 "ext-xml": "*",
-                "php": ">=5.3.0"
+                "php": "^5.4.0 || ^7.0 || ^8.0"
+            },
+            "conflict": {
+                "phpxmlrpc/extras": "<= 0.6.3"
             },
             "require-dev": {
-                "docbook/docbook-xsl": "^1.79",
                 "ext-curl": "*",
                 "ext-dom": "*",
                 "ext-mbstring": "*",
-                "ext-xsl": "*",
-                "indeyets/pake": "^1.99",
-                "phpunit/phpunit": "^5.0 || ^8.5.12",
+                "phpunit/phpunit": "^4.8 || ^5.0 || ^8.5.14",
                 "phpunit/phpunit-selenium": "*",
                 "yoast/phpunit-polyfills": "*"
             },
             "suggest": {
-                "ext-curl": "Needed for HTTPS and HTTP 1.1 support, NTLM Auth etc...",
+                "ext-curl": "Needed for HTTPS, HTTP2 and HTTP 1.1 support, NTLM Auth etc...",
                 "ext-mbstring": "Needed to allow reception of requests/responses in character sets other than ASCII,LATIN-1,UTF-8",
                 "ext-zlib": "Needed for sending compressed requests and receiving compressed responses, if cURL is not available",
-                "sami/sami": "Required for doc generation using pake. Version constraints: ^3.3 || ^4.1"
+                "phpxmlrpc/extras": "Adds more featured Server classes, including self-documenting and ajax-enabled servers",
+                "phpxmlrpc/jsonrpc": "Adds support for the JSON-RPC protocol"
             },
             "type": "library",
             "autoload": {
@@ -2280,13 +2283,14 @@
             "homepage": "https://gggeek.github.io/phpxmlrpc/",
             "keywords": [
                 "webservices",
+                "xml-rpc",
                 "xmlrpc"
             ],
             "support": {
                 "issues": "https://github.com/gggeek/phpxmlrpc/issues",
-                "source": "https://github.com/gggeek/phpxmlrpc/tree/4.4.3"
+                "source": "https://github.com/gggeek/phpxmlrpc/tree/4.10.0"
             },
-            "time": "2020-12-16T23:25:16+00:00"
+            "time": "2023-02-11T17:10:30+00:00"
         },
         {
             "name": "psr/container",
@@ -7343,7 +7347,9 @@
     ],
     "aliases": [],
     "minimum-stability": "stable",
-    "stability-flags": [],
+    "stability-flags": {
+        "phpxmlrpc/extras": 10
+    },
     "prefer-stable": false,
     "prefer-lowest": false,
     "platform": {
diff --git a/lib/webservices/webservices_bootstrap.php b/lib/webservices/webservices_bootstrap.php
index 8844b19151dffa65abefa054b8667b349c44bdc0..538d2b979fa95d9440b3db88f040e25cd392b931 100644
--- a/lib/webservices/webservices_bootstrap.php
+++ b/lib/webservices/webservices_bootstrap.php
@@ -23,10 +23,6 @@ require_once 'vendor/studip_ws/soap_dispatcher.php';
 require_once 'vendor/studip_ws/studip_ws.php';
 require_once 'vendor/studip_ws/xmlrpc_dispatcher.php';
 
-# requiring jsonrpc_dispatcher
-require_once 'vendor/studip_ws/studip_ws.php';
-require_once 'vendor/studip_ws/jsonrpc_dispatcher.php';
-
 # requiring all the webservices
 require_once 'lib/webservices/services/access_controlled_webservice.php';
 require_once 'lib/webservices/services/user_webservice.php';
diff --git a/public/jsonrpc.php b/public/jsonrpc.php
deleted file mode 100644
index 3a6c5c09a5234f6b19cbd91a2b308cdea57a334f..0000000000000000000000000000000000000000
--- a/public/jsonrpc.php
+++ /dev/null
@@ -1,28 +0,0 @@
-<?php
-# Lifter002: TODO
-# Lifter007: TODO
-# Lifter003: TODO
-# Lifter010: TODO
-
-/*
- * jsonrpc.php - JSON-RPC Backend for Stud.IP web services
- *
- * Copyright (C) 2006 - Marcus Lunzenauer <mlunzena@uos.de>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- */
-
-require '../lib/bootstrap.php';
-require '../lib/webservices/webservices_bootstrap.php';
-
-# create server
-$dispatcher = new Studip_Ws_JsonrpcDispatcher($AVAILABLE_SERVICES);
-$server = new jsonrpc_server($dispatcher->get_dispatch_map(), 0);
-# $server->setDebug(3);
-# $server->compress_response = FALSE;
-
-# start server
-$server->service();
diff --git a/public/xmlrpc.php b/public/xmlrpc.php
index d2a8e14a10ab6ff3c5f333c3577604dab75b0d04..8c0ffa632f01a9717dd749697f708c1028be2e45 100644
--- a/public/xmlrpc.php
+++ b/public/xmlrpc.php
@@ -15,11 +15,14 @@
  * the License, or (at your option) any later version.
  */
 
+use PhpXmlRpc\Extras\XmlrpcSmartyTemplate;
+use PhpXmlRpc\PhpXmlRpc;
+
 require '../lib/bootstrap.php';
 require '../lib/webservices/webservices_bootstrap.php';
 
 // Bootstrap documenting server
-class StudipDocumentingXmlRpcServer extends documenting_xmlrpc_server
+class StudipDocumentingXmlRpcServer extends \PhpXmlRpc\Extras\SelfDocumentingServer
 {
     public function checkAuth()
     {
@@ -45,27 +48,35 @@ class StudipDocumentingXmlRpcServer extends documenting_xmlrpc_server
         return parent::service($data, $return_payload, $doctype);
     }
 
-    public function generateDocs($server, $doctype='html', $lang='en', $editorpath='')
+    public function generateDocs($doctype='html', $lang='en', $editorpath='')
     {
         if ($doctype === 'html' && isset($_GET['methodName'])) {
             $_GET['methodName'] = preg_replace('/[^a-zA-Z0-9_.:\/]/', '', $_GET['methodName']);
         }
 
-        parent::generateDocs($server, $doctype, $lang, $editorpath);
+        $documentationGenerator = new StudipServerDocumentor(new XmlrpcSmartyTemplate(null));
+        return $documentationGenerator->generateDocs($this, $doctype, $lang, $editorpath);
     }
+}
 
-    public function __get($key)
+class StudipServerDocumentor extends \PhpXmlRpc\Extras\ServerDocumentor
+{
+    public static function templates()
     {
-        if ($key === 'dmap') {
-            return $this->allow_system_funcs
-                 ? array_merge($this->dmap, $this->getSystemDispatchMap())
-                 : $this->dmap;
-        }
+        return array_merge(parent::templates(), [
+            'docheader' => '<!DOCTYPE html>
+<html lang="{$lang}">
+<head>
+<meta name="generator" content="' . PhpXmlRpc::$xmlrpcName . '" />
+<link href="assets/stylesheets/webservices.css" type="text/css" rel="stylesheet" />
+{$extras}
+<title>{$title}</title>
+</head>
+<body>',
+        ]);
     }
 }
 
-$GLOBALS['_xmlrpcs_dmap'] = [];
-$GLOBALS['xmlrpcdocparts']['html']['docheader'] .= '<link href="assets/stylesheets/webservices.css" type="text/css" rel="stylesheet">';
 
 # create server
 $dispatcher = new Studip_Ws_XmlrpcDispatcher($AVAILABLE_SERVICES);
diff --git a/vendor/studip_ws/jsonrpc_dispatcher.php b/vendor/studip_ws/jsonrpc_dispatcher.php
deleted file mode 100644
index 91cddae6e803b06721aec85c3bdc50ca22ab1400..0000000000000000000000000000000000000000
--- a/vendor/studip_ws/jsonrpc_dispatcher.php
+++ /dev/null
@@ -1,154 +0,0 @@
-<?php
-
-/*
- * jsonrpc_dispatcher.php - <short-description>
- *
- * Copyright (C) 2006 - Marcus Lunzenauer <mlunzena@uos.de>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- */
-
-
-/**
- * <ClassDescription>
- *
- * @package     studip
- * @subpackage  ws
- *
- * @author    mlunzena
- * @copyright (c) Authors
- * @version   $Id: jsonrpc_dispatcher.php 3888 2006-09-06 13:27:19Z mlunzena $
- */
-
-class Studip_Ws_JsonrpcDispatcher extends Studip_Ws_Dispatcher {
-  
-
-  /**
-   * <MethodDescription>
-   *
-   * @param type <description>
-   *
-   * @return type <description>
-   */
-  function dispatch($msg = NULL) {
-    
-    # ensure correct invocation
-    if (is_null($msg) || !is_a($msg, 'jsonrpcmsg'))
-      return $this->throw_exception('functions_parameters_type must not be '.
-                                    'phpvals.');
-
-    # get decoded parameters
-    $len = $msg->getNumParams();
-    $argument_array = array();
-    for ($i = 0; $i < $len; ++$i)
-      $argument_array[] = php_jsonrpc_decode($msg->getParam($i));
-
-    # return result
-    return new jsonrpcresp(
-      php_jsonrpc_encode($this->invoke($msg->method(), $argument_array))); 
-  }
-  
-
-  /**
-   * <MethodDescription>
-   *
-   * @param type <description>
-   *
-   * @return type <description>
-   */
-  function throw_exception($message/*, ...*/) {
-    $args = func_get_args();
-    return new jsonrpcresp(0, $GLOBALS['xmlrpcerruser'] + 1,
-                          vsprintf(array_shift($args), $args));
-  }
-
-
-  /**
-   * Class method that composes the dispatch map from the available methods.
-   *
-   * @return array This service's dispatch map.
-   *
-   */
-  function get_dispatch_map() {
-    $dispatch_map = array();
-    foreach ($this->api_methods as $method_name => $method)
-      $dispatch_map[$method_name] = $this->map_method($method);
-    return $dispatch_map;
-  }
-  
-  
-  /**
-   * <MethodDescription>
-   *
-   * @param type <description>
-   *
-   * @return type <description>
-   */
-  function map_method($method) {
-
-    # TODO validate method
-
-    ## 1. function
-    $function = array(&$this, 'dispatch');
-
-    ## 2. signature
-    $signature = array(array());
-
-    # return value
-    $signature[0][] = $this->translate_type($method->returns);
-
-    # arguments
-    foreach ($method->expects as $type)
-      $signature[0][] = $this->translate_type($type);
-      
-    ## 3. docstring
-    $docstring = $method->description;
-
-    return compact('function', 'signature', 'docstring');
-  }
-
-
-  /**
-   * <MethodDescription>
-   *
-   * @param type <description>
-   *
-   * @return type <description>
-   */
-  function translate_type($type0) {
-
-    switch ($type = Studip_Ws_Type::get_type($type0)) {
-      case STUDIP_WS_TYPE_INT:
-                                  return $GLOBALS['xmlrpcInt'];
-
-      case STUDIP_WS_TYPE_STRING:
-                                  return $GLOBALS['xmlrpcString'];
-
-      case STUDIP_WS_TYPE_BASE64:
-                                  return $GLOBALS['xmlrpcBase64'];
-
-      case STUDIP_WS_TYPE_BOOL:
-                                  return $GLOBALS['xmlrpcBoolean'];
-
-      case STUDIP_WS_TYPE_FLOAT:
-                                  return $GLOBALS['xmlrpcDouble'];
-
-      case STUDIP_WS_TYPE_NULL:
-                                  return $GLOBALS['xmlrpcBoolean'];
-
-      case STUDIP_WS_TYPE_ARRAY:
-                                  return $GLOBALS['xmlrpcArray'];
-
-      case STUDIP_WS_TYPE_STRUCT:
-                                  return $GLOBALS['xmlrpcStruct'];
-    }
-
-    trigger_error(sprintf('Type %s could not be found.', 
-                          var_export($type, TRUE)),
-                  E_USER_ERROR);
-    return $GLOBALS['xmlrpcString'];
-  }
-}