diff --git a/pom.xml b/pom.xml
index 73877cbc31b7c6e72c69321f0d04819751452995..c76d397b8fc1e655f1cf0fbf675e3b549eea876a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -56,6 +56,17 @@
       <url>file:///${project.basedir}/.m2-local</url>
     </repository>
   </repositories>
+  <dependencyManagement>
+    <dependencies>
+      <dependency>
+        <groupId>org.junit</groupId>
+        <artifactId>junit-bom</artifactId>
+        <version>5.9.0</version>
+        <type>pom</type>
+        <scope>import</scope>
+      </dependency>
+    </dependencies>
+  </dependencyManagement>
   <dependencies>
     <dependency>
       <groupId>de.timmfitschen</groupId>
@@ -78,9 +89,8 @@
       <version>1.8.0</version>
     </dependency>
     <dependency>
-      <groupId>junit</groupId>
-      <artifactId>junit</artifactId>
-      <version>4.12</version>
+      <groupId>org.junit.jupiter</groupId>
+      <artifactId>junit-jupiter</artifactId>
       <scope>test</scope>
     </dependency>
     <dependency>
@@ -222,7 +232,9 @@
     <resources>
       <resource>
         <directory>${basedir}/src/main/</directory>
-        <includes><include>**/*.properties</include></includes>
+        <includes>
+          <include>**/*.properties</include>
+        </includes>
       </resource>
     </resources>
     <sourceDirectory>${basedir}/src/main/java</sourceDirectory>
diff --git a/src/main/java/org/caosdb/server/database/access/AbstractAccess.java b/src/main/java/org/caosdb/server/database/access/AbstractAccess.java
index 9d00a876e8db21446b88b6ab00dfeb12ee043c0d..1d30bd3fee7187b9c44378e5b94c1c6d97287f00 100644
--- a/src/main/java/org/caosdb/server/database/access/AbstractAccess.java
+++ b/src/main/java/org/caosdb/server/database/access/AbstractAccess.java
@@ -77,7 +77,13 @@ public abstract class AbstractAccess<T extends TransactionInterface> implements
   public void setUseCache(final Boolean useCache) {
     this.useCache = useCache;
   }
-
+  /**
+   * Whether the transaction allows to use the query cache or other caches. This is controlled by
+   * the "cache" flag.
+   *
+   * @see {@link NoCache}
+   * @return true if caching is encouraged.
+   */
   @Override
   public boolean useCache() {
     return this.useCache;
diff --git a/src/main/java/org/caosdb/server/query/Backreference.java b/src/main/java/org/caosdb/server/query/Backreference.java
index fec64b19b761418a4da148ca4adff9d9145960af..7d551fd45e761a54d2c2508dcbb1b98ffc72891c 100644
--- a/src/main/java/org/caosdb/server/query/Backreference.java
+++ b/src/main/java/org/caosdb/server/query/Backreference.java
@@ -130,7 +130,7 @@ public class Backreference implements EntityFilterInterface, QueryInterface {
         callApplyBackRef.setNull(2, VARCHAR);
       }
       if (this.propertiesTable != null) { // propertiesTable
-        getQuery().filterEntitiesWithoutRetrievePermission(this.propertiesTable);
+        getQuery().filterIntermediateResult(this.propertiesTable);
         callApplyBackRef.setString(3, this.propertiesTable);
         this.statistics.put("propertiesTable", this.propertiesTable);
         this.statistics.put(
@@ -140,7 +140,7 @@ public class Backreference implements EntityFilterInterface, QueryInterface {
         callApplyBackRef.setNull(3, VARCHAR);
       }
       if (this.entitiesTable != null) { // entitiesTable
-        getQuery().filterEntitiesWithoutRetrievePermission(this.entitiesTable);
+        getQuery().filterIntermediateResult(this.entitiesTable);
         callApplyBackRef.setString(4, this.entitiesTable);
         this.statistics.put("entitiesTable", this.entitiesTable);
         this.statistics.put(
diff --git a/src/main/java/org/caosdb/server/query/Query.java b/src/main/java/org/caosdb/server/query/Query.java
index 07a165a352ba9a07a345018e7d287cd961f4a00b..81a08a9dbecbd28195172df55dfdd600ae24e53b 100644
--- a/src/main/java/org/caosdb/server/query/Query.java
+++ b/src/main/java/org/caosdb/server/query/Query.java
@@ -50,12 +50,12 @@ import org.caosdb.api.entity.v1.MessageCode;
 import org.caosdb.datetime.UTCDateTime;
 import org.caosdb.server.CaosDBServer;
 import org.caosdb.server.ServerProperties;
+import org.caosdb.server.accessControl.Principal;
 import org.caosdb.server.caching.Cache;
 import org.caosdb.server.database.access.Access;
 import org.caosdb.server.database.backend.implementation.MySQL.ConnectionException;
 import org.caosdb.server.database.backend.implementation.MySQL.MySQLHelper;
 import org.caosdb.server.database.backend.transaction.RetrieveSparseEntity;
-import org.caosdb.server.database.exceptions.TransactionException;
 import org.caosdb.server.database.misc.DBHelper;
 import org.caosdb.server.database.misc.TransactionBenchmark;
 import org.caosdb.server.entity.Entity;
@@ -70,6 +70,8 @@ import org.caosdb.server.permissions.EntityPermission;
 import org.caosdb.server.query.CQLParser.CqContext;
 import org.caosdb.server.query.CQLParsingErrorListener.ParsingError;
 import org.caosdb.server.transaction.TransactionInterface;
+import org.caosdb.server.transaction.WriteTransaction;
+import org.caosdb.server.utils.ResultSetIterator;
 import org.jdom2.Element;
 import org.slf4j.Logger;
 
@@ -211,14 +213,17 @@ public class Query implements QueryInterface, ToElementable, TransactionInterfac
     }
   }
 
-  public static class IdVersionPair {
-    public IdVersionPair(final Integer id, final String version) {
+  /** A data class for storing triplets of (Entity ID, version hash, ACL string) */
+  public static class IdVersionAclTriplet {
+    public IdVersionAclTriplet(final Integer id, final String version, final String acl) {
       this.id = id;
       this.version = version;
+      this.acl = acl;
     }
 
     public Integer id;
     public String version;
+    public String acl;
 
     @Override
     public String toString() {
@@ -230,9 +235,16 @@ public class Query implements QueryInterface, ToElementable, TransactionInterfac
 
     @Override
     public boolean equals(final Object obj) {
-      if (obj instanceof IdVersionPair) {
-        final IdVersionPair that = (IdVersionPair) obj;
-        return this.id == that.id && this.version == that.version;
+      if (obj instanceof IdVersionAclTriplet) {
+        final IdVersionAclTriplet that = (IdVersionAclTriplet) obj;
+        // checking ID and version hash should be sufficient
+        if (this.id == that.id && this.version == that.version) {
+          if (this.acl != that.acl) {
+            throw new RuntimeException("Implementation error! ACL should not differ");
+          }
+          return true;
+        }
+        ;
       }
       return false;
     }
@@ -249,7 +261,7 @@ public class Query implements QueryInterface, ToElementable, TransactionInterfac
           .equalsIgnoreCase("FALSE");
 
   private final Logger logger = org.slf4j.LoggerFactory.getLogger(getClass());
-  List<IdVersionPair> resultSet = null;
+  List<IdVersionAclTriplet> resultSet = null;
   private final String query;
   private Pattern entity = null;
   private Role role = null;
@@ -265,6 +277,18 @@ public class Query implements QueryInterface, ToElementable, TransactionInterfac
   private final ArrayList<ToElementable> messages = new ArrayList<>();
   private Access access;
   private boolean versioned = false;
+  /**
+   * This key-value cache stores lists of of (id, version hash, acl string) triplets. Those values
+   * are the result sets of queries. The keys are created such that they are different for different
+   * for different queries (@see {@link #getCacheKey}). The key includes realm and username of a
+   * subject, if the query result must not be shared among users. If intermediate permission checks
+   * are done (e.g. in a subproperty query filter), the query result will be stored using a user
+   * specific key. The final permission check has not yet been applied to the result set that is
+   * stored in the cache. This allows (some) cache entries to be shared among users since the final
+   * check is applied after the retrieval of the result set from the cache (@see {@link
+   * filterEntitiesWithoutRetrievePermission}) The cache is invalidated whenever there is a write
+   * operation (@see {@link #clearCache} which is called in the {@link WriteTransaction#commit}).
+   */
   private static ICacheAccess<String, Serializable> cache =
       Cache.getCache("HIGH_LEVEL_QUERY_CACHE");
   /** Cached=true means that the results of this query have actually been pulled from the cache. */
@@ -274,7 +298,7 @@ public class Query implements QueryInterface, ToElementable, TransactionInterfac
    * query evaluation contains complex permission checking which could only be cached on a per-user
    * basis (maybe in the future).
    */
-  private boolean cachable = true;
+  private boolean filteredIntermediateResult = false;
 
   /**
    * Tags the query cache and is renewed each time the cache is being cleared, i.e. each time the
@@ -367,17 +391,16 @@ public class Query implements QueryInterface, ToElementable, TransactionInterfac
       return this.sourceSet;
     } catch (final SQLException e) {
       e.printStackTrace();
-      throw new TransactionException(e);
+      throw new QueryException(e);
     }
   }
 
   /**
-   * Finds all QueryTemplates in the resultSet and applies them to the same resultSet. The ids of
+   * Finds all QueryTemplates in the resultSet and applies them to the same resultSet. The IDs of
    * the QueryTemplates themselves are then removed from the resultSet. If the current user doesn't
    * have the RETRIEVE:ENTITY permission for a particular QueryTemplate it will be ignored.
    *
    * @param resultSet
-   * @throws SQLException
    * @throws QueryException
    */
   public void applyQueryTemplates(final QueryInterface query, final String resultSet)
@@ -415,7 +438,7 @@ public class Query implements QueryInterface, ToElementable, TransactionInterfac
         union(query, resultSet, subResultSet);
       }
     } catch (final SQLException e) {
-      throw new TransactionException(e);
+      throw new QueryException(e);
     }
   }
 
@@ -567,7 +590,7 @@ public class Query implements QueryInterface, ToElementable, TransactionInterfac
    *
    * <ol>
    *   <li>FIND * -> FIND ENTITY (which basically prevents to copy the complete entity table just to
-   *       read out the ids immediately).
+   *       read out the IDs immediately).
    * </ol>
    */
   public void optimize() {
@@ -593,33 +616,47 @@ public class Query implements QueryInterface, ToElementable, TransactionInterfac
   }
 
   /**
-   * Generate a SQL statement which reads out the resulting ids (and version ids if `versioned` is
-   * true).
+   * Generate a SQL statement which reads out the resulting IDs and ACL strings (and version IDs if
+   * `versioned` is true).
    *
-   * <p>If the parameter `resultSetTableName` is "entities" actually the entity_version table is
-   * used to fetch all ids.
+   * <p>There are four variants: Where the parameter `resultSetTableName` is "entities" and
+   * otherwise and where `versioned` is true and otherwise.
    *
    * @param resultSetTableName name of the table with all the resulting entities
    * @param versioned whether the query was versioned
    * @return an SQL statement
-   * @throws QueryException
    */
   private String generateSelectStatementForResultSet(
       final String resultSetTableName, final boolean versioned) {
+    // TODO remove the entities.role part when
+    // https://gitlab.indiscale.com/caosdb/src/caosdb-server/-/issues/245 is resolved
     if (resultSetTableName.equals("entities")) {
-      return "SELECT entity_id AS id"
-          + (versioned ? ", version AS version" : "")
-          + " FROM entity_version"
-          + (versioned ? "" : " WHERE `_iversion` = 1");
+      final String baseStatement =
+          "SELECT entities.id, entity_acl.acl FROM entities INNER JOIN entity_acl ON entity_acl.id=entities.acl WHERE entities.role!='DOMAIN'";
+      if (!versioned) {
+        return baseStatement + ";";
+      }
+      // if versioned, the statement is surrounded with another SELECT and JOIN
+      return ("SELECT id, acl, version FROM ("
+          + baseStatement
+          + ") AS tmp JOIN entity_version ON entity_version.entity_id=tmp.id;");
+    } else {
+      if (!versioned) {
+        return (" SELECT tmp.id, entity_acl.acl FROM "
+                + " (SELECT results.id AS id, entities.acl AS acl_id FROM `"
+                + resultSetTableName
+                + "` AS results JOIN entities ON results.id=entities.id WHERE entities.role!='DOMAIN') AS tmp"
+                + " JOIN entity_acl ON entity_acl.id=tmp.acl_id")
+            + ";";
+      }
+      // if versioned, the statement is surrounded with another SELECT and JOIN
+      return ("SELECT tmp2.id, acl, version FROM( SELECT tmp.id, entity_acl.acl, tmp._iversion AS _iversion FROM "
+          + " (SELECT results.id AS id, entities.acl AS acl_id, results._iversion AS _iversion FROM `"
+          + resultSetTableName
+          + "` AS results JOIN entities ON results.id=entities.id) AS tmp"
+          + " JOIN entity_acl ON entity_acl.id=tmp.acl_id) as tmp2  "
+          + "join entity_version on (entity_version.entity_id=tmp2.id AND tmp2._iversion = entity_version._iversion);");
     }
-    return "SELECT results.id AS id"
-        + (versioned ? ", ev.version AS version" : "")
-        + " FROM `"
-        + resultSetTableName
-        + "` AS results"
-        + (versioned
-            ? " JOIN entity_version AS ev ON (results.id = ev.entity_id AND results._iversion = ev._iversion)"
-            : "");
   }
 
   /**
@@ -630,17 +667,19 @@ public class Query implements QueryInterface, ToElementable, TransactionInterfac
    * @return list of results of this query.
    * @throws QueryException
    */
-  private List<IdVersionPair> getResultSet(final String resultSetTableName, final boolean versioned)
-      throws QueryException {
+  private List<IdVersionAclTriplet> getResultSet(
+      final String resultSetTableName, final boolean versioned) throws QueryException {
     ResultSet finishResultSet = null;
     try {
       final String sql = generateSelectStatementForResultSet(resultSetTableName, versioned);
       final PreparedStatement finish = getConnection().prepareStatement(sql);
       finishResultSet = finish.executeQuery();
-      final List<IdVersionPair> rs = new LinkedList<>();
+      final List<IdVersionAclTriplet> rs = new LinkedList<>();
       while (finishResultSet.next()) {
         final String version = versioned ? finishResultSet.getString("version") : null;
-        rs.add(new IdVersionPair(finishResultSet.getInt("id"), version));
+        final String acl = finishResultSet.getString("acl");
+
+        rs.add(new IdVersionAclTriplet(finishResultSet.getInt("id"), version, acl));
       }
       return rs;
     } catch (final SQLException e) {
@@ -657,14 +696,43 @@ public class Query implements QueryInterface, ToElementable, TransactionInterfac
   }
 
   /**
-   * Whether the transaction allows this query instance to use the query cache. This is controlled
-   * by the "cache" flag.
-   *
-   * @see {@link NoCache}
-   * @return true if caching is encouraged.
+   * Try to set the `resultSet` member variable using the values stored in the high level query
+   * cache.
    */
-  private boolean useCache() {
-    return getAccess().useCache();
+  private void getResultFromCache() {
+    // try key with username and realm
+    // TODO include this again to activate the user-specific caching
+    // this.resultSet = getCached(getCacheKey(true));
+    if (this.resultSet == null) {
+      // try key without username and realm
+      this.resultSet = getCached(getCacheKey(false));
+    }
+  }
+  /** Store the content of `resultSet` member in the high level query cache. */
+  private void storeResultInCache() {
+    // Decide whether user specific cache needs to be used or not
+    // Currently, this is solely determined via filteredIntermediateResult.
+    if (this.filteredIntermediateResult) {
+      // TODO include this again to activate user-specific caching
+      // cacheItem(getCacheKey(true), this.resultSet);
+    } else {
+      cacheItem(getCacheKey(false), this.resultSet);
+    }
+  }
+  /** Fill entities from `resultSet` into `container`. */
+  private void fillContainerWithResult() {
+    if (this.container != null && this.type == Type.FIND) {
+      for (final IdVersionAclTriplet t : this.resultSet) {
+
+        final Entity e = new RetrieveEntity(t.id, t.version);
+
+        // if query has select-clause:
+        if (this.selections != null && !this.selections.isEmpty()) {
+          e.addSelections(this.selections);
+        }
+        this.container.add(e);
+      }
+    }
   }
 
   /**
@@ -674,59 +742,60 @@ public class Query implements QueryInterface, ToElementable, TransactionInterfac
    *
    * @param access
    * @return
-   * @throws ParsingException
+   * @throws ParsingException, QueryException
    */
-  public Query execute(final Access access) throws ParsingException {
-    parse();
-    setAccess(access);
-    if (useCache()) {
-      this.resultSet = getCached(getCacheKey());
-    }
-
-    if (this.resultSet == null) {
-      executeNoCache(access);
-      if (this.cachable) {
-        setCache(getCacheKey(), this.resultSet);
+  public Query execute(final Access access) throws ParsingException, QueryException {
+    try {
+      parse();
+      setAccess(access);
+      if (access.useCache()) {
+        getResultFromCache();
       }
-      this.logger.debug("Uncached query {}", this.query);
-    } else {
-      this.logger.debug("Using cached result for {}", this.query);
-      this.cached = true;
-    }
-
-    this.resultSet = filterEntitiesWithoutRetrievePermission(this.resultSet);
-
-    // Fill resulting entities into container
-    if (this.container != null && this.type == Type.FIND) {
-      for (final IdVersionPair p : this.resultSet) {
+      if (this.resultSet != null) {
+        this.logger.debug("Using cached result for {}", this.query);
+        this.cached = true;
 
-        if (p.id > 99) {
-          final Entity e = new RetrieveEntity(p.id, p.version);
-
-          // if query has select-clause:
-          if (this.selections != null && !this.selections.isEmpty()) {
-            e.addSelections(this.selections);
-          }
-          this.container.add(e);
-        }
+      } else {
+        executeQueryInBackend(access);
+        storeResultInCache();
+        this.logger.debug("Uncached query {}", this.query);
       }
+
+      this.resultSet = filterEntitiesWithoutRetrievePermission(this.resultSet);
+      this.resultSet = removeInternalEntitiesFromResultSet();
+      fillContainerWithResult();
+    } catch (final SQLException e) {
+      e.printStackTrace();
+      throw new QueryException(e);
     }
     return this;
   }
-
   /** Remove all cached queries from the cache. */
   public static void clearCache() {
     cacheETag = UUID.randomUUID().toString();
     cache.clear();
   }
 
+  /** There are internal Entities (with ID<100) that should never be returned. */
+  private List<IdVersionAclTriplet> removeInternalEntitiesFromResultSet() {
+
+    final List<IdVersionAclTriplet> filtered = new ArrayList<>();
+    for (final IdVersionAclTriplet triplet : resultSet) {
+
+      if (triplet.id >= 100) {
+        filtered.add(triplet);
+      }
+    }
+    return filtered;
+  }
+
   /**
    * Cache a query result.
    *
    * @param key
    * @param resultSet
    */
-  private void setCache(final String key, final List<IdVersionPair> resultSet) {
+  private void cacheItem(final String key, final List<IdVersionAclTriplet> resultSet) {
     synchronized (cache) {
       if (resultSet instanceof Serializable) {
         cache.put(key, (Serializable) resultSet);
@@ -737,17 +806,17 @@ public class Query implements QueryInterface, ToElementable, TransactionInterfac
   }
 
   /**
-   * Retrieve a result set of entity ids (and the version) from the cache.
+   * Retrieve a result set of entity IDs (and the version) from the cache.
    *
    * @param key
    * @return
    */
   @SuppressWarnings("unchecked")
-  private List<IdVersionPair> getCached(final String key) {
-    return (List<IdVersionPair>) cache.get(key);
+  private List<IdVersionAclTriplet> getCached(final String key) {
+    return (List<IdVersionAclTriplet>) cache.get(key);
   }
 
-  protected void executeNoCache(final Access access) {
+  protected void executeQueryInBackend(final Access access) throws SQLException {
     try {
       this.resultSet = getResultSet(executeStrategy(this.versioned), this.versioned);
     } finally {
@@ -787,72 +856,100 @@ public class Query implements QueryInterface, ToElementable, TransactionInterfac
 
   /**
    * Filter out all entities which may not be retrieved by this user due to a missing RETRIEVE
-   * permission. This one is also designed for filtering of intermediate results.
+   * permission. This function is also designed for filtering of intermediate results.
    *
-   * @param resultSet
+   * @param tabname
    * @throws SQLException
-   * @throws TransactionException
    */
-  public void filterEntitiesWithoutRetrievePermission(final String resultSet)
-      throws SQLException, TransactionException {
+  public void filterIntermediateResult(final String tabname) throws SQLException {
     if (!filterEntitiesWithoutRetrievePermisions) {
       return;
     }
-    cachable = false;
+    filteredIntermediateResult = true;
+
+    /*
+     * The following creates a table with the columns (entity ID, acl) from
+     * a given table with entity IDs. Here, acl is the string representation
+     * of the acl.
+     *
+     * TODO:In future, one might want to retrieve only a distinct set of acl
+     * with (acl_id, acl) and a table with (entity_id, acl_id) to reduce the
+     * amount of data being transfered.
+     */
+
     try (final Statement stmt = this.getConnection().createStatement()) {
-      final ResultSet rs = stmt.executeQuery("SELECT id from `" + resultSet + "`");
-      final List<Integer> toBeDeleted = new LinkedList<Integer>();
-      while (rs.next()) {
-        final long t1 = System.currentTimeMillis();
-        final Integer id = rs.getInt("id");
-        if (id > 99
-            && !execute(new RetrieveSparseEntity(id, null), this.getAccess())
-                .getEntity()
-                .getEntityACL()
-                .isPermitted(this.getUser(), EntityPermission.RETRIEVE_ENTITY)) {
-          toBeDeleted.add(id);
+      final String query =
+          ("SELECT entity_n_acl.id, entity_acl.acl from "
+              + "(select entities.id, entities.acl from entities "
+              + "inner join `"
+              + tabname
+              + "` as rs on entities.id=rs.id) "
+              + "as entity_n_acl "
+              + "left join entity_acl on entity_n_acl.acl=entity_acl.id;");
+      final ResultSet entitiesRS = stmt.executeQuery(query);
+      final ResultSetIterator entitiesWithACL = new ResultSetIterator(entitiesRS);
+      final List<Integer> toBeDeleted = collectIdsWithoutPermission(entitiesWithACL);
+      try (final PreparedStatement pstmt =
+          this.getConnection().prepareStatement("DELETE FROM `" + tabname + "` WHERE id = ?")) {
+        for (final Integer id : toBeDeleted) {
+          pstmt.setInt(1, id);
+          pstmt.execute();
         }
-        final long t2 = System.currentTimeMillis();
-        this.addBenchmark("filterEntitiesWithoutRetrievePermission", t2 - t1);
-      }
-      rs.close();
-      for (final Integer id : toBeDeleted) {
-        stmt.execute("DELETE FROM `" + resultSet + "` WHERE id = " + id);
       }
     }
   }
 
   /**
-   * Filter out all entities which may not be retrieved by this user due to a missing RETRIEVE
-   * permission. This one is for the filtering of the final result set and not for the filtering of
-   * any intermediate results.
+   * Creates a new list that contains only the entities from the `resultSet` for which the current
+   * subject has RETRIEVE permission.
    *
-   * @param entities
-   * @throws TransactionException
-   * @return the filtered list.
+   * <p>Note, unlike the public version of this function `resultSet` is not altered but the filtered
+   * list is returned.
+   *
+   * @param resultSet
+   * @return list without the entities with insufficient permissions
    */
-  private List<IdVersionPair> filterEntitiesWithoutRetrievePermission(
-      final List<IdVersionPair> entities) throws TransactionException {
-    if (!filterEntitiesWithoutRetrievePermisions) {
-      return entities;
+  private List<IdVersionAclTriplet> filterEntitiesWithoutRetrievePermission(
+      final List<IdVersionAclTriplet> resultSet) {
+    final List<Integer> toBeDeleted = collectIdsWithoutPermission(resultSet.iterator());
+    final List<IdVersionAclTriplet> filtered = new ArrayList<>();
+    for (final IdVersionAclTriplet triplet : resultSet) {
+      if (-1 == toBeDeleted.indexOf(triplet.id)) {
+        filtered.add(triplet);
+      }
     }
-
-    final List<IdVersionPair> result = new ArrayList<>();
-    final Iterator<IdVersionPair> iterator = entities.iterator();
-    while (iterator.hasNext()) {
+    return filtered;
+  }
+  /**
+   * Creates a list with IDs of those entities that do not have sufficient RETRIEVE permission
+   *
+   * @param entityIterator Iterator over the result set consisting of (ID, version hash, acl string)
+   *     triplets.
+   * @return compiled list
+   */
+  private List<Integer> collectIdsWithoutPermission(Iterator<IdVersionAclTriplet> entityIterator) {
+    final HashMap<String, Boolean> acl_cache = new HashMap<String, Boolean>();
+    final List<Integer> toBeDeleted = new LinkedList<Integer>();
+    while (entityIterator.hasNext()) {
       final long t1 = System.currentTimeMillis();
-      final IdVersionPair next = iterator.next();
-      if (next.id > 99
-          && execute(new RetrieveSparseEntity(next.id, next.version), getAccess())
-              .getEntity()
-              .getEntityACL()
-              .isPermitted(getUser(), EntityPermission.RETRIEVE_ENTITY)) {
-        result.add(next);
+
+      final IdVersionAclTriplet triplet = entityIterator.next();
+
+      if (!acl_cache.containsKey(triplet.acl)) {
+        acl_cache.put(
+            triplet.acl,
+            EntityACL.deserialize(triplet.acl)
+                .isPermitted(this.getUser(), EntityPermission.RETRIEVE_ENTITY));
       }
+
+      if (!acl_cache.get(triplet.acl)) {
+        toBeDeleted.add(triplet.id);
+      }
+
       final long t2 = System.currentTimeMillis();
-      addBenchmark("filterEntitiesWithoutRetrievePermission", t2 - t1);
+      this.addBenchmark("filterEntitiesWithoutRetrievePermission", t2 - t1);
     }
-    return result;
+    return toBeDeleted;
   }
 
   @Override
@@ -1004,18 +1101,29 @@ public class Query implements QueryInterface, ToElementable, TransactionInterfac
    *
    * @return A Cache key.
    */
-  String getCacheKey() {
+  String getCacheKey(boolean addUser) {
     final StringBuilder sb = new StringBuilder();
+    if (addUser && (this.user != null)) {
+      sb.append("U_");
+      String principal_desc =
+          ((Principal) this.user.getPrincipal()).getUsername()
+              + Principal.REALM_SEPARATOR
+              + ((Principal) this.user.getPrincipal()).getRealm();
+      sb.append(principal_desc);
+    }
     if (this.versioned) {
-      sb.append("versioned");
+      sb.append("V_");
     }
     if (this.role != null) {
+      sb.append("R_");
       sb.append(this.role.toString());
     }
     if (this.entity != null) {
+      sb.append("E_");
       sb.append(this.entity.toString());
     }
     if (this.filter != null) {
+      sb.append("F_");
       sb.append(this.filter.getCacheKey());
     }
     return sb.toString();
diff --git a/src/main/java/org/caosdb/server/query/SubProperty.java b/src/main/java/org/caosdb/server/query/SubProperty.java
index f3be825ccf28b7df2ba646306a61f006664ae5a6..8ff167eac1e045875576a75f3d922f5c6461c68e 100644
--- a/src/main/java/org/caosdb/server/query/SubProperty.java
+++ b/src/main/java/org/caosdb/server/query/SubProperty.java
@@ -87,7 +87,7 @@ public class SubProperty implements QueryInterface, EntityFilterInterface {
 
         this.filter.apply(this);
 
-        getQuery().filterEntitiesWithoutRetrievePermission(this.sourceSet);
+        getQuery().filterIntermediateResult(this.sourceSet);
 
         final CallableStatement callFinishSubProperty =
             getConnection().prepareCall("call finishSubProperty(?,?,?,?)");
diff --git a/src/main/java/org/caosdb/server/scripting/ServerSideScriptingCaller.java b/src/main/java/org/caosdb/server/scripting/ServerSideScriptingCaller.java
index 4f5f81e248e17f6344d8523286828ce7142c529a..edb6b39a4e92466e5a3e5a489669d366bbe8ce37 100644
--- a/src/main/java/org/caosdb/server/scripting/ServerSideScriptingCaller.java
+++ b/src/main/java/org/caosdb/server/scripting/ServerSideScriptingCaller.java
@@ -170,7 +170,7 @@ public class ServerSideScriptingCaller {
 
     // create files dir
     if (!getUploadFilesDir().mkdir()) {
-      throw new FileNotFoundException("Could not crete the FILE_UPLOAD_DIR.");
+      throw new FileNotFoundException("Could not create the FILE_UPLOAD_DIR.");
     }
     for (final FileProperties f : files) {
       if (f.getPath() == null || f.getPath().isEmpty()) {
diff --git a/src/main/java/org/caosdb/server/utils/ResultSetIterator.java b/src/main/java/org/caosdb/server/utils/ResultSetIterator.java
new file mode 100644
index 0000000000000000000000000000000000000000..0912d278c7158c9b7b75a585c2827d851951f29b
--- /dev/null
+++ b/src/main/java/org/caosdb/server/utils/ResultSetIterator.java
@@ -0,0 +1,60 @@
+package org.caosdb.server.utils;
+
+import static org.caosdb.server.database.DatabaseUtils.bytes2UTF8;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import org.caosdb.server.database.exceptions.TransactionException;
+import org.caosdb.server.query.Query.IdVersionAclTriplet;
+
+/**
+ * A class for iterating over {@link ResultSet}
+ *
+ * <p>{@link ResultSet} only provides a `next` function which moves the cursor. The behavior is here
+ * mapped onto the functions of the Iterator interface. TODO Move this generic function? Check again
+ * if an implementation is available from elsewhere.
+ */
+public class ResultSetIterator implements Iterator<IdVersionAclTriplet> {
+  public ResultSetIterator(final ResultSet resultset) {
+    this.resultSet = resultset;
+  }
+
+  private ResultSet resultSet;
+  private boolean cursorHasMoved = false;
+  private boolean currentIsValid = true;
+
+  public boolean hasNext() {
+    if (!this.cursorHasMoved) {
+      try {
+        this.currentIsValid = this.resultSet.next();
+      } catch (SQLException e) {
+        throw new TransactionException(e);
+      }
+      this.cursorHasMoved = true;
+    }
+    return this.currentIsValid;
+  };
+
+  public IdVersionAclTriplet next() {
+    if (!this.cursorHasMoved) {
+      try {
+        this.currentIsValid = this.resultSet.next();
+      } catch (SQLException e) {
+        throw new TransactionException(e);
+      }
+    }
+    this.cursorHasMoved = false;
+    if (!this.currentIsValid) {
+      throw new NoSuchElementException();
+    }
+    try {
+      final Integer id = resultSet.getInt("id");
+      final String acl_str = bytes2UTF8(resultSet.getBytes("ACL"));
+      return new IdVersionAclTriplet(id, "", acl_str);
+    } catch (SQLException e) {
+      throw new TransactionException(e);
+    }
+  }
+}
diff --git a/src/test/java/org/caosdb/CaosDBTestClass.java b/src/test/java/org/caosdb/CaosDBTestClass.java
deleted file mode 100644
index d22f9ade8ed43b5e44e505b70e7d2b1d704e211b..0000000000000000000000000000000000000000
--- a/src/test/java/org/caosdb/CaosDBTestClass.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * ** header v3.0
- * This file is a part of the CaosDB Project.
- *
- * Copyright (C) 2018 Research Group Biomedical Physics,
- * Max-Planck-Institute for Dynamics and Self-Organization Göttingen
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <https://www.gnu.org/licenses/>.
- *
- * ** end header
- */
-package org.caosdb;
-
-import java.io.File;
-import java.io.IOException;
-import org.apache.commons.io.FileUtils;
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-
-public class CaosDBTestClass {
-
-  public static final File TEST_DIR = new File(".TEST_DIR");
-
-  @BeforeClass
-  public static final void setupAll() throws IOException {
-    TEST_DIR.mkdirs();
-    FileUtils.forceDeleteOnExit(TEST_DIR);
-  }
-
-  @AfterClass
-  public static final void teardownAll() {}
-}
diff --git a/src/test/java/org/caosdb/datetime/DateTimeTest.java b/src/test/java/org/caosdb/datetime/DateTimeTest.java
index 81e0edf748432daf8c023b421b6119a3bf14f2d4..49e883fb0d2a2c3f62e0417a2a246841c4e6c9bb 100644
--- a/src/test/java/org/caosdb/datetime/DateTimeTest.java
+++ b/src/test/java/org/caosdb/datetime/DateTimeTest.java
@@ -22,9 +22,10 @@
  */
 package org.caosdb.datetime;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
 
 import java.io.IOException;
 import java.sql.SQLException;
@@ -34,13 +35,12 @@ import java.util.GregorianCalendar;
 import java.util.TimeZone;
 import org.caosdb.server.CaosDBServer;
 import org.caosdb.server.database.backend.implementation.MySQL.ConnectionException;
-import org.junit.Assert;
-import org.junit.BeforeClass;
-import org.junit.Test;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
 
 public class DateTimeTest {
 
-  @BeforeClass
+  @BeforeAll
   public static void setup() throws InterruptedException, IOException {
     CaosDBServer.initServerProperties();
     CaosDBServer.initTimeZone();
@@ -50,7 +50,7 @@ public class DateTimeTest {
   public void testGetTimeZoneFromDate() throws InterruptedException, IOException {
     String tz = CaosDBServer.getTimeZoneFromDate();
     ZoneId of = java.time.ZoneId.of(tz);
-    Assert.assertNotNull(of);
+    assertNotNull(of);
   }
 
   @Test
diff --git a/src/test/java/org/caosdb/server/Misc.java b/src/test/java/org/caosdb/server/Misc.java
index f6d1364644d803abf194532471f9e1775fa990de..0b39327e6371fcc619f70d10c67bb4d7269589cd 100644
--- a/src/test/java/org/caosdb/server/Misc.java
+++ b/src/test/java/org/caosdb/server/Misc.java
@@ -22,10 +22,11 @@
  */
 package org.caosdb.server;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
 
 import java.io.File;
 import java.io.FileInputStream;
@@ -40,14 +41,13 @@ import org.apache.shiro.subject.Subject;
 import org.caosdb.server.database.misc.TransactionBenchmark;
 import org.caosdb.server.jobs.core.CheckFileStorageConsistency;
 import org.caosdb.server.utils.CronJob;
-import org.junit.Assert;
-import org.junit.BeforeClass;
-import org.junit.Test;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
 import org.jvnet.libpam.PAMException;
 import org.jvnet.libpam.UnixUser;
 
 public class Misc {
-  @BeforeClass
+  @BeforeAll
   public static void initServerProperties() throws IOException {
     CaosDBServer.initServerProperties();
   }
@@ -55,12 +55,12 @@ public class Misc {
   @Test
   public void testUnixUser() throws PAMException {
     final UnixUser u = new UnixUser("root");
-    Assert.assertEquals("/root", u.getDir());
-    Assert.assertNotNull(u.getUserName());
-    Assert.assertNotNull(u.getGroups());
-    Assert.assertEquals(0, u.getUID());
+    assertEquals("/root", u.getDir());
+    assertNotNull(u.getUserName());
+    assertNotNull(u.getGroups());
+    assertEquals(0, u.getUID());
 
-    Assert.assertFalse(UnixUser.exists("non-existing-user"));
+    assertFalse(UnixUser.exists("non-existing-user"));
   }
 
   @Test
@@ -70,12 +70,12 @@ public class Misc {
     final Pattern p = Pattern.compile("(\\d+)(?::(\\d+))?");
     final Matcher m1 = p.matcher(s1);
     final Matcher m2 = p.matcher(s2);
-    Assert.assertTrue(m1.matches());
+    assertTrue(m1.matches());
     assertTrue(m2.matches());
-    Assert.assertEquals(2, m1.groupCount());
-    Assert.assertEquals("100", m1.group(1));
-    Assert.assertEquals("200", m1.group(2));
-    Assert.assertEquals(2, m2.groupCount());
+    assertEquals(2, m1.groupCount());
+    assertEquals("100", m1.group(1));
+    assertEquals("200", m1.group(2));
+    assertEquals(2, m2.groupCount());
     assertEquals("100", m2.group(1));
     assertNull(m2.group(2));
 
diff --git a/src/test/java/org/caosdb/server/accessControl/TestDefaultPamScriptCaller.java b/src/test/java/org/caosdb/server/accessControl/TestDefaultPamScriptCaller.java
index 21197f4fa430283898c87741df4c765b28152f33..a893b46afa0e855c281103022a1553d3cb47675b 100644
--- a/src/test/java/org/caosdb/server/accessControl/TestDefaultPamScriptCaller.java
+++ b/src/test/java/org/caosdb/server/accessControl/TestDefaultPamScriptCaller.java
@@ -22,12 +22,12 @@
  */
 package org.caosdb.server.accessControl;
 
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
 
 import java.io.File;
 import java.io.IOException;
-import org.junit.Test;
+import org.junit.jupiter.api.Test;
 
 public class TestDefaultPamScriptCaller {
   @Test
diff --git a/src/test/java/org/caosdb/server/authentication/AuthTokenTest.java b/src/test/java/org/caosdb/server/authentication/AuthTokenTest.java
index 0b19b414517769ee1d6c3882658e870d50193225..d83651a3b202be77a2bab7abbab37c6281f1b0b2 100644
--- a/src/test/java/org/caosdb/server/authentication/AuthTokenTest.java
+++ b/src/test/java/org/caosdb/server/authentication/AuthTokenTest.java
@@ -23,9 +23,14 @@
 
 package org.caosdb.server.authentication;
 
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
+import static org.junit.jupiter.api.Assertions.assertArrayEquals;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.fail;
 
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.fasterxml.jackson.databind.ObjectReader;
@@ -60,19 +65,18 @@ import org.caosdb.server.resource.TestScriptingResource.RetrievePasswordValidato
 import org.caosdb.server.resource.TestScriptingResource.RetrievePermissionRules;
 import org.caosdb.server.resource.TestScriptingResource.RetrieveRoleMockup;
 import org.caosdb.server.resource.TestScriptingResource.RetrieveUserMockUp;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Test;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
 
 public class AuthTokenTest {
 
-  @BeforeClass
+  @BeforeAll
   public static void initServerProperties() throws IOException {
     CaosDBServer.initServerProperties();
   }
 
-  @BeforeClass
+  @BeforeAll
   public static void setupShiro() throws IOException {
     BackendTransaction.setImpl(RetrieveRoleImpl.class, RetrieveRoleMockup.class);
     BackendTransaction.setImpl(RetrievePermissionRulesImpl.class, RetrievePermissionRules.class);
@@ -84,7 +88,7 @@ public class AuthTokenTest {
     CaosDBServer.initShiro();
   }
 
-  @Before
+  @BeforeEach
   public void reset() {
     OneTimeAuthenticationToken.resetConfig();
   }
@@ -101,61 +105,61 @@ public class AuthTokenTest {
             "wrong checksum",
             null,
             null);
-    Assert.assertFalse(t1.isExpired());
-    Assert.assertFalse(t1.isHashValid());
-    Assert.assertFalse(t1.isValid());
+    assertFalse(t1.isExpired());
+    assertFalse(t1.isHashValid());
+    assertFalse(t1.isValid());
 
     // Token 3 - correct checksum, not expired
     final SessionToken t3 =
         new SessionToken(new Principal("somerealm", "someuser2"), 60000, null, null);
-    Assert.assertFalse(t3.isExpired());
-    Assert.assertTrue(t3.isHashValid());
-    Assert.assertTrue(t3.isValid());
+    assertFalse(t3.isExpired());
+    assertTrue(t3.isHashValid());
+    assertTrue(t3.isValid());
 
     // Token 5 - correct checksum, soon to be expired
     final SessionToken t5 =
         new SessionToken(new Principal("somerealm", "someuser3"), 2000, null, null);
-    Assert.assertFalse(t5.isExpired());
-    Assert.assertTrue(t5.isHashValid());
-    Assert.assertTrue(t5.isValid());
+    assertFalse(t5.isExpired());
+    assertTrue(t5.isHashValid());
+    assertTrue(t5.isValid());
     // wait until expired
     Thread.sleep(2001);
-    Assert.assertTrue(t5.isExpired());
-    Assert.assertTrue(t5.isHashValid());
-    Assert.assertFalse(t5.isValid());
+    assertTrue(t5.isExpired());
+    assertTrue(t5.isHashValid());
+    assertFalse(t5.isValid());
 
     // Token 6 - correct checksum, immediately expired
     final SessionToken t6 =
         new SessionToken(new Principal("somerealm", "someuser3"), 0, null, null);
-    Assert.assertTrue(t6.isExpired());
-    Assert.assertTrue(t6.isHashValid());
-    Assert.assertFalse(t6.isValid());
+    assertTrue(t6.isExpired());
+    assertTrue(t6.isHashValid());
+    assertFalse(t6.isValid());
 
     // All tokens can be successfully parsed back.
     final SelfValidatingAuthenticationToken t1p = SessionToken.parse(t1.toString());
     final SelfValidatingAuthenticationToken t3p = SessionToken.parse(t3.toString());
     final SelfValidatingAuthenticationToken t5p = SessionToken.parse(t5.toString());
     final SelfValidatingAuthenticationToken t6p = SessionToken.parse(t6.toString());
-    Assert.assertEquals(t1.toString(), t1p.toString());
-    Assert.assertEquals(t3.toString(), t3p.toString());
-    Assert.assertEquals(t5.toString(), t5p.toString());
-    Assert.assertEquals(t6.toString(), t6p.toString());
+    assertEquals(t1.toString(), t1p.toString());
+    assertEquals(t3.toString(), t3p.toString());
+    assertEquals(t5.toString(), t5p.toString());
+    assertEquals(t6.toString(), t6p.toString());
 
     // ... and parsed tokens have the correct hash validation
-    Assert.assertFalse(t1p.isHashValid());
-    Assert.assertTrue(t3p.isHashValid());
-    Assert.assertTrue(t5p.isHashValid());
-    Assert.assertTrue(t6p.isHashValid());
+    assertFalse(t1p.isHashValid());
+    assertTrue(t3p.isHashValid());
+    assertTrue(t5p.isHashValid());
+    assertTrue(t6p.isHashValid());
 
-    Assert.assertFalse(
+    assertFalse(
         AuthenticationUtils.parseSessionTokenCookie(
                 AuthenticationUtils.createSessionTokenCookie(t3))
             .isExpired());
-    Assert.assertTrue(
+    assertTrue(
         AuthenticationUtils.parseSessionTokenCookie(
                 AuthenticationUtils.createSessionTokenCookie(t3))
             .isHashValid());
-    Assert.assertTrue(
+    assertTrue(
         AuthenticationUtils.parseSessionTokenCookie(
                 AuthenticationUtils.createSessionTokenCookie(t3))
             .isValid());
@@ -173,25 +177,25 @@ public class AuthTokenTest {
             new String[] {"roles"},
             1L,
             3000L);
-    Assert.assertEquals(1L, t1.getMaxReplays());
-    Assert.assertFalse(t1.isExpired());
-    Assert.assertTrue(t1.isHashValid());
-    Assert.assertTrue(t1.isValid());
+    assertEquals(1L, t1.getMaxReplays());
+    assertFalse(t1.isExpired());
+    assertTrue(t1.isHashValid());
+    assertTrue(t1.isValid());
 
     String serialized = t1.toString();
     OneTimeAuthenticationToken parsed =
         (OneTimeAuthenticationToken) OneTimeAuthenticationToken.parse(serialized);
 
-    Assert.assertEquals(t1, parsed);
-    Assert.assertEquals(serialized, parsed.toString());
+    assertEquals(t1, parsed);
+    assertEquals(serialized, parsed.toString());
 
-    Assert.assertEquals(1L, parsed.getMaxReplays());
-    Assert.assertFalse(parsed.isExpired());
-    Assert.assertTrue(parsed.isHashValid());
-    Assert.assertTrue(parsed.isValid());
+    assertEquals(1L, parsed.getMaxReplays());
+    assertFalse(parsed.isExpired());
+    assertTrue(parsed.isHashValid());
+    assertTrue(parsed.isValid());
   }
 
-  @Test(expected = AuthenticationException.class)
+  @Test
   public void testOneTimeTokenConsume() {
     final OneTimeAuthenticationToken t1 =
         new OneTimeAuthenticationToken(
@@ -201,23 +205,26 @@ public class AuthTokenTest {
             new String[] {"roles"},
             3L,
             3000L);
-    Assert.assertFalse(t1.isExpired());
-    Assert.assertTrue(t1.isHashValid());
-    Assert.assertTrue(t1.isValid());
+    assertFalse(t1.isExpired());
+    assertTrue(t1.isHashValid());
+    assertTrue(t1.isValid());
     try {
       t1.consume();
       t1.consume();
       t1.consume();
     } catch (AuthenticationException e) {
-      Assert.fail(e.getMessage());
+      fail(e.getMessage());
     }
 
-    // throws
-    t1.consume();
-    Assert.fail("4th time consume() should throw");
+    assertThrows(
+        AuthenticationException.class,
+        () ->
+
+            // throws
+            t1.consume());
   }
 
-  @Test(expected = AuthenticationException.class)
+  @Test
   public void testOneTimeTokenConsumeByParsing() {
     final OneTimeAuthenticationToken t1 =
         new OneTimeAuthenticationToken(
@@ -227,25 +234,28 @@ public class AuthTokenTest {
             new String[] {"roles"},
             3L,
             3000L);
-    Assert.assertFalse(t1.isExpired());
-    Assert.assertTrue(t1.isHashValid());
-    Assert.assertTrue(t1.isValid());
+    assertFalse(t1.isExpired());
+    assertTrue(t1.isHashValid());
+    assertTrue(t1.isValid());
 
     String serialized = t1.toString();
     try {
       SelfValidatingAuthenticationToken parsed1 = OneTimeAuthenticationToken.parse(serialized);
-      Assert.assertTrue(parsed1.isValid());
+      assertTrue(parsed1.isValid());
       SelfValidatingAuthenticationToken parsed2 = OneTimeAuthenticationToken.parse(serialized);
-      Assert.assertTrue(parsed2.isValid());
+      assertTrue(parsed2.isValid());
       SelfValidatingAuthenticationToken parsed3 = OneTimeAuthenticationToken.parse(serialized);
-      Assert.assertTrue(parsed3.isValid());
+      assertTrue(parsed3.isValid());
     } catch (AuthenticationException e) {
-      Assert.fail(e.getMessage());
+      fail(e.getMessage());
     }
 
-    // throws
-    OneTimeAuthenticationToken.parse(serialized);
-    Assert.fail("4th parsing should throw");
+    assertThrows(
+        AuthenticationException.class,
+        () ->
+
+            // throws
+            OneTimeAuthenticationToken.parse(serialized));
   }
 
   @Test
@@ -256,7 +266,7 @@ public class AuthTokenTest {
     List<Config> configs =
         OneTimeAuthenticationToken.loadConfig(new CharSequenceInputStream(testYaml, "utf-8"));
 
-    Assert.assertTrue("empty config", configs.isEmpty());
+    assertTrue(configs.isEmpty()); // empty config
   }
 
   @Test
@@ -267,21 +277,21 @@ public class AuthTokenTest {
     List<Config> configs =
         OneTimeAuthenticationToken.loadConfig(new CharSequenceInputStream(testYaml, "utf-8"));
 
-    Assert.assertEquals(1, configs.size());
-    Assert.assertTrue("parsing to Config object", configs.get(0) instanceof Config);
+    assertEquals(1, configs.size());
+    assertTrue(configs.get(0) instanceof Config); // parsing to Config object
 
     Config config = configs.get(0);
 
-    Assert.assertEquals(
+    assertEquals(
         Integer.parseInt(
             CaosDBServer.getServerProperty(ServerProperties.KEY_ONE_TIME_TOKEN_EXPIRES_MS)),
         config.getExpiresAfter());
-    Assert.assertEquals(1, config.getMaxReplays());
-    Assert.assertNull("no purpose", config.getPurpose());
+    assertEquals(1, config.getMaxReplays());
+    assertNull(config.getPurpose(), "no purpose");
 
-    Assert.assertArrayEquals("no permissions", new String[] {}, config.getPermissions());
-    Assert.assertArrayEquals("no roles", new String[] {}, config.getRoles());
-    Assert.assertNull("no output", config.getOutput());
+    assertArrayEquals(new String[] {}, config.getPermissions()); // no permissions
+    assertArrayEquals(new String[] {}, config.getRoles()); // no roles
+    assertNull(config.getOutput()); // no output
   }
 
   @Test
@@ -299,17 +309,16 @@ public class AuthTokenTest {
 
     OneTimeAuthenticationToken.initConfig(new CharSequenceInputStream(testYaml, "utf-8"));
     Map<String, Config> map = OneTimeAuthenticationToken.getPurposeMap();
-    Assert.assertNotNull("test purpose there", map.get("test purpose 1"));
-    Assert.assertTrue("parsing to Config object", map.get("test purpose 1") instanceof Config);
+    assertNotNull(map.get("test purpose 1")); //
+    assertTrue(map.get("test purpose 1") instanceof Config); // parsing to Config object
     Config config = map.get("test purpose 1");
-    Assert.assertEquals(10000, config.getExpiresAfter());
-    Assert.assertEquals(3, config.getMaxReplays());
+    assertEquals(10000, config.getExpiresAfter());
+    assertEquals(3, config.getMaxReplays());
 
-    Assert.assertArrayEquals(
-        "permissions parsed",
+    assertArrayEquals(
         new String[] {"permission1", "permission2", "permission3", "permission with white space"},
-        config.getPermissions());
-    Assert.assertArrayEquals("roles parsed", new String[] {"role1", "role2"}, config.getRoles());
+        config.getPermissions()); // permissions parsed
+    assertArrayEquals(new String[] {"role1", "role2"}, config.getRoles()); // roles parsed
   }
 
   @Test
@@ -326,7 +335,7 @@ public class AuthTokenTest {
     Map<String, Config> map = OneTimeAuthenticationToken.getPurposeMap();
     Config config = map.get("no roles test");
 
-    Assert.assertArrayEquals("empty roles array parsed", new String[] {}, config.getRoles());
+    assertArrayEquals(new String[] {}, config.getRoles()); // empty roles array parsed
   }
 
   @Test
@@ -340,7 +349,7 @@ public class AuthTokenTest {
 
     OneTimeAuthenticationToken.initConfig(new CharSequenceInputStream(testYaml, "utf-8"));
     Map<String, Config> map = OneTimeAuthenticationToken.getPurposeMap();
-    Assert.assertEquals(map.size(), 0);
+    assertEquals(map.size(), 0);
   }
 
   @Test
@@ -353,8 +362,8 @@ public class AuthTokenTest {
 
     OneTimeAuthenticationToken.initConfig(new CharSequenceInputStream(testYaml, "utf-8"));
     Map<String, Config> map = OneTimeAuthenticationToken.getPurposeMap();
-    Assert.assertEquals("four items", 4, map.size());
-    Assert.assertTrue(map.get("purpose 2") instanceof Config);
+    assertEquals(4, map.size()); // four items
+    assertTrue(map.get("purpose 2") instanceof Config);
   }
 
   @Test
@@ -369,19 +378,19 @@ public class AuthTokenTest {
 
     // write the token
     OneTimeAuthenticationToken.initConfig(new CharSequenceInputStream(testYaml, "utf-8"));
-    Assert.assertTrue(tempFile.exists());
+    assertTrue(tempFile.exists());
     try (BufferedReader reader = new BufferedReader(new FileReader(tempFile))) {
       OneTimeAuthenticationToken token =
           (OneTimeAuthenticationToken) SelfValidatingAuthenticationToken.parse(reader.readLine());
-      assertEquals("Token has anonymous username", "anonymous", token.getPrincipal().getUsername());
+      assertEquals("anonymous", token.getPrincipal().getUsername(), "Token has anonymous username");
       assertEquals(
-          "Token has anonymous realm",
           OneTimeAuthenticationToken.REALM_NAME,
-          token.getPrincipal().getRealm());
+          token.getPrincipal().getRealm(),
+          "Token has anonymous realm");
       assertArrayEquals(
-          "Permissions array has been written and read",
           new String[] {"permission1"},
-          token.getPermissions().toArray());
+          token.getPermissions().toArray(),
+          "Permissions array has been written and read");
     }
   }
 
@@ -413,11 +422,11 @@ public class AuthTokenTest {
     SelfValidatingAuthenticationToken parsed = SelfValidatingAuthenticationToken.parse(serialized);
 
     SessionTokenRealm sessionTokenRealm = new SessionTokenRealm();
-    Assert.assertTrue(sessionTokenRealm.supports(token));
-    Assert.assertTrue(sessionTokenRealm.supports(parsed));
+    assertTrue(sessionTokenRealm.supports(token));
+    assertTrue(sessionTokenRealm.supports(parsed));
 
-    Assert.assertNotNull(sessionTokenRealm.getAuthenticationInfo(token));
-    Assert.assertNotNull(sessionTokenRealm.getAuthenticationInfo(parsed));
+    assertNotNull(sessionTokenRealm.getAuthenticationInfo(token));
+    assertNotNull(sessionTokenRealm.getAuthenticationInfo(parsed));
 
     Subject anonymous = SecurityUtils.getSubject();
     anonymous.login(token);
diff --git a/src/test/java/org/caosdb/server/caching/TestCaching.java b/src/test/java/org/caosdb/server/caching/TestCaching.java
index 40387790b369a711ff95668821cbe4e64d813150..1aba2ff6f16cea7a1f62e84e50e2cc9797114e27 100644
--- a/src/test/java/org/caosdb/server/caching/TestCaching.java
+++ b/src/test/java/org/caosdb/server/caching/TestCaching.java
@@ -1,7 +1,7 @@
 package org.caosdb.server.caching;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertSame;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertSame;
 
 import java.io.IOException;
 import org.apache.commons.jcs.JCS;
@@ -9,12 +9,12 @@ import org.apache.commons.jcs.access.CacheAccess;
 import org.caosdb.server.CaosDBServer;
 import org.caosdb.server.accessControl.Pam;
 import org.caosdb.server.database.backend.transaction.RetrieveProperties;
-import org.junit.BeforeClass;
-import org.junit.Test;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
 
 public class TestCaching {
 
-  @BeforeClass
+  @BeforeAll
   public static void init() throws IOException {
     CaosDBServer.initServerProperties();
     JCSCacheHelper.init();
diff --git a/src/test/java/org/caosdb/server/caching/TestNoCaching.java b/src/test/java/org/caosdb/server/caching/TestNoCaching.java
index bcd2f08f128fe58de760ec9e1abca2b0837e7136..4fc73adf89f9355d1ff6addcd0f71fd9eda4e653 100644
--- a/src/test/java/org/caosdb/server/caching/TestNoCaching.java
+++ b/src/test/java/org/caosdb/server/caching/TestNoCaching.java
@@ -1,6 +1,6 @@
 package org.caosdb.server.caching;
 
-import static org.junit.Assert.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertEquals;
 
 import java.io.IOException;
 import org.apache.commons.jcs.JCS;
@@ -8,12 +8,12 @@ import org.apache.commons.jcs.access.CacheAccess;
 import org.caosdb.server.CaosDBServer;
 import org.caosdb.server.ServerProperties;
 import org.caosdb.server.database.backend.transaction.RetrieveProperties;
-import org.junit.BeforeClass;
-import org.junit.Test;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
 
 public class TestNoCaching {
 
-  @BeforeClass
+  @BeforeAll
   public static void init() throws IOException {
     CaosDBServer.initServerProperties();
     CaosDBServer.setProperty(ServerProperties.KEY_CACHE_DISABLE, "TRUE");
diff --git a/src/test/java/org/caosdb/server/database/DatabaseAccessManagerTest.java b/src/test/java/org/caosdb/server/database/DatabaseAccessManagerTest.java
index 1e8f6cc707299f5b0102ad774d127630dee51c08..9d682ce3b2e2d6fe233095baa7095ebef2602ba4 100644
--- a/src/test/java/org/caosdb/server/database/DatabaseAccessManagerTest.java
+++ b/src/test/java/org/caosdb/server/database/DatabaseAccessManagerTest.java
@@ -21,12 +21,12 @@
  */
 package org.caosdb.server.database;
 
-import static org.junit.Assert.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
 
 import java.util.LinkedList;
 import java.util.List;
-import org.junit.Assert;
-import org.junit.Test;
+import org.junit.jupiter.api.Test;
 
 public class DatabaseAccessManagerTest {
   Thread createReadThread(long wait, String name, ReadAccessSemaphore readAccess) {
@@ -133,7 +133,7 @@ public class DatabaseAccessManagerTest {
       this.wait(500);
     }
     // waiting means any processing
-    Assert.assertEquals(wt1.getState(), Thread.State.WAITING);
+    assertEquals(wt1.getState(), Thread.State.WAITING);
 
     final ReadThread rt2 = new ReadThread("rt2");
     rt2.start(); // paused, has acquired a second read access now
@@ -149,7 +149,7 @@ public class DatabaseAccessManagerTest {
 
     // rt2 was processed while wt1 has reserved but not yet acquired write
     // access. rt2 terminated after releasing its read access.
-    Assert.assertEquals(rt2.getState(), Thread.State.TERMINATED);
+    assertEquals(rt2.getState(), Thread.State.TERMINATED);
 
     final WriteThread wt2 = new WriteThread("wt2");
     wt2.start(); // wt2 immediatelly reserves write access and is block
@@ -157,17 +157,17 @@ public class DatabaseAccessManagerTest {
     synchronized (this) {
       this.wait(500);
     }
-    Assert.assertEquals(wt2.getState(), Thread.State.WAITING);
+    assertEquals(wt2.getState(), Thread.State.WAITING);
 
     // wt1 request write access.
     synchronized (wt1) {
       wt1.notify();
     }
     // it is blocked as rt1 yet yields it.
-    Assert.assertEquals(wt1.getState(), Thread.State.BLOCKED);
+    assertEquals(wt1.getState(), Thread.State.BLOCKED);
 
     // rt1 is waiting (due to pause()).
-    Assert.assertEquals(rt1.getState(), Thread.State.WAITING);
+    assertEquals(rt1.getState(), Thread.State.WAITING);
     synchronized (rt1) {
       rt1.notify();
     }
@@ -176,7 +176,7 @@ public class DatabaseAccessManagerTest {
     }
     // rt1 was notified an terminated, releasing the read acccess.
     // so wt1 acquires write access and pauses the second time.
-    Assert.assertEquals(rt1.getState(), Thread.State.TERMINATED);
+    assertEquals(rt1.getState(), Thread.State.TERMINATED);
 
     synchronized (wt1) {
       wt1.notify();
@@ -185,8 +185,8 @@ public class DatabaseAccessManagerTest {
       this.wait(1000);
     }
     // wt2 reserves write access as wt1 released it now.
-    Assert.assertEquals(wt1.getState(), Thread.State.TERMINATED);
-    Assert.assertEquals(wt2.getState(), Thread.State.WAITING);
+    assertEquals(wt1.getState(), Thread.State.TERMINATED);
+    assertEquals(wt2.getState(), Thread.State.WAITING);
 
     // while wt2 has not yet acquired write access, rt3 acquires read
     // access
@@ -195,7 +195,7 @@ public class DatabaseAccessManagerTest {
     synchronized (this) {
       this.wait(500);
     }
-    Assert.assertEquals(rt3.getState(), Thread.State.WAITING);
+    assertEquals(rt3.getState(), Thread.State.WAITING);
 
     synchronized (wt2) {
       wt2.notify();
@@ -203,7 +203,7 @@ public class DatabaseAccessManagerTest {
     synchronized (this) {
       this.wait(500);
     }
-    Assert.assertEquals(wt2.getState(), Thread.State.WAITING);
+    assertEquals(wt2.getState(), Thread.State.WAITING);
 
     synchronized (rt3) {
       rt3.notify();
@@ -211,7 +211,7 @@ public class DatabaseAccessManagerTest {
     synchronized (this) {
       this.wait(500);
     }
-    Assert.assertEquals(rt3.getState(), Thread.State.TERMINATED);
+    assertEquals(rt3.getState(), Thread.State.TERMINATED);
 
     synchronized (wt2) {
       wt2.notify();
@@ -219,7 +219,7 @@ public class DatabaseAccessManagerTest {
     synchronized (this) {
       this.wait(500);
     }
-    Assert.assertEquals(wt2.getState(), Thread.State.TERMINATED);
+    assertEquals(wt2.getState(), Thread.State.TERMINATED);
   }
 
   @Test
@@ -254,7 +254,7 @@ public class DatabaseAccessManagerTest {
     synchronized (this) {
       this.wait(500);
     }
-    Assert.assertEquals(rt1.getState(), Thread.State.WAITING);
+    assertEquals(rt1.getState(), Thread.State.WAITING);
     synchronized (wt2) {
       wt2.notify();
     }
diff --git a/src/test/java/org/caosdb/server/database/InsertTest.java b/src/test/java/org/caosdb/server/database/InsertTest.java
index b6b535c77700e55bfba67523d6250025b6ce3360..d5aa4480a961b849c2cb2ce4b1f395826b563f28 100644
--- a/src/test/java/org/caosdb/server/database/InsertTest.java
+++ b/src/test/java/org/caosdb/server/database/InsertTest.java
@@ -24,9 +24,9 @@ package org.caosdb.server.database;
 
 import static org.caosdb.server.database.DatabaseUtils.deriveStage1Inserts;
 import static org.caosdb.server.database.DatabaseUtils.deriveStage2Inserts;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
 
 import java.util.LinkedList;
 import org.caosdb.server.datatype.CollectionValue;
@@ -37,7 +37,7 @@ import org.caosdb.server.entity.EntityInterface;
 import org.caosdb.server.entity.Role;
 import org.caosdb.server.entity.StatementStatus;
 import org.caosdb.server.entity.wrapper.Property;
-import org.junit.Test;
+import org.junit.jupiter.api.Test;
 
 public class InsertTest {
 
diff --git a/src/test/java/org/caosdb/server/database/backend/transaction/RetrieveFullEntityTest.java b/src/test/java/org/caosdb/server/database/backend/transaction/RetrieveFullEntityTest.java
index 4b6429b73946110b0fd173de9c53a3b30fd83e18..f995f0806ed5c94c9e0ff7c22172c8d4893aed35 100644
--- a/src/test/java/org/caosdb/server/database/backend/transaction/RetrieveFullEntityTest.java
+++ b/src/test/java/org/caosdb/server/database/backend/transaction/RetrieveFullEntityTest.java
@@ -22,9 +22,9 @@
  */
 package org.caosdb.server.database.backend.transaction;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -34,7 +34,7 @@ import org.caosdb.server.entity.EntityInterface;
 import org.caosdb.server.entity.wrapper.Property;
 import org.caosdb.server.entity.xml.PropertyToElementStrategyTest;
 import org.caosdb.server.query.Query.Selection;
-import org.junit.Test;
+import org.junit.jupiter.api.Test;
 
 public class RetrieveFullEntityTest {
 
diff --git a/src/test/java/org/caosdb/server/database/backend/transactions/TestGetAllNames.java b/src/test/java/org/caosdb/server/database/backend/transactions/TestGetAllNames.java
index 73d434218dcd0962d31a798af510277708cf1a32..90efd31063bd480e0c1a4f36cf1a12c1b0c058a3 100644
--- a/src/test/java/org/caosdb/server/database/backend/transactions/TestGetAllNames.java
+++ b/src/test/java/org/caosdb/server/database/backend/transactions/TestGetAllNames.java
@@ -1,6 +1,6 @@
 package org.caosdb.server.database.backend.transactions;
 
-import static org.junit.Assert.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertEquals;
 
 import java.io.IOException;
 import java.util.ArrayList;
@@ -13,8 +13,8 @@ import org.caosdb.server.database.backend.transaction.GetAllNames;
 import org.caosdb.server.database.misc.TransactionBenchmark;
 import org.caosdb.server.database.proto.SparseEntity;
 import org.caosdb.server.entity.EntityInterface;
-import org.junit.BeforeClass;
-import org.junit.Test;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
 
 public class TestGetAllNames {
 
@@ -46,7 +46,7 @@ public class TestGetAllNames {
     public GetAllNamesBackend(Access access) {}
   }
 
-  @BeforeClass
+  @BeforeAll
   public static void setup() throws IOException {
     CaosDBServer.initServerProperties();
     BackendTransaction.init();
diff --git a/src/test/java/org/caosdb/server/datatype/testBoolean.java b/src/test/java/org/caosdb/server/datatype/testBoolean.java
index acf0578a332bb4ef21e1ff9eecce4037fc78540c..a8b3913089b797bcc3d1f4217c228120aec37b49 100644
--- a/src/test/java/org/caosdb/server/datatype/testBoolean.java
+++ b/src/test/java/org/caosdb/server/datatype/testBoolean.java
@@ -22,15 +22,15 @@
  */
 package org.caosdb.server.datatype;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
 
 import org.caosdb.server.datatype.AbstractDatatype.Table;
 import org.caosdb.server.entity.Message;
 import org.caosdb.server.utils.ServerMessages;
-import org.junit.Test;
+import org.junit.jupiter.api.Test;
 
 public class testBoolean {
 
diff --git a/src/test/java/org/caosdb/server/entity/EntityTest.java b/src/test/java/org/caosdb/server/entity/EntityTest.java
index 3bc85dfbf81ba865e2ebb543a28b72c5e468a485..3a923315529bfc6e17f52bf932d942344b32b68b 100644
--- a/src/test/java/org/caosdb/server/entity/EntityTest.java
+++ b/src/test/java/org/caosdb/server/entity/EntityTest.java
@@ -22,11 +22,11 @@
  */
 package org.caosdb.server.entity;
 
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
 
 import org.caosdb.server.datatype.IntegerDatatype;
-import org.junit.Test;
+import org.junit.jupiter.api.Test;
 
 public class EntityTest {
 
diff --git a/src/test/java/org/caosdb/server/entity/SelectionTest.java b/src/test/java/org/caosdb/server/entity/SelectionTest.java
index 26fbf413d42e66ccb5c65759a65dbb08a9d94df5..8772063805ea9f8d6b3916d8d029a33a9c580bb2 100644
--- a/src/test/java/org/caosdb/server/entity/SelectionTest.java
+++ b/src/test/java/org/caosdb/server/entity/SelectionTest.java
@@ -24,22 +24,21 @@
  */
 package org.caosdb.server.entity;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
 
 import java.io.IOException;
 import org.caosdb.server.CaosDBServer;
 import org.caosdb.server.entity.xml.SerializeFieldStrategy;
 import org.caosdb.server.query.Query;
 import org.caosdb.server.query.Query.Selection;
-import org.junit.Assert;
-import org.junit.BeforeClass;
-import org.junit.Test;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
 
 public class SelectionTest {
 
-  @BeforeClass
+  @BeforeAll
   public static void initServerProperties() throws IOException {
     CaosDBServer.initServerProperties();
   }
@@ -48,17 +47,17 @@ public class SelectionTest {
   public void testEmpty1() {
     final SerializeFieldStrategy setFieldStrategy = new SerializeFieldStrategy();
 
-    Assert.assertTrue(setFieldStrategy.isToBeSet("id"));
-    Assert.assertTrue(setFieldStrategy.isToBeSet("name"));
-    Assert.assertTrue(setFieldStrategy.isToBeSet("description"));
-    Assert.assertTrue(setFieldStrategy.isToBeSet("blabla"));
+    assertTrue(setFieldStrategy.isToBeSet("id"));
+    assertTrue(setFieldStrategy.isToBeSet("name"));
+    assertTrue(setFieldStrategy.isToBeSet("description"));
+    assertTrue(setFieldStrategy.isToBeSet("blabla"));
 
     setFieldStrategy.addSelection(null);
 
-    Assert.assertTrue(setFieldStrategy.isToBeSet("id"));
-    Assert.assertTrue(setFieldStrategy.isToBeSet("name"));
-    Assert.assertTrue(setFieldStrategy.isToBeSet("description"));
-    Assert.assertTrue(setFieldStrategy.isToBeSet("blabla"));
+    assertTrue(setFieldStrategy.isToBeSet("id"));
+    assertTrue(setFieldStrategy.isToBeSet("name"));
+    assertTrue(setFieldStrategy.isToBeSet("description"));
+    assertTrue(setFieldStrategy.isToBeSet("blabla"));
   }
 
   @Test
@@ -67,7 +66,7 @@ public class SelectionTest {
     final SerializeFieldStrategy setFieldStrategy =
         (new SerializeFieldStrategy()).addSelection(selection);
 
-    Assert.assertTrue(setFieldStrategy.isToBeSet("name"));
+    assertTrue(setFieldStrategy.isToBeSet("name"));
   }
 
   @Test
@@ -76,7 +75,7 @@ public class SelectionTest {
     final SerializeFieldStrategy setFieldStrategy =
         (new SerializeFieldStrategy()).addSelection(selection);
 
-    Assert.assertTrue(setFieldStrategy.isToBeSet("name"));
+    assertTrue(setFieldStrategy.isToBeSet("name"));
   }
 
   @Test
@@ -85,7 +84,7 @@ public class SelectionTest {
     final SerializeFieldStrategy setFieldStrategy =
         (new SerializeFieldStrategy()).addSelection(selection);
 
-    Assert.assertTrue(setFieldStrategy.isToBeSet("name"));
+    assertTrue(setFieldStrategy.isToBeSet("name"));
   }
 
   @Test
@@ -94,7 +93,7 @@ public class SelectionTest {
     final SerializeFieldStrategy setFieldStrategy =
         (new SerializeFieldStrategy()).addSelection(selection);
 
-    Assert.assertTrue(setFieldStrategy.isToBeSet("name"));
+    assertTrue(setFieldStrategy.isToBeSet("name"));
   }
 
   @Test
@@ -103,7 +102,7 @@ public class SelectionTest {
     final SerializeFieldStrategy setFieldStrategy =
         (new SerializeFieldStrategy()).addSelection(selection);
 
-    Assert.assertTrue(setFieldStrategy.isToBeSet("name"));
+    assertTrue(setFieldStrategy.isToBeSet("name"));
   }
 
   @Test
@@ -112,7 +111,7 @@ public class SelectionTest {
     final SerializeFieldStrategy setFieldStrategy =
         (new SerializeFieldStrategy()).addSelection(selection);
 
-    Assert.assertTrue(setFieldStrategy.isToBeSet("name"));
+    assertTrue(setFieldStrategy.isToBeSet("name"));
   }
 
   @Test
@@ -121,7 +120,7 @@ public class SelectionTest {
     final SerializeFieldStrategy setFieldStrategy =
         (new SerializeFieldStrategy()).addSelection(selection);
 
-    Assert.assertTrue(setFieldStrategy.isToBeSet("name"));
+    assertTrue(setFieldStrategy.isToBeSet("name"));
   }
 
   @Test
@@ -130,7 +129,7 @@ public class SelectionTest {
     final SerializeFieldStrategy setFieldStrategy =
         (new SerializeFieldStrategy()).addSelection(selection);
 
-    Assert.assertTrue(setFieldStrategy.isToBeSet("id"));
+    assertTrue(setFieldStrategy.isToBeSet("id"));
   }
 
   @Test
@@ -139,7 +138,7 @@ public class SelectionTest {
     final SerializeFieldStrategy setFieldStrategy =
         (new SerializeFieldStrategy()).addSelection(selection);
 
-    Assert.assertTrue(setFieldStrategy.isToBeSet("id"));
+    assertTrue(setFieldStrategy.isToBeSet("id"));
   }
 
   @Test
@@ -148,7 +147,7 @@ public class SelectionTest {
     final SerializeFieldStrategy setFieldStrategy =
         (new SerializeFieldStrategy()).addSelection(selection);
 
-    Assert.assertTrue(setFieldStrategy.isToBeSet("id"));
+    assertTrue(setFieldStrategy.isToBeSet("id"));
   }
 
   @Test
@@ -157,7 +156,7 @@ public class SelectionTest {
     final SerializeFieldStrategy setFieldStrategy =
         (new SerializeFieldStrategy()).addSelection(selection);
 
-    Assert.assertTrue(setFieldStrategy.isToBeSet("id"));
+    assertTrue(setFieldStrategy.isToBeSet("id"));
   }
 
   @Test
@@ -166,7 +165,7 @@ public class SelectionTest {
     final SerializeFieldStrategy setFieldStrategy =
         (new SerializeFieldStrategy()).addSelection(selection);
 
-    Assert.assertTrue(setFieldStrategy.isToBeSet("description"));
+    assertTrue(setFieldStrategy.isToBeSet("description"));
   }
 
   @Test
@@ -175,7 +174,7 @@ public class SelectionTest {
     final SerializeFieldStrategy setFieldStrategy =
         (new SerializeFieldStrategy()).addSelection(selection);
 
-    Assert.assertFalse(setFieldStrategy.isToBeSet("description"));
+    assertFalse(setFieldStrategy.isToBeSet("description"));
   }
 
   @Test
@@ -184,7 +183,7 @@ public class SelectionTest {
     final SerializeFieldStrategy setFieldStrategy =
         (new SerializeFieldStrategy()).addSelection(selection);
 
-    Assert.assertFalse(setFieldStrategy.isToBeSet("description"));
+    assertFalse(setFieldStrategy.isToBeSet("description"));
   }
 
   @Test
@@ -193,7 +192,7 @@ public class SelectionTest {
     final SerializeFieldStrategy setFieldStrategy =
         (new SerializeFieldStrategy()).addSelection(selection);
 
-    Assert.assertFalse(setFieldStrategy.isToBeSet("description"));
+    assertFalse(setFieldStrategy.isToBeSet("description"));
   }
 
   @Test
@@ -203,10 +202,10 @@ public class SelectionTest {
             .addSelection(new Selection("id"))
             .addSelection(new Selection("name"));
 
-    Assert.assertFalse(setFieldStrategy.isToBeSet("blablabla"));
-    Assert.assertFalse(setFieldStrategy.isToBeSet("description"));
-    Assert.assertTrue(setFieldStrategy.isToBeSet("id"));
-    Assert.assertTrue(setFieldStrategy.isToBeSet("name"));
+    assertFalse(setFieldStrategy.isToBeSet("blablabla"));
+    assertFalse(setFieldStrategy.isToBeSet("description"));
+    assertTrue(setFieldStrategy.isToBeSet("id"));
+    assertTrue(setFieldStrategy.isToBeSet("name"));
   }
 
   @Test
@@ -216,11 +215,11 @@ public class SelectionTest {
             .addSelection(new Selection("id"))
             .addSelection(new Selection("description"));
 
-    Assert.assertFalse(setFieldStrategy.isToBeSet("blablabla"));
-    Assert.assertFalse(setFieldStrategy.isToBeSet("datatype"));
-    Assert.assertTrue(setFieldStrategy.isToBeSet("description"));
-    Assert.assertTrue(setFieldStrategy.isToBeSet("id"));
-    Assert.assertTrue(setFieldStrategy.isToBeSet("name"));
+    assertFalse(setFieldStrategy.isToBeSet("blablabla"));
+    assertFalse(setFieldStrategy.isToBeSet("datatype"));
+    assertTrue(setFieldStrategy.isToBeSet("description"));
+    assertTrue(setFieldStrategy.isToBeSet("id"));
+    assertTrue(setFieldStrategy.isToBeSet("name"));
   }
 
   @Test
@@ -230,11 +229,11 @@ public class SelectionTest {
             .addSelection(new Selection("datatype"))
             .addSelection(new Selection("description"));
 
-    Assert.assertFalse(setFieldStrategy.isToBeSet("blablabla"));
-    Assert.assertTrue(setFieldStrategy.isToBeSet("datatype"));
-    Assert.assertTrue(setFieldStrategy.isToBeSet("description"));
-    Assert.assertTrue(setFieldStrategy.isToBeSet("id"));
-    Assert.assertTrue(setFieldStrategy.isToBeSet("name"));
+    assertFalse(setFieldStrategy.isToBeSet("blablabla"));
+    assertTrue(setFieldStrategy.isToBeSet("datatype"));
+    assertTrue(setFieldStrategy.isToBeSet("description"));
+    assertTrue(setFieldStrategy.isToBeSet("id"));
+    assertTrue(setFieldStrategy.isToBeSet("name"));
   }
 
   @Test
@@ -244,11 +243,11 @@ public class SelectionTest {
             .addSelection(new Selection("datatype"))
             .addSelection(new Selection("value"));
 
-    Assert.assertFalse(setFieldStrategy.isToBeSet("blablabla"));
-    Assert.assertTrue(setFieldStrategy.isToBeSet("datatype"));
-    Assert.assertTrue(setFieldStrategy.isToBeSet("value"));
-    Assert.assertTrue(setFieldStrategy.isToBeSet("id"));
-    Assert.assertTrue(setFieldStrategy.isToBeSet("name"));
+    assertFalse(setFieldStrategy.isToBeSet("blablabla"));
+    assertTrue(setFieldStrategy.isToBeSet("datatype"));
+    assertTrue(setFieldStrategy.isToBeSet("value"));
+    assertTrue(setFieldStrategy.isToBeSet("id"));
+    assertTrue(setFieldStrategy.isToBeSet("name"));
   }
 
   @Test
@@ -256,15 +255,15 @@ public class SelectionTest {
     final SerializeFieldStrategy setFieldStrategy =
         (new SerializeFieldStrategy()).addSelection(new Selection("blabla"));
 
-    Assert.assertTrue(setFieldStrategy.isToBeSet("blabla"));
-    Assert.assertTrue(setFieldStrategy.isToBeSet("id"));
-    Assert.assertTrue(setFieldStrategy.isToBeSet("name"));
-    Assert.assertFalse(setFieldStrategy.isToBeSet("bleb"));
+    assertTrue(setFieldStrategy.isToBeSet("blabla"));
+    assertTrue(setFieldStrategy.isToBeSet("id"));
+    assertTrue(setFieldStrategy.isToBeSet("name"));
+    assertFalse(setFieldStrategy.isToBeSet("bleb"));
 
     final SerializeFieldStrategy forProperty = setFieldStrategy.forProperty("blabla");
-    Assert.assertTrue(forProperty.isToBeSet("id"));
-    Assert.assertTrue(forProperty.isToBeSet("name"));
-    Assert.assertTrue(forProperty.isToBeSet("blub"));
+    assertTrue(forProperty.isToBeSet("id"));
+    assertTrue(forProperty.isToBeSet("name"));
+    assertTrue(forProperty.isToBeSet("blub"));
   }
 
   @Test
@@ -274,15 +273,15 @@ public class SelectionTest {
             .addSelection(new Selection("blabla"))
             .addSelection(new Selection("blabla.name"));
 
-    Assert.assertTrue(setFieldStrategy.isToBeSet("blabla"));
-    Assert.assertTrue(setFieldStrategy.isToBeSet("id"));
-    Assert.assertTrue(setFieldStrategy.isToBeSet("name"));
-    Assert.assertFalse(setFieldStrategy.isToBeSet("bleb"));
+    assertTrue(setFieldStrategy.isToBeSet("blabla"));
+    assertTrue(setFieldStrategy.isToBeSet("id"));
+    assertTrue(setFieldStrategy.isToBeSet("name"));
+    assertFalse(setFieldStrategy.isToBeSet("bleb"));
 
     final SerializeFieldStrategy forProperty = setFieldStrategy.forProperty("blabla");
-    Assert.assertTrue(forProperty.isToBeSet("id"));
-    Assert.assertTrue(forProperty.isToBeSet("name"));
-    Assert.assertTrue(forProperty.isToBeSet("blub"));
+    assertTrue(forProperty.isToBeSet("id"));
+    assertTrue(forProperty.isToBeSet("name"));
+    assertTrue(forProperty.isToBeSet("blub"));
   }
 
   @Test
diff --git a/src/test/java/org/caosdb/server/entity/container/PropertyContainerTest.java b/src/test/java/org/caosdb/server/entity/container/PropertyContainerTest.java
index a65d2bccb61c787ee6fed4663f97b0b84e1d98c0..836ca13f3422e429d1f516a75f7aaf4ebcc373da 100644
--- a/src/test/java/org/caosdb/server/entity/container/PropertyContainerTest.java
+++ b/src/test/java/org/caosdb/server/entity/container/PropertyContainerTest.java
@@ -22,7 +22,7 @@
  */
 package org.caosdb.server.entity.container;
 
-import static org.junit.Assert.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertEquals;
 
 import org.caosdb.server.datatype.GenericValue;
 import org.caosdb.server.datatype.ReferenceValue;
@@ -32,8 +32,8 @@ import org.caosdb.server.entity.wrapper.Property;
 import org.caosdb.server.entity.xml.PropertyToElementStrategyTest;
 import org.caosdb.server.entity.xml.SerializeFieldStrategy;
 import org.jdom2.Element;
-import org.junit.BeforeClass;
-import org.junit.Test;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
 
 public class PropertyContainerTest {
 
@@ -44,7 +44,7 @@ public class PropertyContainerTest {
   public static Entity houseOwner = null;
   public static Property windowProperty = null;
 
-  @BeforeClass
+  @BeforeAll
   public static void setup() {
     window = new Entity(1234);
     windowHeight = new Property(new Entity("window.height", Role.Property));
diff --git a/src/test/java/org/caosdb/server/entity/xml/PropertyToElementStrategyTest.java b/src/test/java/org/caosdb/server/entity/xml/PropertyToElementStrategyTest.java
index fa8469dba9d95b70d77dcf0428e4426ff1672548..7f534892f8e84fae4f2a5e5013852a8a86698cf3 100644
--- a/src/test/java/org/caosdb/server/entity/xml/PropertyToElementStrategyTest.java
+++ b/src/test/java/org/caosdb/server/entity/xml/PropertyToElementStrategyTest.java
@@ -22,7 +22,7 @@
  */
 package org.caosdb.server.entity.xml;
 
-import static org.junit.Assert.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertEquals;
 
 import org.caosdb.server.datatype.GenericValue;
 import org.caosdb.server.datatype.ReferenceValue;
@@ -32,8 +32,8 @@ import org.caosdb.server.entity.Role;
 import org.caosdb.server.entity.wrapper.Property;
 import org.caosdb.server.query.Query.Selection;
 import org.jdom2.Element;
-import org.junit.Before;
-import org.junit.Test;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
 
 public class PropertyToElementStrategyTest {
 
@@ -62,7 +62,7 @@ public class PropertyToElementStrategyTest {
     return result;
   }
 
-  @Before
+  @BeforeEach
   public void setup() {
     window = new Entity(1234, Role.Record);
     windowHeight = new Property(new Entity("height", Role.Property));
diff --git a/src/test/java/org/caosdb/server/grpc/CaosDBToGrpcConvertersTest.java b/src/test/java/org/caosdb/server/grpc/CaosDBToGrpcConvertersTest.java
index 84baba26fbadb920320b8d22a789509e855f9693..8a078e8b9f8d7e3590ddeecff762f8fd52fe1df7 100644
--- a/src/test/java/org/caosdb/server/grpc/CaosDBToGrpcConvertersTest.java
+++ b/src/test/java/org/caosdb/server/grpc/CaosDBToGrpcConvertersTest.java
@@ -1,8 +1,8 @@
 package org.caosdb.server.grpc;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
 
 import java.util.TimeZone;
 import org.caosdb.datetime.DateTimeFactory2;
@@ -16,7 +16,7 @@ import org.caosdb.server.entity.StatementStatus;
 import org.caosdb.server.entity.wrapper.Parent;
 import org.caosdb.server.entity.wrapper.Property;
 import org.caosdb.server.entity.xml.IdAndServerMessagesOnlyStrategy;
-import org.junit.Test;
+import org.junit.jupiter.api.Test;
 
 public class CaosDBToGrpcConvertersTest {
 
diff --git a/src/test/java/org/caosdb/server/jobs/JobConfigTest.java b/src/test/java/org/caosdb/server/jobs/JobConfigTest.java
index 70917b53553c6b94b283ed1e39b0ee81db9d466c..d182cafaa0db347ea5f0953d5d56f6413bdd381d 100644
--- a/src/test/java/org/caosdb/server/jobs/JobConfigTest.java
+++ b/src/test/java/org/caosdb/server/jobs/JobConfigTest.java
@@ -1,6 +1,6 @@
 package org.caosdb.server.jobs;
 
-import static org.junit.Assert.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertEquals;
 
 import java.io.IOException;
 import org.caosdb.server.CaosDBServer;
@@ -10,12 +10,12 @@ import org.caosdb.server.entity.RetrieveEntity;
 import org.caosdb.server.entity.Role;
 import org.caosdb.server.entity.UpdateEntity;
 import org.jdom2.Element;
-import org.junit.BeforeClass;
-import org.junit.Test;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
 
 public class JobConfigTest {
 
-  @BeforeClass
+  @BeforeAll
   public static void setup() throws IOException {
     CaosDBServer.initServerProperties();
   }
diff --git a/src/test/java/org/caosdb/server/jobs/ScheduleTest.java b/src/test/java/org/caosdb/server/jobs/ScheduleTest.java
index 9aa8e6f66788911f2c4314c44549d543277398d2..7033ac35bf10391c85745d74a7184f065d8f6e38 100644
--- a/src/test/java/org/caosdb/server/jobs/ScheduleTest.java
+++ b/src/test/java/org/caosdb/server/jobs/ScheduleTest.java
@@ -22,16 +22,16 @@
  */
 package org.caosdb.server.jobs;
 
-import static org.junit.Assert.fail;
+import static org.junit.jupiter.api.Assertions.fail;
 
 import java.io.IOException;
 import org.caosdb.server.CaosDBServer;
-import org.junit.BeforeClass;
-import org.junit.Test;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
 
 public class ScheduleTest {
 
-  @BeforeClass
+  @BeforeAll
   public static void setup() throws IOException {
     CaosDBServer.initServerProperties();
   }
diff --git a/src/test/java/org/caosdb/server/jobs/core/TestInsertFilesInDir.java b/src/test/java/org/caosdb/server/jobs/core/TestInsertFilesInDir.java
index 5d81ac368f65c559eb666f003f34da522f191f21..a7202be9e7f8a4cfea5c050f403f15025511d09c 100644
--- a/src/test/java/org/caosdb/server/jobs/core/TestInsertFilesInDir.java
+++ b/src/test/java/org/caosdb/server/jobs/core/TestInsertFilesInDir.java
@@ -1,16 +1,16 @@
 package org.caosdb.server.jobs.core;
 
-import static org.junit.Assert.assertTrue;
+import static org.junit.jupiter.api.Assertions.assertTrue;
 
 import java.io.File;
 import java.io.IOException;
 import org.caosdb.server.CaosDBServer;
-import org.junit.BeforeClass;
-import org.junit.Test;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
 
 public class TestInsertFilesInDir {
 
-  @BeforeClass
+  @BeforeAll
   public static void setup() throws IOException {
     CaosDBServer.initServerProperties();
   }
diff --git a/src/test/java/org/caosdb/server/logging/TestLogging.java b/src/test/java/org/caosdb/server/logging/TestLogging.java
index f1a130ad09c0eca378560b500fc38344df279f17..0f67ebeae074c21712567c45cdd60948350a77bf 100644
--- a/src/test/java/org/caosdb/server/logging/TestLogging.java
+++ b/src/test/java/org/caosdb/server/logging/TestLogging.java
@@ -1,12 +1,15 @@
 package org.caosdb.server.logging;
 
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
 import java.io.File;
 import java.io.IOException;
 import org.apache.commons.io.FileUtils;
 import org.caosdb.server.CaosDBServer;
-import org.junit.Assert;
-import org.junit.BeforeClass;
-import org.junit.Test;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
 import org.restlet.Request;
 import org.restlet.Response;
 import org.slf4j.Logger;
@@ -19,7 +22,7 @@ public class TestLogging {
       LoggerFactory.getLogger(CaosDBServer.REQUEST_ERRORS_LOGGER);
   private Logger request_time_logger = LoggerFactory.getLogger(CaosDBServer.REQUEST_TIME_LOGGER);
 
-  @BeforeClass
+  @BeforeAll
   public static void setup() throws IOException {
     File f = new File("testlog/");
     FileUtils.forceDeleteOnExit(f);
@@ -32,17 +35,17 @@ public class TestLogging {
     logger.info("info");
     logger.debug("debug");
     logger.trace("trace");
-    Assert.assertEquals(logger.getName(), "org.caosdb.server.logging.TestLogging");
-    Assert.assertTrue(logger.isErrorEnabled());
-    Assert.assertTrue(logger.isWarnEnabled());
-    Assert.assertTrue(logger.isInfoEnabled());
-    Assert.assertTrue(logger.isDebugEnabled());
-    Assert.assertTrue(logger.isTraceEnabled());
+    assertEquals(logger.getName(), "org.caosdb.server.logging.TestLogging");
+    assertTrue(logger.isErrorEnabled());
+    assertTrue(logger.isWarnEnabled());
+    assertTrue(logger.isInfoEnabled());
+    assertTrue(logger.isDebugEnabled());
+    assertTrue(logger.isTraceEnabled());
   }
 
   @Test
   public void testRequestErrorsLogger() {
-    Assert.assertTrue(request_errors_logger.isErrorEnabled());
+    assertTrue(request_errors_logger.isErrorEnabled());
     request_errors_logger.error(
         "ERROR:REQUEST:" + "ABC0123",
         new RequestErrorLogMessage(new Request(), new Response(null)),
@@ -51,8 +54,8 @@ public class TestLogging {
 
   @Test
   public void testRequestTimeLogger() {
-    Assert.assertTrue(CaosDBServer.isDebugMode());
-    Assert.assertFalse(request_time_logger.isErrorEnabled());
-    Assert.assertFalse(request_time_logger.isTraceEnabled());
+    assertTrue(CaosDBServer.isDebugMode());
+    assertFalse(request_time_logger.isErrorEnabled());
+    assertFalse(request_time_logger.isTraceEnabled());
   }
 }
diff --git a/src/test/java/org/caosdb/server/permissions/EntityACLTest.java b/src/test/java/org/caosdb/server/permissions/EntityACLTest.java
index 30c0cd992573c0c083d863a6d60750dd77d6e035..5feab38f5a465844b52946ef4bb9e3ce32c6dd5c 100644
--- a/src/test/java/org/caosdb/server/permissions/EntityACLTest.java
+++ b/src/test/java/org/caosdb/server/permissions/EntityACLTest.java
@@ -22,10 +22,10 @@
  */
 package org.caosdb.server.permissions;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
 
 import java.io.IOException;
 import java.util.BitSet;
@@ -57,9 +57,8 @@ import org.caosdb.server.resource.AbstractCaosDBServerResource.XMLParser;
 import org.caosdb.server.utils.Utils;
 import org.jdom2.Element;
 import org.jdom2.JDOMException;
-import org.junit.Assert;
-import org.junit.BeforeClass;
-import org.junit.Test;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
 
 public class EntityACLTest {
 
@@ -157,7 +156,7 @@ public class EntityACLTest {
     }
   }
 
-  @BeforeClass
+  @BeforeAll
   public static void init() throws IOException {
     CaosDBServer.initServerProperties();
     CaosDBServer.initShiro();
@@ -182,37 +181,37 @@ public class EntityACLTest {
     l = Long.MIN_VALUE;
     System.out.println(EntityACL.convert(l));
     final BitSet bitSet = new BitSet(64);
-    Assert.assertEquals(0, convert(bitSet));
+    assertEquals(0, convert(bitSet));
 
     bitSet.set(0);
-    Assert.assertEquals(1, convert(bitSet));
+    assertEquals(1, convert(bitSet));
 
     bitSet.clear();
     bitSet.set(63);
-    Assert.assertEquals(Long.MIN_VALUE, convert(bitSet));
+    assertEquals(Long.MIN_VALUE, convert(bitSet));
 
     bitSet.clear();
     bitSet.set(0, 63, true);
-    Assert.assertEquals(Long.MAX_VALUE, convert(bitSet));
+    assertEquals(Long.MAX_VALUE, convert(bitSet));
 
     bitSet.clear();
     bitSet.set(62);
-    Assert.assertEquals(EntityACL.MIN_PRIORITY_BITSET, convert(bitSet));
+    assertEquals(EntityACL.MIN_PRIORITY_BITSET, convert(bitSet));
 
     bitSet.set(63);
-    Assert.assertEquals(-EntityACL.MIN_PRIORITY_BITSET, convert(bitSet));
+    assertEquals(-EntityACL.MIN_PRIORITY_BITSET, convert(bitSet));
 
     bitSet.clear();
     bitSet.set(0, 64, true);
-    Assert.assertEquals(-1L, convert(bitSet));
+    assertEquals(-1L, convert(bitSet));
 
-    Assert.assertTrue(EntityACL.convert(-12523).get(63));
-    Assert.assertFalse(EntityACL.convert(12523).get(63));
+    assertTrue(EntityACL.convert(-12523).get(63));
+    assertFalse(EntityACL.convert(12523).get(63));
 
     bitSet.clear();
     bitSet.set(0, 63, true);
-    Assert.assertEquals(Long.MAX_VALUE + 1L, Long.MIN_VALUE);
-    Assert.assertEquals(Long.MAX_VALUE, convert(bitSet));
+    assertEquals(Long.MAX_VALUE + 1L, Long.MIN_VALUE);
+    assertEquals(Long.MAX_VALUE, convert(bitSet));
   }
 
   @Test
@@ -220,11 +219,11 @@ public class EntityACLTest {
     final BitSet bitSet = new BitSet(64);
     bitSet.set(63);
 
-    Assert.assertTrue(EntityACL.isDenial(convert(bitSet)));
-    Assert.assertTrue(EntityACL.isDenial(-12523));
-    Assert.assertFalse(EntityACL.isDenial(0));
-    Assert.assertFalse(EntityACL.isDenial(246345));
-    Assert.assertTrue(EntityACL.isDenial(-EntityACL.MIN_PRIORITY_BITSET));
+    assertTrue(EntityACL.isDenial(convert(bitSet)));
+    assertTrue(EntityACL.isDenial(-12523));
+    assertFalse(EntityACL.isDenial(0));
+    assertFalse(EntityACL.isDenial(246345));
+    assertTrue(EntityACL.isDenial(-EntityACL.MIN_PRIORITY_BITSET));
   }
 
   @Test
@@ -232,83 +231,82 @@ public class EntityACLTest {
     final BitSet bitSet = new BitSet(32);
     bitSet.set(27);
 
-    Assert.assertTrue(EntityACL.isAllowance(convert(bitSet)));
-    Assert.assertTrue(EntityACL.isAllowance(12523));
-    Assert.assertTrue(EntityACL.isAllowance(0));
-    Assert.assertFalse(EntityACL.isAllowance(-246345));
-    Assert.assertTrue(EntityACL.isAllowance(EntityACL.MIN_PRIORITY_BITSET));
+    assertTrue(EntityACL.isAllowance(convert(bitSet)));
+    assertTrue(EntityACL.isAllowance(12523));
+    assertTrue(EntityACL.isAllowance(0));
+    assertFalse(EntityACL.isAllowance(-246345));
+    assertTrue(EntityACL.isAllowance(EntityACL.MIN_PRIORITY_BITSET));
   }
 
   @Test
   public void testGetResultingACL() {
     final LinkedList<Long> acl = new LinkedList<Long>();
     acl.add(1L); // +P1
-    Assert.assertEquals(1L, EntityACL.getResultingACL(acl)); // P1
+    assertEquals(1L, EntityACL.getResultingACL(acl)); // P1
 
     acl.add(2L); // +P2
-    Assert.assertEquals(3L, EntityACL.getResultingACL(acl)); // P1,P2
+    assertEquals(3L, EntityACL.getResultingACL(acl)); // P1,P2
 
     acl.add(4L); // +P3
-    Assert.assertEquals(7L, EntityACL.getResultingACL(acl)); // P1,P2,P3
+    assertEquals(7L, EntityACL.getResultingACL(acl)); // P1,P2,P3
 
     acl.add(Long.MIN_VALUE + 1); // -P1
-    Assert.assertEquals(6L, EntityACL.getResultingACL(acl)); // P2,P3
+    assertEquals(6L, EntityACL.getResultingACL(acl)); // P2,P3
 
     acl.add(Long.MIN_VALUE + 1); // -P1Allow
-    Assert.assertEquals(6L, EntityACL.getResultingACL(acl)); // P2,P3
+    assertEquals(6L, EntityACL.getResultingACL(acl)); // P2,P3
 
     acl.add(Long.MIN_VALUE + 8); // -P4
-    Assert.assertEquals(6L, EntityACL.getResultingACL(acl)); // P2,P3
+    assertEquals(6L, EntityACL.getResultingACL(acl)); // P2,P3
 
     acl.add(8L); // +P4
-    Assert.assertEquals(6L, EntityACL.getResultingACL(acl)); // P2,P3
+    assertEquals(6L, EntityACL.getResultingACL(acl)); // P2,P3
 
     acl.add(EntityACL.MIN_PRIORITY_BITSET + 1); // ++P1
-    Assert.assertEquals(7L, EntityACL.getResultingACL(acl)); // P1,P2,P3
+    assertEquals(7L, EntityACL.getResultingACL(acl)); // P1,P2,P3
 
     acl.add(EntityACL.MIN_PRIORITY_BITSET + 2); // ++P2
-    Assert.assertEquals(7L, EntityACL.getResultingACL(acl)); // P1,P2,P3
+    assertEquals(7L, EntityACL.getResultingACL(acl)); // P1,P2,P3
 
     acl.add(Long.MIN_VALUE + 1); // -P1
-    Assert.assertEquals(7l, EntityACL.getResultingACL(acl)); // P1,P2,P3
+    assertEquals(7l, EntityACL.getResultingACL(acl)); // P1,P2,P3
 
     acl.add(Long.MIN_VALUE + 4); // -P1
-    Assert.assertEquals(3l, EntityACL.getResultingACL(acl)); // P1,P2
+    assertEquals(3l, EntityACL.getResultingACL(acl)); // P1,P2
 
     acl.add(EntityACL.MIN_PRIORITY_BITSET + 8); // ++P4
-    Assert.assertEquals(11L, EntityACL.getResultingACL(acl)); // P1,P2,P4
+    assertEquals(11L, EntityACL.getResultingACL(acl)); // P1,P2,P4
 
     acl.add(Long.MIN_VALUE + EntityACL.MIN_PRIORITY_BITSET + 2); // --P2
-    Assert.assertEquals(9L, EntityACL.getResultingACL(acl)); // P1,P4
+    assertEquals(9L, EntityACL.getResultingACL(acl)); // P1,P4
 
     acl.add(Long.MIN_VALUE + EntityACL.MIN_PRIORITY_BITSET + 1); // --P1Allow
-    Assert.assertEquals(8L, EntityACL.getResultingACL(acl)); // P4
+    assertEquals(8L, EntityACL.getResultingACL(acl)); // P4
   }
 
   @Test
   public void testOwnerBitSet() {
-    Assert.assertEquals(convert(EntityACL.convert(EntityACL.OWNER_BITSET).get(1, 32)), 0);
+    assertEquals(convert(EntityACL.convert(EntityACL.OWNER_BITSET).get(1, 32)), 0);
   }
 
   @Test
   public void testDeserialize() {
-    Assert.assertTrue(EntityACL.deserialize("{}") instanceof EntityACL);
-    Assert.assertTrue(EntityACL.deserialize("{\"tf\":134}") instanceof EntityACL);
-    Assert.assertTrue(EntityACL.deserialize("{\"tf\":6343,\"bla\":884}") instanceof EntityACL);
-    Assert.assertTrue(EntityACL.deserialize("{\"tf\":-2835,\"bla\":884}") instanceof EntityACL);
-    Assert.assertTrue(
-        EntityACL.deserialize("{\"?OWNER?\":526,\"tahsdh   \": -235}") instanceof EntityACL);
-    Assert.assertTrue(EntityACL.deserialize("{\"asdf\":2345}") instanceof EntityACL);
-    Assert.assertTrue(raisesIllegalStateException("{"));
-    Assert.assertTrue(raisesIllegalStateException("}"));
-    Assert.assertTrue(raisesIllegalStateException("{tf:}"));
-    Assert.assertTrue(raisesIllegalStateException("{tf:;}"));
-    Assert.assertTrue(raisesIllegalStateException("{:234}"));
-    Assert.assertTrue(raisesIllegalStateException("{:234;}"));
-    Assert.assertTrue(raisesIllegalStateException("{tf:tf;}"));
-    Assert.assertTrue(raisesIllegalStateException("{tf: +5259;}"));
-    Assert.assertTrue(raisesIllegalStateException("{tf;}"));
-    Assert.assertTrue(raisesIllegalStateException("{tf:123223727356235782735235;}"));
+    assertTrue(EntityACL.deserialize("{}") instanceof EntityACL);
+    assertTrue(EntityACL.deserialize("{\"tf\":134}") instanceof EntityACL);
+    assertTrue(EntityACL.deserialize("{\"tf\":6343,\"bla\":884}") instanceof EntityACL);
+    assertTrue(EntityACL.deserialize("{\"tf\":-2835,\"bla\":884}") instanceof EntityACL);
+    assertTrue(EntityACL.deserialize("{\"?OWNER?\":526,\"tahsdh   \": -235}") instanceof EntityACL);
+    assertTrue(EntityACL.deserialize("{\"asdf\":2345}") instanceof EntityACL);
+    assertTrue(raisesIllegalStateException("{"));
+    assertTrue(raisesIllegalStateException("}"));
+    assertTrue(raisesIllegalStateException("{tf:}"));
+    assertTrue(raisesIllegalStateException("{tf:;}"));
+    assertTrue(raisesIllegalStateException("{:234}"));
+    assertTrue(raisesIllegalStateException("{:234;}"));
+    assertTrue(raisesIllegalStateException("{tf:tf;}"));
+    assertTrue(raisesIllegalStateException("{tf: +5259;}"));
+    assertTrue(raisesIllegalStateException("{tf;}"));
+    assertTrue(raisesIllegalStateException("{tf:123223727356235782735235;}"));
   }
 
   public boolean raisesIllegalStateException(final String input) {
@@ -356,29 +354,29 @@ public class EntityACLTest {
     user2.login(token2);
 
     f.grant(role1, "UPDATE:NAME");
-    Assert.assertTrue((f.create().isPermitted(user1, EntityPermission.UPDATE_NAME)));
-    Assert.assertFalse((f.create().isPermitted(user2, EntityPermission.UPDATE_NAME)));
+    assertTrue((f.create().isPermitted(user1, EntityPermission.UPDATE_NAME)));
+    assertFalse((f.create().isPermitted(user2, EntityPermission.UPDATE_NAME)));
     f.grant(role2, "DELETE");
-    Assert.assertFalse((f.create().isPermitted(user1, EntityPermission.DELETE)));
-    Assert.assertTrue((f.create().isPermitted(user2, EntityPermission.DELETE)));
+    assertFalse((f.create().isPermitted(user1, EntityPermission.DELETE)));
+    assertTrue((f.create().isPermitted(user2, EntityPermission.DELETE)));
     f.deny(role2, 1);
     f.deny(role1, 1);
-    Assert.assertFalse((f.create().isPermitted(user1, EntityPermission.DELETE)));
-    Assert.assertFalse((f.create().isPermitted(user2, EntityPermission.DELETE)));
+    assertFalse((f.create().isPermitted(user1, EntityPermission.DELETE)));
+    assertFalse((f.create().isPermitted(user2, EntityPermission.DELETE)));
     f.grant(role1, true, 1);
-    Assert.assertTrue((f.create().isPermitted(user1, EntityPermission.DELETE)));
-    Assert.assertFalse((f.create().isPermitted(user2, EntityPermission.DELETE)));
+    assertTrue((f.create().isPermitted(user1, EntityPermission.DELETE)));
+    assertFalse((f.create().isPermitted(user2, EntityPermission.DELETE)));
     f.deny(role2, true, 1);
-    Assert.assertTrue((f.create().isPermitted(user1, EntityPermission.DELETE)));
-    Assert.assertFalse((f.create().isPermitted(user2, EntityPermission.DELETE)));
+    assertTrue((f.create().isPermitted(user1, EntityPermission.DELETE)));
+    assertFalse((f.create().isPermitted(user2, EntityPermission.DELETE)));
     f.grant(role2, true, 1);
-    Assert.assertTrue((f.create().isPermitted(user1, EntityPermission.DELETE)));
-    Assert.assertFalse((f.create().isPermitted(user2, EntityPermission.DELETE)));
+    assertTrue((f.create().isPermitted(user1, EntityPermission.DELETE)));
+    assertFalse((f.create().isPermitted(user2, EntityPermission.DELETE)));
     f.deny(role1, true, 1);
-    Assert.assertFalse((f.create().isPermitted(user1, EntityPermission.DELETE)));
-    Assert.assertFalse((f.create().isPermitted(user2, EntityPermission.DELETE)));
-    Assert.assertTrue((f.create().isPermitted(user1, EntityPermission.UPDATE_NAME)));
-    Assert.assertFalse((f.create().isPermitted(user2, EntityPermission.UPDATE_NAME)));
+    assertFalse((f.create().isPermitted(user1, EntityPermission.DELETE)));
+    assertFalse((f.create().isPermitted(user2, EntityPermission.DELETE)));
+    assertTrue((f.create().isPermitted(user1, EntityPermission.UPDATE_NAME)));
+    assertFalse((f.create().isPermitted(user2, EntityPermission.UPDATE_NAME)));
   }
 
   @Test
@@ -400,10 +398,7 @@ public class EntityACLTest {
     f.remove(other); // normalize and remove "other"
 
     EntityACL tester = f.create();
-    assertEquals(
-        "only the very last rule survived, the others have been overriden or removed",
-        1,
-        tester.getRules().size());
+    assertEquals(1, tester.getRules().size()); // Permissions array has been written and read
     for (EntityACI aci : tester.getRules()) {
       assertEquals(aci.getResponsibleAgent(), org.caosdb.server.permissions.Role.create("role5"));
     }
diff --git a/src/test/java/org/caosdb/server/permissions/EntityPermissionTest.java b/src/test/java/org/caosdb/server/permissions/EntityPermissionTest.java
index fd7c3e8e7e9a66a8b99ac09487bfa02767497e22..8699a4311a27172904878d461f2b708b2a7d18ab 100644
--- a/src/test/java/org/caosdb/server/permissions/EntityPermissionTest.java
+++ b/src/test/java/org/caosdb/server/permissions/EntityPermissionTest.java
@@ -1,8 +1,8 @@
 package org.caosdb.server.permissions;
 
-import static org.junit.Assert.*;
+import static org.junit.jupiter.api.Assertions.*;
 
-import org.junit.Test;
+import org.junit.jupiter.api.Test;
 
 public class EntityPermissionTest {
 
diff --git a/src/test/java/org/caosdb/server/query/QueryTest.java b/src/test/java/org/caosdb/server/query/QueryTest.java
index 8f3d4946c36d795e5e7bd9048a66f86cc0290a0b..1827ceaf576bfba79059d557fa1422839cad8d28 100644
--- a/src/test/java/org/caosdb/server/query/QueryTest.java
+++ b/src/test/java/org/caosdb/server/query/QueryTest.java
@@ -19,59 +19,79 @@
  */
 package org.caosdb.server.query;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.fail;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.fail;
 
 import java.io.IOException;
+import org.apache.shiro.SecurityUtils;
+import org.apache.shiro.subject.Subject;
 import org.caosdb.server.CaosDBServer;
+import org.caosdb.server.ServerProperties;
+import org.caosdb.server.accessControl.AnonymousAuthenticationToken;
 import org.caosdb.server.database.access.InitAccess;
 import org.caosdb.server.transaction.WriteTransaction;
-import org.junit.BeforeClass;
-import org.junit.Test;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
 
 public class QueryTest {
 
-  @BeforeClass
+  @BeforeAll
   public static void initServerProperties() throws IOException {
     CaosDBServer.initServerProperties();
+    CaosDBServer.initShiro();
   }
 
   String getCacheKey(String query) {
     Query q = new Query(query);
     q.parse();
-    return q.getCacheKey();
+    return q.getCacheKey(true);
+  }
+
+  String getCacheKeyWithUser(String query) {
+    Subject anonymous = SecurityUtils.getSubject();
+    CaosDBServer.setProperty(ServerProperties.KEY_AUTH_OPTIONAL, "true");
+    anonymous.login(AnonymousAuthenticationToken.getInstance());
+    Query q = new Query(query, anonymous);
+    q.parse();
+    return q.getCacheKey(true);
   }
 
   @Test
   public void testGetKey() {
-    assertEquals("enamePOV(pname,=,val1)", getCacheKey("FIND ename WITH pname = val1"));
-    assertEquals("enamePOV(pname,=,val1)", getCacheKey("COUNT ename WITH pname = val1"));
-    assertEquals("enamePOV(pname,=,val1)", getCacheKey("SELECT bla FROM ename WITH pname = val1"));
-    assertEquals("enamePOV(pname,null,null)", getCacheKey("SELECT bla FROM ename WITH pname"));
+    assertEquals("E_enameF_POV(pname,=,val1)", getCacheKey("FIND ename WITH pname = val1"));
+    assertEquals("E_enameF_POV(pname,=,val1)", getCacheKey("COUNT ename WITH pname = val1"));
+    assertEquals(
+        "E_enameF_POV(pname,=,val1)", getCacheKey("SELECT bla FROM ename WITH pname = val1"));
+    assertEquals("E_enameF_POV(pname,null,null)", getCacheKey("SELECT bla FROM ename WITH pname"));
     assertEquals(
-        "enamemaxPOV(pname,null,null)",
+        "E_enameF_maxPOV(pname,null,null)",
         getCacheKey("SELECT bla FROM ename WITH THE GREATEST pname"));
 
     assertEquals(
-        "RECORDenamePOV(pname,=,val1)", getCacheKey("FIND RECORD ename WITH pname = val1"));
-    assertEquals("ENTITYPOV(pname,=,val1)", getCacheKey("COUNT ENTITY WITH pname = val1"));
+        "R_RECORDE_enameF_POV(pname,=,val1)", getCacheKey("FIND RECORD ename WITH pname = val1"));
+    assertEquals("R_ENTITYF_POV(pname,=,val1)", getCacheKey("COUNT ENTITY WITH pname = val1"));
     assertEquals(
-        "enameConj(POV(pname,=,val1)POV(ename2,=,val2))",
+        "E_enameF_Conj(POV(pname,=,val1)POV(ename2,=,val2))",
         getCacheKey("SELECT bla FROM ename WITH pname = val1 AND ename2 = val2"));
 
-    assertEquals("versionedENTITYID(,>,2)", getCacheKey("FIND ANY VERSION OF ENTITY WITH ID > 2"));
-    assertEquals("ENTITYID(min,,)", getCacheKey("FIND ENTITY WITH THE SMALLEST ID"));
-    assertEquals("ENTITYSAT(asdf/%%)", getCacheKey("FIND ENTITY WHICH IS STORED AT /asdf/*"));
-    assertEquals("ENTITYSAT(asdf/asdf)", getCacheKey("FIND ENTITY WHICH IS STORED AT asdf/asdf"));
+    assertEquals("V_R_ENTITYF_ID(,>,2)", getCacheKey("FIND ANY VERSION OF ENTITY WITH ID > 2"));
+    assertEquals("R_ENTITYF_ID(min,,)", getCacheKey("FIND ENTITY WITH THE SMALLEST ID"));
+    assertEquals("R_ENTITYF_SAT(asdf/%%)", getCacheKey("FIND ENTITY WHICH IS STORED AT /asdf/*"));
     assertEquals(
-        "enamePOV(ref1,null,null)SUB(POV(pname,>,val1)",
+        "R_ENTITYF_SAT(asdf/asdf)", getCacheKey("FIND ENTITY WHICH IS STORED AT asdf/asdf"));
+    assertEquals(
+        "E_enameF_POV(ref1,null,null)SUB(POV(pname,>,val1)",
         getCacheKey("FIND ename WITH ref1 WITH pname > val1 "));
     assertEquals(
-        "ename@(ref1,null)SUB(POV(pname,>,val1)",
+        "E_enameF_@(ref1,null)SUB(POV(pname,>,val1)",
         getCacheKey("FIND ename WHICH IS REFERENCED BY ref1 WITH pname > val1 "));
+
+    assertEquals(
+        "U_anonymous@anonymousE_enameF_POV(pname,=,val1)",
+        getCacheKeyWithUser("FIND ename WITH pname = val1"));
   }
 
   @Test
diff --git a/src/test/java/org/caosdb/server/query/TestCQL.java b/src/test/java/org/caosdb/server/query/TestCQL.java
index 3217d4228068027628b1846eb6073da1bc18052e..cfd53f94f305088f04f9a5eb0a2e443ad65f9c6c 100644
--- a/src/test/java/org/caosdb/server/query/TestCQL.java
+++ b/src/test/java/org/caosdb/server/query/TestCQL.java
@@ -21,12 +21,12 @@
  */
 package org.caosdb.server.query;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.fail;
 
 import java.io.IOException;
 import java.sql.SQLException;
@@ -44,12 +44,12 @@ import org.caosdb.server.query.CQLParser.CqContext;
 import org.caosdb.server.query.Query.Pattern;
 import org.caosdb.server.query.Query.QueryException;
 import org.caosdb.server.utils.Initialization;
-import org.junit.BeforeClass;
-import org.junit.Test;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
 
 public class TestCQL {
 
-  @BeforeClass
+  @BeforeAll
   public static void initServerProperties() throws IOException {
     CaosDBServer.initServerProperties();
   }
diff --git a/src/test/java/org/caosdb/server/resource/FileSystemResourceTest.java b/src/test/java/org/caosdb/server/resource/FileSystemResourceTest.java
index ed89c68ae554c0f7718ccabcb6fb2b48c0d59e61..63c10c1f3e3f7e44e34ece9248bf87b4cbfa139f 100644
--- a/src/test/java/org/caosdb/server/resource/FileSystemResourceTest.java
+++ b/src/test/java/org/caosdb/server/resource/FileSystemResourceTest.java
@@ -22,18 +22,24 @@
  */
 package org.caosdb.server.resource;
 
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
 import java.io.File;
-import org.junit.Test;
+import org.junit.jupiter.api.Test;
 
 public class FileSystemResourceTest {
 
-  @Test(expected = NullPointerException.class)
+  @Test
   public void testGetFileElementNullDir() throws Exception {
-    new FileSystemResource().getFileElement(null, new File("conf/ext/server.conf"));
+    assertThrows(
+        NullPointerException.class,
+        () -> new FileSystemResource().getFileElement(null, new File("conf/ext/server.conf")));
   }
 
-  @Test(expected = NullPointerException.class)
+  @Test
   public void testGetFileElementNullFile() throws Exception {
-    new FileSystemResource().getFileElement("somedir/", null);
+    assertThrows(
+        NullPointerException.class,
+        () -> new FileSystemResource().getFileElement("somedir/", null));
   }
 }
diff --git a/src/test/java/org/caosdb/server/resource/TestAbstractCaosDBServerResource.java b/src/test/java/org/caosdb/server/resource/TestAbstractCaosDBServerResource.java
index 226c9aaac077a56fa96535480418762d30bbb6e9..ca4fbb0954f469055c2da3d0bf00b03cdc9dd563 100644
--- a/src/test/java/org/caosdb/server/resource/TestAbstractCaosDBServerResource.java
+++ b/src/test/java/org/caosdb/server/resource/TestAbstractCaosDBServerResource.java
@@ -1,10 +1,12 @@
 package org.caosdb.server.resource;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
 
+import java.io.File;
 import java.io.IOException;
 import java.nio.file.Files;
+import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.security.NoSuchAlgorithmException;
 import java.sql.SQLException;
@@ -28,17 +30,14 @@ import org.caosdb.server.database.misc.TransactionBenchmark;
 import org.caosdb.server.permissions.PermissionRule;
 import org.caosdb.server.utils.WebinterfaceUtils;
 import org.jdom2.Element;
-import org.junit.BeforeClass;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.TemporaryFolder;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.io.TempDir;
 import org.restlet.data.Reference;
 import org.restlet.representation.Representation;
 
 public class TestAbstractCaosDBServerResource {
 
-  @Rule public TemporaryFolder tempFolder = new TemporaryFolder();
-
   /** a no-op mock-up which resolved all rules to an empty set of permissions. */
   public static class RetrievePermissionRulesMockup implements RetrievePermissionRulesImpl {
 
@@ -77,7 +76,7 @@ public class TestAbstractCaosDBServerResource {
     }
   }
 
-  @BeforeClass
+  @BeforeAll
   public static void initServerProperties() throws IOException {
     CaosDBServer.initServerProperties();
 
@@ -87,7 +86,7 @@ public class TestAbstractCaosDBServerResource {
   }
 
   @Test
-  public void testReponseRootElement() throws IOException {
+  public void testReponseRootElement(@TempDir Path tmpDir) throws IOException {
     final Subject user = new DelegatingSubject(new DefaultSecurityManager(new AnonymousRealm()));
     CaosDBServer.setProperty(ServerProperties.KEY_AUTH_OPTIONAL, "true");
     user.login(AnonymousAuthenticationToken.getInstance());
@@ -133,7 +132,7 @@ public class TestAbstractCaosDBServerResource {
             return WebinterfaceUtils.getInstance(getRootRef().toString());
           }
         };
-    provideUserSourcesFile();
+    provideUserSourcesFile(tmpDir);
     Element response = s.generateRootElement();
     assertNotNull(response);
     assertEquals("TEST-SRID", response.getAttribute("srid").getValue());
@@ -144,9 +143,16 @@ public class TestAbstractCaosDBServerResource {
     assertNotNull(userInfo);
   }
 
-  /** Creates a dummy usersources.ini and injects it into the server properties. */
-  private void provideUserSourcesFile() throws IOException {
-    String usersourcesFileName = tempFolder.newFile("usersources.ini").getAbsolutePath();
+  /**
+   * Creates a dummy usersources.ini and injects it into the server properties.
+   *
+   * @param tmpDir
+   */
+  private void provideUserSourcesFile(Path tempFolder) throws IOException {
+    File usersourcesini = tempFolder.resolve("usersources.ini").toFile();
+    usersourcesini.createNewFile();
+    String usersourcesFileName = usersourcesini.getAbsolutePath();
+
     String usersourcesContent =
         "realms = PAM\n"
             + "defaultRealm = PAM\n"
diff --git a/src/test/java/org/caosdb/server/resource/TestScriptingResource.java b/src/test/java/org/caosdb/server/resource/TestScriptingResource.java
index 566c8a09ee301f628bfe9232dde75ad5a66c0207..31d4a384c4a2a7e12b48c99073119cb7a38e3acc 100644
--- a/src/test/java/org/caosdb/server/resource/TestScriptingResource.java
+++ b/src/test/java/org/caosdb/server/resource/TestScriptingResource.java
@@ -23,7 +23,7 @@
 
 package org.caosdb.server.resource;
 
-import static org.junit.Assert.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertEquals;
 
 import java.io.IOException;
 import java.util.Date;
@@ -52,8 +52,8 @@ import org.caosdb.server.permissions.PermissionRule;
 import org.caosdb.server.scripting.ScriptingPermissions;
 import org.caosdb.server.scripting.ServerSideScriptingCaller;
 import org.jdom2.Element;
-import org.junit.BeforeClass;
-import org.junit.Test;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
 import org.restlet.Request;
 import org.restlet.Response;
 import org.restlet.data.Form;
@@ -151,7 +151,7 @@ public class TestScriptingResource {
     }
   }
 
-  @BeforeClass
+  @BeforeAll
   public static void setupShiro() throws IOException {
     CaosDBServer.initServerProperties();
     CaosDBServer.initShiro();
diff --git a/src/test/java/org/caosdb/server/resource/TestSharedFileResource.java b/src/test/java/org/caosdb/server/resource/TestSharedFileResource.java
index bff03a45e908419bbaef3a8988df7d9d382a0e8a..6b9fab19af6a899629e0338f7274f09f4baec7b4 100644
--- a/src/test/java/org/caosdb/server/resource/TestSharedFileResource.java
+++ b/src/test/java/org/caosdb/server/resource/TestSharedFileResource.java
@@ -22,15 +22,16 @@
 
 package org.caosdb.server.resource;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.fail;
 
 import java.io.File;
 import java.io.IOException;
 import java.nio.file.Files;
+import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.util.concurrent.ConcurrentMap;
 import net.jcip.annotations.NotThreadSafe;
@@ -42,18 +43,15 @@ import org.caosdb.server.FileSystem;
 import org.caosdb.server.ServerProperties;
 import org.caosdb.server.accessControl.AnonymousAuthenticationToken;
 import org.caosdb.server.accessControl.AnonymousRealm;
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.TemporaryFolder;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.io.TempDir;
 import org.restlet.Request;
 import org.restlet.Response;
 import org.restlet.data.Disposition;
 import org.restlet.data.MediaType;
 import org.restlet.data.Method;
 import org.restlet.data.Reference;
-import org.restlet.data.Status;
 import org.restlet.representation.FileRepresentation;
 import org.restlet.representation.Representation;
 import org.restlet.representation.StringRepresentation;
@@ -61,8 +59,6 @@ import org.restlet.representation.StringRepresentation;
 @NotThreadSafe
 public class TestSharedFileResource {
 
-  @Rule public TemporaryFolder tempFolder = new TemporaryFolder();
-
   static String illegalTopLevelString = "22334455-HGFEDCBA";
   static String illegalFolderString = "11001100-00110011";
   static String legalFolderString = "22334455-ABCDEFGH";
@@ -77,7 +73,7 @@ public class TestSharedFileResource {
   static File legalFolder;
   static File legalFile;
 
-  @BeforeClass
+  @BeforeAll
   public static void setup() throws Exception {
     CaosDBServer.initServerProperties();
     String tmpStr = FileSystem.getTmp();
@@ -96,15 +92,6 @@ public class TestSharedFileResource {
     legalFile.createNewFile();
   }
 
-  @AfterClass
-  public static void teardown() throws Exception {
-    if (false) {
-      assertTrue(legalFolder.delete());
-      assertTrue(illegalFolder.delete());
-      assertTrue(illegalTopLevelFile.delete());
-    }
-  }
-
   // Some tests for illegal requests.
   @Test
   public void testValidity() throws Exception {
@@ -118,9 +105,9 @@ public class TestSharedFileResource {
 
   // Trying to obtain files via `path` attribute.
   @Test
-  public void testFileUrl() throws Exception {
+  public void testFileUrl(@TempDir Path tmpDir) throws Exception {
 
-    provideUserSourcesFile();
+    provideUserSourcesFile(tmpDir);
     final Subject user = new DelegatingSubject(new DefaultSecurityManager(new AnonymousRealm()));
     CaosDBServer.setProperty(ServerProperties.KEY_AUTH_OPTIONAL, "true");
     user.login(AnonymousAuthenticationToken.getInstance());
@@ -167,11 +154,6 @@ public class TestSharedFileResource {
     req.setAttributes(attrs);
     resource.init(null, req, new Response(null));
     Representation repr = resource.handle();
-    Response resp = resource.getResponse();
-    // No unit testing framework yet.
-    if (false) {
-      assertEquals(Status.SUCCESS_OK, resp.getStatus());
-    }
     FileRepresentation frep;
     try {
       frep = (FileRepresentation) repr;
@@ -185,8 +167,10 @@ public class TestSharedFileResource {
   }
 
   /** Creates a dummy usersources.ini and injects it into the server properties. */
-  private void provideUserSourcesFile() throws IOException {
-    String usersourcesFileName = tempFolder.newFile("usersources.ini").getAbsolutePath();
+  private void provideUserSourcesFile(Path tempFolder) throws IOException {
+    File usersourcesini = tempFolder.resolve("usersources.ini").toFile();
+    usersourcesini.createNewFile();
+    String usersourcesFileName = usersourcesini.getAbsolutePath();
     String usersourcesContent =
         "realms = PAM\n"
             + "defaultRealm = PAM\n"
diff --git a/src/test/java/org/caosdb/server/scripting/TestServerSideScriptingCaller.java b/src/test/java/org/caosdb/server/scripting/TestServerSideScriptingCaller.java
index 45b8e7f4408ca7186fbc2589b176d3c5eba113ba..0d37928231f139b40b9c3c17d6753fac7368b233 100644
--- a/src/test/java/org/caosdb/server/scripting/TestServerSideScriptingCaller.java
+++ b/src/test/java/org/caosdb/server/scripting/TestServerSideScriptingCaller.java
@@ -22,21 +22,23 @@
  */
 package org.caosdb.server.scripting;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
 
 import java.io.File;
 import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
+import java.nio.file.Files;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashMap;
 import java.util.Map;
+import java.util.concurrent.TimeUnit;
 import org.apache.commons.io.FileUtils;
-import org.caosdb.CaosDBTestClass;
 import org.caosdb.server.CaosDBException;
 import org.caosdb.server.CaosDBServer;
 import org.caosdb.server.ServerProperties;
@@ -44,40 +46,34 @@ import org.caosdb.server.database.exceptions.TransactionException;
 import org.caosdb.server.entity.FileProperties;
 import org.caosdb.server.entity.Message;
 import org.caosdb.server.utils.ServerMessages;
-import org.hamcrest.BaseMatcher;
-import org.hamcrest.Description;
-import org.junit.After;
-import org.junit.AfterClass;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.ExpectedException;
-
-public class TestServerSideScriptingCaller extends CaosDBTestClass {
-
-  public static File testFolder =
-      TEST_DIR.toPath().resolve("serverSideScriptingCallerTestFolder").toFile();
-  public static File testFile = testFolder.toPath().resolve("TestFile").toFile();
-  public static File testExecutable = testFolder.toPath().resolve("TestScript").toFile();
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.Timeout;
+
+public class TestServerSideScriptingCaller {
+
+  public static File testFolder = null;
+  public static File testFile = null;
+  public static File testExecutable = null;
   final Map<String, String> emptyEnv = new HashMap<String, String>();
 
-  @BeforeClass
-  public static void initServerProperties() throws IOException {
-    CaosDBServer.initServerProperties();
-  }
-
-  @BeforeClass
+  @BeforeAll
   public static void setupTestFolder() throws IOException {
+    testFolder = Files.createTempDirectory(".TestDir_ServerSideScripting").toFile();
+    CaosDBServer.initServerProperties();
     CaosDBServer.getServerProperties()
         .setProperty(
             ServerProperties.KEY_SERVER_SIDE_SCRIPTING_BIN_DIRS, testFolder.getAbsolutePath());
 
+    testFile = testFolder.toPath().resolve("TestFile").toFile();
+    testExecutable = testFolder.toPath().resolve("TestScript").toFile();
     FileUtils.forceDeleteOnExit(testFolder);
     FileUtils.forceDeleteOnExit(testFile);
     FileUtils.forceDeleteOnExit(testExecutable);
 
-    assertFalse(testFolder.exists());
     assertFalse(testFile.exists());
     assertFalse(testExecutable.exists());
     testFolder.mkdirs();
@@ -88,7 +84,7 @@ public class TestServerSideScriptingCaller extends CaosDBTestClass {
     testExecutable.setExecutable(true);
   }
 
-  @AfterClass
+  @AfterAll
   public static void deleteTestFolder() throws IOException {
     FileUtils.forceDelete(testFile);
     FileUtils.forceDelete(testFolder);
@@ -123,14 +119,14 @@ public class TestServerSideScriptingCaller extends CaosDBTestClass {
 
   private File pwd;
 
-  @Before
+  @BeforeEach
   public void setupPWD() throws IOException {
     this.pwd = testFolder.toPath().resolve("testPWD").toFile();
     FileUtils.forceDeleteOnExit(this.pwd);
     assertFalse(this.pwd.exists());
   }
 
-  @After
+  @AfterEach
   public void deletePWD() throws IOException {
     if (this.pwd.exists()) {
       FileUtils.forceDelete(this.pwd);
@@ -138,20 +134,16 @@ public class TestServerSideScriptingCaller extends CaosDBTestClass {
     assertFalse(this.pwd.exists());
   }
 
-  @Rule public ExpectedException exception = ExpectedException.none();
-
   @Test
   public void testCreateWorkingDirFailure() throws Exception {
     final ServerSideScriptingCaller caller =
         new ServerSideScriptingCaller(
             null, -1, null, null, emptyEnv, new ScriptingUtils(), this.pwd);
 
-    this.exception.expect(Exception.class);
-    this.exception.expectMessage(
-        "The working directory must be non-existing when the caller is invoked.");
-
     this.pwd.mkdirs();
-    caller.createWorkingDir();
+    Exception exc = assertThrows(Exception.class, () -> caller.createWorkingDir());
+    assertEquals(
+        exc.getMessage(), "The working directory must be non-existing when the caller is invoked.");
   }
 
   @Test
@@ -179,10 +171,9 @@ public class TestServerSideScriptingCaller extends CaosDBTestClass {
         new ServerSideScriptingCaller(
             null, -1, null, null, emptyEnv, new ScriptingUtils(), this.pwd);
 
-    this.exception.expect(FileNotFoundException.class);
-    this.exception.expectMessage("FILE_UPLOAD_DIR");
-
-    caller.putFilesInWorkingDir(new ArrayList<>());
+    Exception exc =
+        assertThrows(Exception.class, () -> caller.putFilesInWorkingDir(new ArrayList<>()));
+    assertEquals(exc.getMessage(), "Could not create the FILE_UPLOAD_DIR.");
   }
 
   /**
@@ -201,10 +192,8 @@ public class TestServerSideScriptingCaller extends CaosDBTestClass {
     final ArrayList<FileProperties> files = new ArrayList<>();
     files.add(new FileProperties(null, null, null));
 
-    this.exception.expect(CaosDBException.class);
-    this.exception.expectMessage("The path must not be null or empty!");
-
-    caller.putFilesInWorkingDir(files);
+    Exception exc = assertThrows(Exception.class, () -> caller.putFilesInWorkingDir(files));
+    assertEquals(exc.getMessage(), "The path must not be null or empty!");
   }
 
   /**
@@ -226,10 +215,8 @@ public class TestServerSideScriptingCaller extends CaosDBTestClass {
     f.setPath("testfile");
     files.add(f);
 
-    this.exception.expect(NullPointerException.class);
-    this.exception.expectMessage("target was null.");
-
-    caller.putFilesInWorkingDir(files);
+    Exception exc = assertThrows(Exception.class, () -> caller.putFilesInWorkingDir(files));
+    assertEquals(exc.getMessage(), "target was null.");
   }
 
   /**
@@ -252,10 +239,8 @@ public class TestServerSideScriptingCaller extends CaosDBTestClass {
     f.setPath("bla");
     files.add(f);
 
-    this.exception.expect(TransactionException.class);
-    this.exception.expectMessage("target does not exist");
-
-    caller.putFilesInWorkingDir(files);
+    Exception exc = assertThrows(Exception.class, () -> caller.putFilesInWorkingDir(files));
+    assertEquals(exc.getMessage(), "target does not exist.");
   }
 
   /**
@@ -380,7 +365,8 @@ public class TestServerSideScriptingCaller extends CaosDBTestClass {
     assertTrue(p.wasTimeouted());
   }
 
-  @Test(timeout = 1000)
+  @Timeout(value = 1, unit = TimeUnit.SECONDS)
+  @Test
   public void testTimeout() throws Exception {
     final String[] cmd = {testExecutable.getAbsolutePath()};
     final ServerSideScriptingCaller caller =
@@ -391,8 +377,7 @@ public class TestServerSideScriptingCaller extends CaosDBTestClass {
 
     testSleep(10);
 
-    this.exception.expect(TimeoutException.class);
-    caller.callScript(cmd[0], cmd, null, emptyEnv);
+    assertThrows(TimeoutException.class, () -> caller.callScript(cmd[0], cmd, null, emptyEnv));
   }
 
   @Test
@@ -431,20 +416,9 @@ public class TestServerSideScriptingCaller extends CaosDBTestClass {
           @Override
           public void cleanup() {}
         };
-    this.exception.expect(
-        new BaseMatcher<Exception>() {
 
-          @Override
-          public boolean matches(final Object item) {
-            return item == ServerMessages.SERVER_SIDE_SCRIPT_SETUP_ERROR;
-          }
-
-          @Override
-          public void describeTo(final Description description) {
-            description.appendValue(ServerMessages.SERVER_SIDE_SCRIPT_SETUP_ERROR);
-          }
-        });
-    caller.invoke();
+    Message exc = assertThrows(Message.class, () -> caller.invoke());
+    assertEquals(exc, ServerMessages.SERVER_SIDE_SCRIPT_SETUP_ERROR);
   }
 
   @Test
@@ -470,25 +444,14 @@ public class TestServerSideScriptingCaller extends CaosDBTestClass {
           @Override
           public void cleanup() {}
         };
-    this.exception.expect(
-        new BaseMatcher<Exception>() {
-
-          @Override
-          public boolean matches(final Object item) {
-            return item == ServerMessages.SERVER_SIDE_SCRIPT_SETUP_ERROR;
-          }
-
-          @Override
-          public void describeTo(final Description description) {
-            description.appendValue(ServerMessages.SERVER_SIDE_SCRIPT_SETUP_ERROR);
-          }
-        });
-    caller.invoke();
+    Message exc = assertThrows(Message.class, () -> caller.invoke());
+    assertEquals(exc, ServerMessages.SERVER_SIDE_SCRIPT_SETUP_ERROR);
   }
 
   @Test
   public void testInvokeWithErrorInCallScript() throws Message {
     final String[] cmd = {testExecutable.getAbsolutePath()};
+    assertTrue(new File(cmd[0]).exists());
     final ServerSideScriptingCaller caller =
         new ServerSideScriptingCaller(
             cmd, -1, null, null, emptyEnv, new ScriptingUtils(), this.pwd) {
@@ -512,20 +475,9 @@ public class TestServerSideScriptingCaller extends CaosDBTestClass {
           @Override
           public void cleanup() {}
         };
-    this.exception.expect(
-        new BaseMatcher<Exception>() {
-
-          @Override
-          public boolean matches(final Object item) {
-            return item == ServerMessages.SERVER_SIDE_SCRIPT_ERROR;
-          }
 
-          @Override
-          public void describeTo(final Description description) {
-            description.appendValue(ServerMessages.SERVER_SIDE_SCRIPT_ERROR);
-          }
-        });
-    caller.invoke();
+    Message exc = assertThrows(Message.class, () -> caller.invoke());
+    assertEquals(exc, ServerMessages.SERVER_SIDE_SCRIPT_ERROR);
   }
 
   @Test
@@ -556,9 +508,9 @@ public class TestServerSideScriptingCaller extends CaosDBTestClass {
             throw new IOException();
           }
         };
-    this.exception.expect(RuntimeException.class);
-    this.exception.expectMessage("Cleanup failed.");
-    caller.invoke();
+
+    Exception exc = assertThrows(RuntimeException.class, () -> caller.invoke());
+    assertEquals(exc.getMessage(), "Cleanup failed.");
   }
 
   @Test
@@ -630,26 +582,13 @@ public class TestServerSideScriptingCaller extends CaosDBTestClass {
     final ServerSideScriptingCaller caller =
         new ServerSideScriptingCaller(
             cmd, -1, null, null, emptyEnv, new ScriptingUtils(), this.pwd);
-    this.exception.expect(
-        new BaseMatcher<Exception>() {
-
-          @Override
-          public boolean matches(final Object item) {
-            return item == ServerMessages.SERVER_SIDE_SCRIPT_ERROR;
-          }
 
-          @Override
-          public void describeTo(final Description description) {
-            description.appendValue(ServerMessages.SERVER_SIDE_SCRIPT_ERROR);
-          }
+    assertThrows(
+        Exception.class,
+        () -> {
+          caller.createTmpHomeDir();
+          caller.createWorkingDir();
         });
-    try {
-      caller.createTmpHomeDir();
-      caller.createWorkingDir();
-    } catch (final Exception e) {
-      e.printStackTrace();
-      throw ServerMessages.SERVER_SIDE_SCRIPT_ERROR;
-    }
     caller.cleanup();
   }
 
diff --git a/src/test/java/org/caosdb/server/transaction/RetrieveTest.java b/src/test/java/org/caosdb/server/transaction/RetrieveTest.java
index 08c41ba4a2346058d9d2da587dd7c26930ad2896..d4fab9e1203ce1f45e3d8c027a6107ca42ceea31 100644
--- a/src/test/java/org/caosdb/server/transaction/RetrieveTest.java
+++ b/src/test/java/org/caosdb/server/transaction/RetrieveTest.java
@@ -1,8 +1,8 @@
 package org.caosdb.server.transaction;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
 
 import java.io.IOException;
 import org.apache.shiro.SecurityUtils;
@@ -23,13 +23,13 @@ import org.caosdb.server.entity.xml.IdAndServerMessagesOnlyStrategy;
 import org.caosdb.server.permissions.EntityACLFactory;
 import org.caosdb.server.utils.EntityStatus;
 import org.caosdb.server.utils.ServerMessages;
-import org.junit.BeforeClass;
-import org.junit.Test;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
 
 public class RetrieveTest {
 
   // @review Florian Spreckelsen 2022-03-22
-  @BeforeClass
+  @BeforeAll
   public static void setup() throws IOException {
     CaosDBServer.initServerProperties();
     CaosDBServer.setProperty(ServerProperties.KEY_AUTH_OPTIONAL, "TRUE");
diff --git a/src/test/java/org/caosdb/server/transaction/UpdateTest.java b/src/test/java/org/caosdb/server/transaction/UpdateTest.java
index 9ae999bbf4be5ed4cfdf3e4ad03e2504cc311b33..860e06b2bf0d9ee41ac2f1ff7be421b6a696f9d8 100644
--- a/src/test/java/org/caosdb/server/transaction/UpdateTest.java
+++ b/src/test/java/org/caosdb/server/transaction/UpdateTest.java
@@ -23,8 +23,8 @@ package org.caosdb.server.transaction;
 
 import static org.caosdb.server.utils.EntityStatus.QUALIFIED;
 import static org.caosdb.server.utils.EntityStatus.VALID;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
 
 import java.io.IOException;
 import java.security.NoSuchAlgorithmException;
@@ -41,12 +41,12 @@ import org.caosdb.server.entity.wrapper.Property;
 import org.caosdb.server.permissions.EntityPermission;
 import org.caosdb.server.permissions.Permission;
 import org.caosdb.server.utils.EntityStatus;
-import org.junit.BeforeClass;
-import org.junit.Test;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
 
 public class UpdateTest {
 
-  @BeforeClass
+  @BeforeAll
   public static void setup() throws IOException {
     CaosDBServer.initServerProperties();
   }
diff --git a/src/test/java/org/caosdb/server/utils/FileUtilsTest.java b/src/test/java/org/caosdb/server/utils/FileUtilsTest.java
index 7e0664f3df401f916ed48c6830271334083a5ac4..e05a3c7f6f082f2432137737c5937e67ff75d4ef 100644
--- a/src/test/java/org/caosdb/server/utils/FileUtilsTest.java
+++ b/src/test/java/org/caosdb/server/utils/FileUtilsTest.java
@@ -22,15 +22,18 @@
  */
 package org.caosdb.server.utils;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.fail;
 
 import java.io.File;
 import java.io.IOException;
 import java.io.PrintStream;
 import java.io.PrintWriter;
+import java.nio.file.Files;
+import java.nio.file.Path;
 import java.security.NoSuchAlgorithmException;
 import java.util.Iterator;
 import java.util.regex.Pattern;
@@ -41,25 +44,32 @@ import org.caosdb.server.FileSystem;
 import org.caosdb.server.ServerProperties;
 import org.caosdb.server.database.BackendTransaction;
 import org.caosdb.server.database.access.Access;
+import org.caosdb.server.database.backend.implementation.UnixFileSystem.UnixFileSystemCheckHash;
+import org.caosdb.server.database.backend.implementation.UnixFileSystem.UnixFileSystemCheckSize;
+import org.caosdb.server.database.backend.implementation.UnixFileSystem.UnixFileSystemFileExists;
+import org.caosdb.server.database.backend.implementation.UnixFileSystem.UnixFileSystemFileWasModifiedAfter;
+import org.caosdb.server.database.backend.implementation.UnixFileSystem.UnixFileSystemGetFileIterator;
 import org.caosdb.server.database.backend.implementation.UnixFileSystem.UnixFileSystemGetFileIterator.FileNameIterator;
 import org.caosdb.server.database.backend.implementation.UnixFileSystem.UnixFileSystemHelper;
+import org.caosdb.server.database.backend.interfaces.FileCheckHash;
+import org.caosdb.server.database.backend.interfaces.FileCheckSize;
+import org.caosdb.server.database.backend.interfaces.FileExists;
+import org.caosdb.server.database.backend.interfaces.FileWasModifiedAfter;
+import org.caosdb.server.database.backend.interfaces.GetFileIteratorImpl;
 import org.caosdb.server.database.backend.transaction.FileConsistencyCheck;
 import org.caosdb.server.database.backend.transaction.GetFileIterator;
 import org.caosdb.server.database.exceptions.TransactionException;
 import org.caosdb.server.entity.Message;
 import org.eclipse.jetty.io.RuntimeIOException;
-import org.junit.After;
-import org.junit.AfterClass;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.ClassRule;
-import org.junit.Test;
-import org.junit.rules.TemporaryFolder;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
 
 @NotThreadSafe
 public class FileUtilsTest {
-  @ClassRule public static TemporaryFolder tempFolder = new TemporaryFolder();
+  public static Path tempDirectory;
   public static File testRoot;
   public static File someDir;
   public static File linkToSomeDir;
@@ -68,34 +78,47 @@ public class FileUtilsTest {
   public static File linkToSomeFile;
   public static File tmpFolderCaosDB;
 
-  @BeforeClass
+  private static File newFolder(String name) throws IOException {
+    Path ret = Files.createTempDirectory(tempDirectory, name);
+    return ret.toFile();
+  }
+
+  @BeforeAll
   public static void setup() throws Message, IOException, CaosDBException, InterruptedException {
     CaosDBServer.initServerProperties();
-    testRoot = tempFolder.newFolder("fileutils_testfolder");
-    File basePath = tempFolder.newFolder("caosdbRoot");
-    File dropOffBox = tempFolder.newFolder("dropOffBox");
+    BackendTransaction.setImpl(FileExists.class, UnixFileSystemFileExists.class);
+    BackendTransaction.setImpl(GetFileIteratorImpl.class, UnixFileSystemGetFileIterator.class);
+    BackendTransaction.setImpl(
+        FileWasModifiedAfter.class, UnixFileSystemFileWasModifiedAfter.class);
+    BackendTransaction.setImpl(FileCheckSize.class, UnixFileSystemCheckSize.class);
+    BackendTransaction.setImpl(FileCheckHash.class, UnixFileSystemCheckHash.class);
+
+    tempDirectory = Files.createTempDirectory(null);
+    testRoot = newFolder("fileutils_testfolder");
+    File basePath = newFolder("caosdbRoot");
+    File dropOffBox = newFolder("dropOffBox");
     someDir = testRoot.toPath().resolve("some_dir").toFile();
     linkToSomeDir = testRoot.toPath().resolve("link_to_some_dir").toFile();
     someFile = testRoot.toPath().resolve("some_file").toFile();
     someDir_someFile = someDir.toPath().resolve("someFile").toFile();
     linkToSomeFile = testRoot.toPath().resolve("link_to_some_file").toFile();
 
-    tmpFolderCaosDB = tempFolder.newFolder();
+    tmpFolderCaosDB = newFolder("tmpFolderCaosDB");
     CaosDBServer.setProperty(ServerProperties.KEY_FILE_SYSTEM_ROOT, basePath.toString());
     CaosDBServer.setProperty(ServerProperties.KEY_DROP_OFF_BOX, dropOffBox.toString());
     CaosDBServer.setProperty(ServerProperties.KEY_TMP_FILES, tmpFolderCaosDB.toString());
     FileSystem.init();
 
     basePath = new File(FileSystem.getBasepath());
-    Assert.assertTrue(basePath.canWrite());
-    Assert.assertTrue(basePath.canRead());
-    Assert.assertTrue(basePath.canExecute());
-    Assert.assertTrue(new File(FileSystem.getTmp()).canWrite());
-    Assert.assertTrue(new File(FileSystem.getTmp()).canRead());
-    Assert.assertTrue(new File(FileSystem.getTmp()).canExecute());
-    Assert.assertTrue(new File(FileSystem.getDropOffBox()).canWrite());
-    Assert.assertTrue(new File(FileSystem.getDropOffBox()).canRead());
-    Assert.assertTrue(new File(FileSystem.getDropOffBox()).canExecute());
+    assertTrue(basePath.canWrite());
+    assertTrue(basePath.canRead());
+    assertTrue(basePath.canExecute());
+    assertTrue(new File(FileSystem.getTmp()).canWrite());
+    assertTrue(new File(FileSystem.getTmp()).canRead());
+    assertTrue(new File(FileSystem.getTmp()).canExecute());
+    assertTrue(new File(FileSystem.getDropOffBox()).canWrite());
+    assertTrue(new File(FileSystem.getDropOffBox()).canRead());
+    assertTrue(new File(FileSystem.getDropOffBox()).canExecute());
 
     deleteTmp();
     // FileUtils.createFolders(testRoot);
@@ -106,21 +129,21 @@ public class FileUtilsTest {
     FileUtils.createSymlink(linkToSomeFile, someDir_someFile);
   }
 
-  @AfterClass
+  @AfterAll
   public static void teardown() throws IOException, CaosDBException, InterruptedException {
-    System.err.println("teardown");
     FileUtils.delete(testRoot, true);
     deleteTmp();
     assertFalse(testRoot.exists());
-    // assertEquals(0, new File(FileSystem.getTmp()).listFiles().length);
+    if (tempDirectory.toFile().exists()) {
+      tempDirectory.toFile().delete();
+    }
   }
 
   /**
    * @throws InterruptedException
    * @throws CaosDBException
-   * @fixme Currently still fails due to https://github.com/junit-team/junit4/issues/1223
    */
-  @Before
+  @BeforeEach
   public void testTmpEmpty() throws IOException, CaosDBException, InterruptedException {
     if (new File(FileSystem.getTmp()).exists()) {
       if (0 != new File(FileSystem.getTmp()).list().length) {
@@ -130,7 +153,6 @@ public class FileUtilsTest {
           System.err.println(f);
         }
         teardown();
-        // System.exit(1);
         fail("TMP not empty, aborting test");
       }
       assertEquals(0, new File(FileSystem.getTmp()).list().length);
@@ -146,21 +168,24 @@ public class FileUtilsTest {
       }
   }
 
-  @After
+  @AfterEach
   public void callDeleteTmp() throws IOException, CaosDBException, InterruptedException {
     deleteTmp();
   }
 
-  @Test(expected = NullPointerException.class)
+  @Test
   public void testGetMimeTypeNull() {
-    FileUtils.getMimeType(null);
+
+    assertThrows(NullPointerException.class, () -> FileUtils.getMimeType(null));
   }
 
-  @Test(expected = RuntimeIOException.class)
+  @Test
   public void testGetMimeTypeNonExisting() {
+
     final File f = new File("nonexisting");
     assertFalse(f.exists());
-    FileUtils.getMimeType(f);
+
+    assertThrows(RuntimeIOException.class, () -> FileUtils.getMimeType(f));
   }
 
   @Test
@@ -184,19 +209,21 @@ public class FileUtilsTest {
     }
   }
 
-  @Test(expected = NullPointerException.class)
+  @Test
   public void testIsSubDirNullChild() {
-    FileUtils.isSubDirSymlinkSave(null, someDir);
+
+    assertThrows(NullPointerException.class, () -> FileUtils.isSubDirSymlinkSave(null, someDir));
   }
 
-  @Test(expected = NullPointerException.class)
+  @Test
   public void testIsSubDirNullPar() {
-    FileUtils.isSubDirSymlinkSave(someFile, null);
+
+    assertThrows(NullPointerException.class, () -> FileUtils.isSubDirSymlinkSave(someFile, null));
   }
 
-  @Test(expected = NullPointerException.class)
+  @Test
   public void testIsSubDirNull() {
-    FileUtils.isSubDirSymlinkSave(null, null);
+    assertThrows(NullPointerException.class, () -> FileUtils.isSubDirSymlinkSave(null, null));
   }
 
   @Test
@@ -273,37 +300,37 @@ public class FileUtilsTest {
   @Test
   public void testCreateFolders() throws Message {
     final File f = new File(testRoot.getAbsoluteFile() + "/testfolder/testsubfolder/testfile");
-    Assert.assertFalse(f.getAbsoluteFile().getParentFile().exists());
+    assertFalse(f.getAbsoluteFile().getParentFile().exists());
     final Undoable u = FileUtils.createFolders(f.getAbsoluteFile().getParentFile());
-    Assert.assertTrue(f.getAbsoluteFile().getParentFile().exists());
+    assertTrue(f.getAbsoluteFile().getParentFile().exists());
     u.undo();
-    Assert.assertFalse(f.getAbsoluteFile().getParentFile().exists());
+    assertFalse(f.getAbsoluteFile().getParentFile().exists());
   }
 
   @Test
   public void testRenameUndoable1() throws IOException, Message {
     final String newFileTmpName = FileSystem.getTmp() + "renameTestFile" + Utils.getUID();
     final File newFile = new File(newFileTmpName);
-    Assert.assertTrue(newFile.createNewFile());
+    assertTrue(newFile.createNewFile());
     newFile.deleteOnExit();
     final String targetName = FileSystem.getPath("renameTestFile.dat");
     final File target = new File(targetName);
-    Assert.assertFalse(target.exists());
+    assertFalse(target.exists());
     target.deleteOnExit();
 
     final Undoable u = FileUtils.rename(newFile, target);
 
     // file is moved to file system
-    Assert.assertFalse(new File(newFileTmpName).exists());
-    Assert.assertTrue(new File(targetName).exists());
-    Assert.assertEquals(target.getAbsolutePath(), targetName);
-    Assert.assertFalse(newFile.exists());
+    assertFalse(new File(newFileTmpName).exists());
+    assertTrue(new File(targetName).exists());
+    assertEquals(target.getAbsolutePath(), targetName);
+    assertFalse(newFile.exists());
 
     u.undo();
 
     // file is moved back to tmp dir
-    Assert.assertTrue(new File(newFileTmpName).exists());
-    Assert.assertFalse(new File(targetName).exists());
+    assertTrue(new File(newFileTmpName).exists());
+    assertFalse(new File(targetName).exists());
 
     newFile.delete();
     target.delete();
@@ -313,25 +340,25 @@ public class FileUtilsTest {
   public void testRenameUndoable2() throws IOException, Message, NoSuchAlgorithmException {
     final String newFileTmpName = FileSystem.getTmp() + "renameTestFile" + Utils.getUID();
     final File newFile = new File(newFileTmpName);
-    Assert.assertFalse(newFile.exists());
+    assertFalse(newFile.exists());
 
     final PrintWriter outNew = new PrintWriter(newFileTmpName);
     outNew.println("newFile");
     outNew.close();
 
-    Assert.assertTrue(newFile.exists());
+    assertTrue(newFile.exists());
     newFile.deleteOnExit();
 
     final String newHash = FileUtils.getChecksum(newFile);
 
     final String targetName = FileSystem.getPath("renameTestFile.dat");
     final File target = new File(targetName);
-    Assert.assertFalse(target.exists());
+    assertFalse(target.exists());
     final PrintWriter outOld = new PrintWriter(targetName);
     outOld.println("oldFile");
     outOld.close();
 
-    Assert.assertTrue(target.exists());
+    assertTrue(target.exists());
     target.deleteOnExit();
 
     final String oldHash = FileUtils.getChecksum(target);
@@ -339,19 +366,19 @@ public class FileUtilsTest {
     final Undoable u = FileUtils.rename(newFile, target);
 
     // file is moved to file system, old file is moved to tmp
-    Assert.assertFalse(new File(newFileTmpName).exists());
-    Assert.assertTrue(new File(targetName).exists());
-    Assert.assertEquals(target.getAbsolutePath(), targetName);
-    Assert.assertFalse(newFile.exists());
+    assertFalse(new File(newFileTmpName).exists());
+    assertTrue(new File(targetName).exists());
+    assertEquals(target.getAbsolutePath(), targetName);
+    assertFalse(newFile.exists());
 
     u.undo();
 
     // file is moved back to tmp dir, old file is moved back to filesystem.
-    Assert.assertTrue(new File(newFileTmpName).exists());
-    Assert.assertTrue(new File(targetName).exists());
+    assertTrue(new File(newFileTmpName).exists());
+    assertTrue(new File(targetName).exists());
 
-    Assert.assertEquals(newHash, FileUtils.getChecksum(new File(newFileTmpName)));
-    Assert.assertEquals(oldHash, FileUtils.getChecksum(new File(targetName)));
+    assertEquals(newHash, FileUtils.getChecksum(new File(newFileTmpName)));
+    assertEquals(oldHash, FileUtils.getChecksum(new File(targetName)));
 
     target.delete();
     newFile.delete();
@@ -364,45 +391,45 @@ public class FileUtilsTest {
 
     final String newFileTmpName = FileSystem.getTmp() + "renameTestFile" + Utils.getUID();
     final File newFile = new File(newFileTmpName);
-    Assert.assertFalse(newFile.exists());
+    assertFalse(newFile.exists());
 
     final PrintWriter outNew = new PrintWriter(newFileTmpName);
     outNew.println("newFile");
     outNew.close();
 
-    Assert.assertTrue(newFile.exists());
+    assertTrue(newFile.exists());
     newFile.deleteOnExit();
 
     final String newHash = FileUtils.getChecksum(newFile);
 
     final String targetName = FileSystem.getPath("renameTestFile.dat");
     final File target = new File(targetName);
-    Assert.assertFalse(target.exists());
+    assertFalse(target.exists());
     final PrintWriter outOld = new PrintWriter(targetName);
     outOld.println("oldFile");
     outOld.close();
 
-    Assert.assertTrue(target.exists());
+    assertTrue(target.exists());
     target.deleteOnExit();
 
     final Undoable u = FileUtils.rename(newFile, target);
 
     // file is moved to file system, old file is moved to tmp
-    Assert.assertFalse(new File(newFileTmpName).exists());
-    Assert.assertTrue(new File(targetName).exists());
-    Assert.assertEquals(target.getAbsolutePath(), targetName);
-    Assert.assertFalse(newFile.exists());
+    assertFalse(new File(newFileTmpName).exists());
+    assertTrue(new File(targetName).exists());
+    assertEquals(target.getAbsolutePath(), targetName);
+    assertFalse(newFile.exists());
 
     u.cleanUp();
 
     // tmp file has been deleted and new file exists in the file system.
-    Assert.assertFalse(new File(newFileTmpName).exists());
-    Assert.assertTrue(new File(targetName).exists());
+    assertFalse(new File(newFileTmpName).exists());
+    assertTrue(new File(targetName).exists());
 
     // tmp folder is empty again.
-    Assert.assertEquals(0, new File(FileSystem.getTmp()).listFiles().length);
+    assertEquals(0, new File(FileSystem.getTmp()).listFiles().length);
 
-    Assert.assertEquals(newHash, FileUtils.getChecksum(new File(targetName)));
+    assertEquals(newHash, FileUtils.getChecksum(new File(targetName)));
 
     newFile.delete();
     target.delete();
@@ -413,18 +440,18 @@ public class FileUtilsTest {
 
     final String targetName = FileSystem.getPath("renameTestFile.dat");
     final File target = new File(targetName);
-    Assert.assertFalse(target.exists());
+    assertFalse(target.exists());
     final PrintWriter outOld = new PrintWriter(targetName);
     outOld.println("file");
     outOld.close();
 
-    Assert.assertTrue(target.exists());
+    assertTrue(target.exists());
     target.deleteOnExit();
 
     final String hash = FileUtils.getChecksum(target);
 
     final File newFile = new File(targetName);
-    Assert.assertEquals(newFile.getAbsolutePath(), target.getAbsolutePath());
+    assertEquals(newFile.getAbsolutePath(), target.getAbsolutePath());
 
     // rename file to itself
     final Undoable u = FileUtils.rename(newFile, target);
@@ -690,7 +717,7 @@ public class FileUtilsTest {
    * <li>Creates a random directory
    */
   @Test
-  public void testAssertDir() throws IOException {
+  public void testir() throws IOException {
     String existingDirStr = "existingDir";
     String existingFileStr = "existingFile";
     String newDirStr = "newDir/";
diff --git a/src/test/java/org/caosdb/server/utils/UtilsTest.java b/src/test/java/org/caosdb/server/utils/UtilsTest.java
index 3b92a11d69b465c33ddc9629d89c6d91e6f456e0..562d592756b8cf075dd421913dabb193d734af12 100644
--- a/src/test/java/org/caosdb/server/utils/UtilsTest.java
+++ b/src/test/java/org/caosdb/server/utils/UtilsTest.java
@@ -22,9 +22,9 @@
  */
 package org.caosdb.server.utils;
 
-import static org.junit.Assert.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertEquals;
 
-import org.junit.Test;
+import org.junit.jupiter.api.Test;
 
 public class UtilsTest {
 
diff --git a/src/test/java/org/caosdb/server/utils/WebinterfaceUtilsTest.java b/src/test/java/org/caosdb/server/utils/WebinterfaceUtilsTest.java
index 9231dd77a6724b5a8c5f7f4f244bd92c6f4a5e91..c607afd02c7651f0631283be77a3745d44121a3b 100644
--- a/src/test/java/org/caosdb/server/utils/WebinterfaceUtilsTest.java
+++ b/src/test/java/org/caosdb/server/utils/WebinterfaceUtilsTest.java
@@ -1,23 +1,19 @@
 package org.caosdb.server.utils;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
 
 import java.io.IOException;
 import org.caosdb.server.CaosDBServer;
 import org.caosdb.server.ServerProperties;
-import org.junit.BeforeClass;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.ExpectedException;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
 import org.restlet.data.Reference;
 
 public class WebinterfaceUtilsTest {
 
-  @Rule public ExpectedException exceptionRule = ExpectedException.none();
-
-  @BeforeClass
+  @BeforeAll
   public static void setup() throws IOException {
     CaosDBServer.initServerProperties();
   }
diff --git a/src/test/java/org/caosdb/server/utils/mail/TestMail.java b/src/test/java/org/caosdb/server/utils/mail/TestMail.java
index 5d7ba41089ee71d6ca4eff529bf6ce1ca0828b92..05cf5bf5698831ffbb68fc3a76836c4587d15f14 100644
--- a/src/test/java/org/caosdb/server/utils/mail/TestMail.java
+++ b/src/test/java/org/caosdb/server/utils/mail/TestMail.java
@@ -22,20 +22,33 @@
  */
 package org.caosdb.server.utils.mail;
 
+import java.io.File;
 import java.io.IOException;
-import org.caosdb.CaosDBTestClass;
+import java.nio.file.Files;
+import org.apache.commons.io.FileUtils;
 import org.caosdb.server.CaosDBServer;
 import org.caosdb.server.ServerProperties;
-import org.junit.BeforeClass;
-import org.junit.Test;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
 
-public class TestMail extends CaosDBTestClass {
-  @BeforeClass
+public class TestMail {
+
+  public static File testDir = null;
+
+  @BeforeAll
   public static void setupUp() throws IOException {
+    testDir = Files.createTempDirectory(".TestDir_Mail").toFile();
+
     CaosDBServer.initServerProperties();
     // output mails to the test dir
     CaosDBServer.setProperty(
-        ServerProperties.KEY_MAIL_TO_FILE_HANDLER_LOC, TEST_DIR.getAbsolutePath());
+        ServerProperties.KEY_MAIL_TO_FILE_HANDLER_LOC, testDir.getAbsolutePath());
+  }
+
+  @AfterAll
+  public static void tearDown() throws IOException {
+    FileUtils.deleteDirectory(testDir);
   }
 
   @Test