Merge branch 'stable-3.9'

* stable-3.9:
  Explain on the about page when the code-owners plugin should/shouldn't be used

Change-Id: Idc42bb5c0ee0d445fab631f02e237771eed69f87
Reviewed-on: https://gerrit-review.googlesource.com/c/plugins/code-owners/+/409499
Tested-by: Zuul <zuul-63@gerritcodereview-ci.iam.gserviceaccount.com>
Reviewed-by: Nitzan Gur-Furman <nitzan@google.com>
diff --git a/java/com/google/gerrit/plugins/codeowners/acceptance/testsuite/TestCodeOwnerConfigCreation.java b/java/com/google/gerrit/plugins/codeowners/acceptance/testsuite/TestCodeOwnerConfigCreation.java
index 3dd651e..e47e1cc 100644
--- a/java/com/google/gerrit/plugins/codeowners/acceptance/testsuite/TestCodeOwnerConfigCreation.java
+++ b/java/com/google/gerrit/plugins/codeowners/acceptance/testsuite/TestCodeOwnerConfigCreation.java
@@ -27,7 +27,6 @@
 import com.google.gerrit.plugins.codeowners.backend.CodeOwnerReference;
 import com.google.gerrit.plugins.codeowners.backend.CodeOwnerSet;
 import java.nio.file.Path;
-import java.nio.file.Paths;
 import java.util.Optional;
 
 /**
@@ -142,7 +141,7 @@
                     new IllegalStateException(
                         "project not specified, specifying a project is required for code owner config creation"));
     String branchName = branch().orElse("master");
-    Path folderPath = folderPath().orElse(Paths.get("/"));
+    Path folderPath = folderPath().orElse(Path.of("/"));
     return CodeOwnerConfig.Key.create(
         BranchNameKey.create(projectName, branchName), folderPath, fileName().orElse(null));
   }
@@ -215,7 +214,7 @@
      * @return the Builder instance for chaining calls
      */
     public Builder folderPath(String folderPath) {
-      return folderPath(Paths.get(folderPath));
+      return folderPath(Path.of(folderPath));
     }
 
     /**
diff --git a/java/com/google/gerrit/plugins/codeowners/api/CodeOwnerConfigs.java b/java/com/google/gerrit/plugins/codeowners/api/CodeOwnerConfigs.java
index 8754809..3b94482 100644
--- a/java/com/google/gerrit/plugins/codeowners/api/CodeOwnerConfigs.java
+++ b/java/com/google/gerrit/plugins/codeowners/api/CodeOwnerConfigs.java
@@ -17,7 +17,6 @@
 import com.google.gerrit.extensions.restapi.NotImplementedException;
 import com.google.gerrit.extensions.restapi.RestApiException;
 import java.nio.file.Path;
-import java.nio.file.Paths;
 import java.util.Optional;
 
 /**
@@ -41,7 +40,7 @@
    * @return the code owner config if it exists
    */
   default Optional<CodeOwnerConfigInfo> get(String path) throws RestApiException {
-    return get(Paths.get(path));
+    return get(Path.of(path));
   }
 
   /**
diff --git a/java/com/google/gerrit/plugins/codeowners/api/CodeOwners.java b/java/com/google/gerrit/plugins/codeowners/api/CodeOwners.java
index 390e34c..1e3e3ed 100644
--- a/java/com/google/gerrit/plugins/codeowners/api/CodeOwners.java
+++ b/java/com/google/gerrit/plugins/codeowners/api/CodeOwners.java
@@ -22,7 +22,6 @@
 import com.google.gerrit.extensions.restapi.NotImplementedException;
 import com.google.gerrit.extensions.restapi.RestApiException;
 import java.nio.file.Path;
-import java.nio.file.Paths;
 import java.util.Arrays;
 import java.util.EnumSet;
 import java.util.Optional;
@@ -69,7 +68,7 @@
      * @return the code owners for the given path
      */
     public CodeOwnersInfo get(String path) throws RestApiException {
-      return get(Paths.get(path));
+      return get(Path.of(path));
     }
 
     /**
diff --git a/java/com/google/gerrit/plugins/codeowners/backend/ChangedFiles.java b/java/com/google/gerrit/plugins/codeowners/backend/ChangedFiles.java
index 1d98268..bdcf002 100644
--- a/java/com/google/gerrit/plugins/codeowners/backend/ChangedFiles.java
+++ b/java/com/google/gerrit/plugins/codeowners/backend/ChangedFiles.java
@@ -31,8 +31,10 @@
 import com.google.gerrit.server.git.GitRepositoryManager;
 import com.google.gerrit.server.patch.DiffNotAvailableException;
 import com.google.gerrit.server.patch.DiffOperations;
+import com.google.gerrit.server.patch.DiffOperationsForCommitValidation;
 import com.google.gerrit.server.patch.DiffOptions;
 import com.google.gerrit.server.patch.filediff.FileDiffOutput;
+import com.google.gerrit.server.patch.gitdiff.ModifiedFile;
 import com.google.inject.Inject;
 import com.google.inject.Singleton;
 import java.io.IOException;
@@ -112,7 +114,9 @@
                 project, revision, 1, DiffOptions.DEFAULTS);
       }
 
-      return toChangedFiles(filterOutMagicFilesAndSort(fileDiffOutputs)).collect(toImmutableList());
+      return fileDiffOutputToChangedFiles(
+              filterOutMagicFilesFromFileDiffOutputAndSort(fileDiffOutputs))
+          .collect(toImmutableList());
     }
   }
 
@@ -157,6 +161,60 @@
         revisionResource.getProject(), revisionResource.getPatchSet().commitId());
   }
 
+  /**
+   * Gets the changed files from {@link DiffOperationsForCommitValidation} which needs to be used to
+   * retrieve modified files during commit validation.
+   *
+   * <p>Rename detection is enabled.
+   *
+   * @param diffOperationsForCommitValidation the {@link DiffOperationsForCommitValidation} instance
+   *     (e.g. from {@link com.google.gerrit.server.events.CommitReceivedEvent#diffOperations}) to
+   *     be used to retrieve the modified files
+   * @param project the project
+   * @param revision the revision for which the changed files should be retrieved
+   * @param mergeCommitStrategy the merge commit strategy that should be used to compute the changed
+   *     files for merge commits
+   * @return the files that have been changed in the given revision, sorted alphabetically by path
+   */
+  public ImmutableList<ChangedFile> getDuringCommitValidation(
+      DiffOperationsForCommitValidation diffOperationsForCommitValidation,
+      Project.NameKey project,
+      ObjectId revision,
+      MergeCommitStrategy mergeCommitStrategy)
+      throws IOException, DiffNotAvailableException {
+    requireNonNull(project, "project");
+    requireNonNull(revision, "revision");
+    requireNonNull(mergeCommitStrategy, "mergeCommitStrategy");
+
+    try (Timer0.Context ctx = codeOwnerMetrics.getChangedFiles.start()) {
+      Map<String, ModifiedFile> modifiedFiles;
+      if (mergeCommitStrategy.equals(MergeCommitStrategy.FILES_WITH_CONFLICT_RESOLUTION)
+          || isInitialCommit(project, revision)) {
+        // Use parentNum=0 to do the comparison against the default base.
+        // For non-merge commits the default base is the only parent (aka parent 1).
+        // Initial commits are supported when using parentNum=0.
+        // For merge commits the default base is the auto-merge commit which should be used as base
+        // if the merge commit strategy is FILES_WITH_CONFLICT_RESOLUTION.
+        modifiedFiles =
+            diffOperationsForCommitValidation.loadModifiedFilesAgainstParentIfNecessary(
+                project, revision, /* parentNum=*/ 0, /* enableRenameDetection= */ true);
+      } else {
+        checkState(mergeCommitStrategy.equals(MergeCommitStrategy.ALL_CHANGED_FILES));
+        // Always use parent 1 to do the comparison.
+        // Non-merge commits should always be compared against the first parent (initial commits are
+        // handled above).
+        // For merge commits also the first parent should be used if the merge commit strategy is
+        // ALL_CHANGED_FILES.
+        modifiedFiles =
+            diffOperationsForCommitValidation.loadModifiedFilesAgainstParentIfNecessary(
+                project, revision, 1, /* enableRenameDetection= */ true);
+      }
+
+      return modifiedFilesToChangedFiles(filterOutMagicFilesFromModifiedFilesAndSort(modifiedFiles))
+          .collect(toImmutableList());
+    }
+  }
+
   private boolean isInitialCommit(Project.NameKey project, ObjectId objectId) throws IOException {
     try (Repository repo = repoManager.openRepository(project);
         RevWalk revWalk = new RevWalk(repo)) {
@@ -164,15 +222,27 @@
     }
   }
 
-  private Stream<Map.Entry<String, FileDiffOutput>> filterOutMagicFilesAndSort(
+  private Stream<Map.Entry<String, FileDiffOutput>> filterOutMagicFilesFromFileDiffOutputAndSort(
       Map<String, FileDiffOutput> fileDiffOutputs) {
     return fileDiffOutputs.entrySet().stream()
         .filter(e -> !Patch.isMagic(e.getKey()))
         .sorted(comparing(Map.Entry::getKey));
   }
 
-  private Stream<ChangedFile> toChangedFiles(
+  private Stream<ChangedFile> fileDiffOutputToChangedFiles(
       Stream<Map.Entry<String, FileDiffOutput>> fileDiffOutputs) {
     return fileDiffOutputs.map(Map.Entry::getValue).map(ChangedFile::create);
   }
+
+  private Stream<Map.Entry<String, ModifiedFile>> filterOutMagicFilesFromModifiedFilesAndSort(
+      Map<String, ModifiedFile> modifiedFiles) {
+    return modifiedFiles.entrySet().stream()
+        .filter(e -> !Patch.isMagic(e.getKey()))
+        .sorted(comparing(Map.Entry::getKey));
+  }
+
+  private Stream<ChangedFile> modifiedFilesToChangedFiles(
+      Stream<Map.Entry<String, ModifiedFile>> modifiedFiles) {
+    return modifiedFiles.map(Map.Entry::getValue).map(ChangedFile::create);
+  }
 }
diff --git a/java/com/google/gerrit/plugins/codeowners/backend/CodeOwnerConfig.java b/java/com/google/gerrit/plugins/codeowners/backend/CodeOwnerConfig.java
index fc78ab8..b72ab39 100644
--- a/java/com/google/gerrit/plugins/codeowners/backend/CodeOwnerConfig.java
+++ b/java/com/google/gerrit/plugins/codeowners/backend/CodeOwnerConfig.java
@@ -24,7 +24,6 @@
 import com.google.gerrit.entities.BranchNameKey;
 import com.google.gerrit.entities.Project;
 import java.nio.file.Path;
-import java.nio.file.Paths;
 import java.util.Optional;
 import org.eclipse.jgit.lib.ObjectId;
 
@@ -328,7 +327,7 @@
      * @return the code owner config key
      */
     public static Key create(Project.NameKey project, String branch, String folderPath) {
-      return create(BranchNameKey.create(project, branch), Paths.get(folderPath));
+      return create(BranchNameKey.create(project, branch), Path.of(folderPath));
     }
 
     /**
@@ -343,7 +342,7 @@
      */
     public static Key create(
         Project.NameKey project, String branch, String folderPath, @Nullable String fileName) {
-      return create(BranchNameKey.create(project, branch), Paths.get(folderPath), fileName);
+      return create(BranchNameKey.create(project, branch), Path.of(folderPath), fileName);
     }
 
     /**
diff --git a/java/com/google/gerrit/plugins/codeowners/backend/CodeOwnerConfigReference.java b/java/com/google/gerrit/plugins/codeowners/backend/CodeOwnerConfigReference.java
index dff2506..c9892e4 100644
--- a/java/com/google/gerrit/plugins/codeowners/backend/CodeOwnerConfigReference.java
+++ b/java/com/google/gerrit/plugins/codeowners/backend/CodeOwnerConfigReference.java
@@ -22,7 +22,6 @@
 import com.google.gerrit.entities.Project;
 import com.google.gerrit.entities.RefNames;
 import java.nio.file.Path;
-import java.nio.file.Paths;
 import java.util.Optional;
 
 /**
@@ -67,7 +66,7 @@
    * <p>May be absolute or relative to the path of the importing code owner config.
    */
   public Path path() {
-    return firstNonNull(filePath().getParent(), Paths.get(""));
+    return firstNonNull(filePath().getParent(), Path.of(""));
   }
 
   /** The name of the code owner config file. */
@@ -118,7 +117,7 @@
    */
   public static Builder builder(CodeOwnerConfigImportMode importMode, String filePath) {
     requireNonNull(filePath, "filePath");
-    return builder(importMode, Paths.get(filePath));
+    return builder(importMode, Path.of(filePath));
   }
 
   /**
diff --git a/java/com/google/gerrit/plugins/codeowners/backend/CodeOwnerConfigTreeWalk.java b/java/com/google/gerrit/plugins/codeowners/backend/CodeOwnerConfigTreeWalk.java
index 0836a53..674c5f3 100644
--- a/java/com/google/gerrit/plugins/codeowners/backend/CodeOwnerConfigTreeWalk.java
+++ b/java/com/google/gerrit/plugins/codeowners/backend/CodeOwnerConfigTreeWalk.java
@@ -25,7 +25,6 @@
 import java.io.IOException;
 import java.nio.file.FileSystems;
 import java.nio.file.Path;
-import java.nio.file.Paths;
 import org.eclipse.jgit.lib.Constants;
 import org.eclipse.jgit.lib.ObjectLoader;
 import org.eclipse.jgit.lib.Ref;
@@ -93,8 +92,8 @@
     Path folderPath =
         filePath.getParent() != null
             ? JgitPath.of(filePath.getParent()).getAsAbsolutePath()
-            : Paths.get("/");
-    String fileName = Paths.get(getPathString()).getFileName().toString();
+            : Path.of("/");
+    String fileName = Path.of(getPathString()).getFileName().toString();
     return CodeOwnerConfig.Key.create(branchNameKey, folderPath, fileName);
   }
 
@@ -162,7 +161,7 @@
               "%s filtered out because it doesn't match the path glob", walker.getPathString());
           return false;
         }
-        String fileName = Paths.get(walker.getPathString()).getFileName().toString();
+        String fileName = Path.of(walker.getPathString()).getFileName().toString();
         return codeOwnerBackend.isCodeOwnerConfigFile(project, fileName);
       }
 
diff --git a/java/com/google/gerrit/plugins/codeowners/backend/config/CodeOwnersPluginConfigValidator.java b/java/com/google/gerrit/plugins/codeowners/backend/config/CodeOwnersPluginConfigValidator.java
index df8003f..67808d9 100644
--- a/java/com/google/gerrit/plugins/codeowners/backend/config/CodeOwnersPluginConfigValidator.java
+++ b/java/com/google/gerrit/plugins/codeowners/backend/config/CodeOwnersPluginConfigValidator.java
@@ -184,7 +184,8 @@
   private boolean isFileChanged(CommitReceivedEvent receiveEvent, String fileName)
       throws IOException, DiffNotAvailableException {
     return changedFiles
-        .getFromDiffCache(
+        .getDuringCommitValidation(
+            receiveEvent.diffOperations,
             receiveEvent.project.getNameKey(),
             receiveEvent.commit,
             MergeCommitStrategy.ALL_CHANGED_FILES)
diff --git a/java/com/google/gerrit/plugins/codeowners/common/ChangedFile.java b/java/com/google/gerrit/plugins/codeowners/common/ChangedFile.java
index 267e3c7..e8d42b0 100644
--- a/java/com/google/gerrit/plugins/codeowners/common/ChangedFile.java
+++ b/java/com/google/gerrit/plugins/codeowners/common/ChangedFile.java
@@ -25,6 +25,7 @@
 import com.google.gerrit.plugins.codeowners.util.JgitPath;
 import com.google.gerrit.server.patch.PatchListEntry;
 import com.google.gerrit.server.patch.filediff.FileDiffOutput;
+import com.google.gerrit.server.patch.gitdiff.ModifiedFile;
 import java.nio.file.Path;
 import java.util.Optional;
 import org.eclipse.jgit.diff.DiffEntry;
@@ -177,6 +178,20 @@
         CHANGE_TYPE.get(fileDiffOutput.changeType()));
   }
 
+  /**
+   * Creates a {@link ChangedFile} instance from a {@link ModifiedFile}.
+   *
+   * @param modifiedFile the modified file
+   */
+  public static ChangedFile create(ModifiedFile modifiedFile) {
+    requireNonNull(modifiedFile, "modifiedFile");
+
+    return new AutoValue_ChangedFile(
+        convertPathFromFileDiffOutput(modifiedFile.newPath()),
+        convertPathFromFileDiffOutput(modifiedFile.oldPath()),
+        CHANGE_TYPE.get(modifiedFile.changeType()));
+  }
+
   /** Converts the given string path to an absolute path. */
   private static Optional<Path> convertPathFromFileDiffOutput(Optional<String> path) {
     requireNonNull(path, "path");
diff --git a/java/com/google/gerrit/plugins/codeowners/restapi/AbstractPathResource.java b/java/com/google/gerrit/plugins/codeowners/restapi/AbstractPathResource.java
index dd603fc..e3e22ba 100644
--- a/java/com/google/gerrit/plugins/codeowners/restapi/AbstractPathResource.java
+++ b/java/com/google/gerrit/plugins/codeowners/restapi/AbstractPathResource.java
@@ -23,7 +23,6 @@
 import com.google.gerrit.server.project.BranchResource;
 import java.nio.file.InvalidPathException;
 import java.nio.file.Path;
-import java.nio.file.Paths;
 import org.eclipse.jgit.lib.ObjectId;
 
 /**
@@ -41,14 +40,14 @@
   protected static Path parsePath(IdString id) throws BadRequestException {
     Path path;
     try {
-      path = Paths.get(id.get());
+      path = Path.of(id.get());
     } catch (InvalidPathException e) {
       throw new BadRequestException("invalid path: " + e.getReason());
     }
 
     if (!path.isAbsolute()) {
       // we assume that all paths are absolute, add the missing leading '/'
-      path = Paths.get("/").resolve(path);
+      path = Path.of("/").resolve(path);
     }
     return path;
   }
diff --git a/java/com/google/gerrit/plugins/codeowners/restapi/CheckCodeOwnerConfigFilesInRevision.java b/java/com/google/gerrit/plugins/codeowners/restapi/CheckCodeOwnerConfigFilesInRevision.java
index af4b97f..d4dcede 100644
--- a/java/com/google/gerrit/plugins/codeowners/restapi/CheckCodeOwnerConfigFilesInRevision.java
+++ b/java/com/google/gerrit/plugins/codeowners/restapi/CheckCodeOwnerConfigFilesInRevision.java
@@ -34,7 +34,7 @@
 import com.google.inject.Singleton;
 import java.io.IOException;
 import java.nio.file.FileSystems;
-import java.nio.file.Paths;
+import java.nio.file.Path;
 import java.util.List;
 import java.util.Map;
 import java.util.Optional;
@@ -103,9 +103,7 @@
                   changedFile ->
                       codeOwnerBackend.isCodeOwnerConfigFile(
                           revisionResource.getProject(),
-                          Paths.get(changedFile.newPath().get().toString())
-                              .getFileName()
-                              .toString()))
+                          Path.of(changedFile.newPath().get().toString()).getFileName().toString()))
               .filter(
                   changedFile ->
                       input.path == null
diff --git a/java/com/google/gerrit/plugins/codeowners/util/JgitPath.java b/java/com/google/gerrit/plugins/codeowners/util/JgitPath.java
index 18b77be..3de836c 100644
--- a/java/com/google/gerrit/plugins/codeowners/util/JgitPath.java
+++ b/java/com/google/gerrit/plugins/codeowners/util/JgitPath.java
@@ -17,7 +17,6 @@
 import static java.util.Objects.requireNonNull;
 
 import java.nio.file.Path;
-import java.nio.file.Paths;
 import java.util.Objects;
 
 /**
@@ -62,7 +61,7 @@
 
   /** Returns the path as absolute path. */
   public Path getAsAbsolutePath() {
-    return Paths.get("/" + get());
+    return Path.of("/" + get());
   }
 
   @Override
diff --git a/java/com/google/gerrit/plugins/codeowners/validation/CodeOwnerConfigValidator.java b/java/com/google/gerrit/plugins/codeowners/validation/CodeOwnerConfigValidator.java
index c8e0c7c..858b1a2 100644
--- a/java/com/google/gerrit/plugins/codeowners/validation/CodeOwnerConfigValidator.java
+++ b/java/com/google/gerrit/plugins/codeowners/validation/CodeOwnerConfigValidator.java
@@ -60,6 +60,7 @@
 import com.google.gerrit.server.git.CodeReviewCommit;
 import com.google.gerrit.server.git.CodeReviewCommit.CodeReviewRevWalk;
 import com.google.gerrit.server.git.GitRepositoryManager;
+import com.google.gerrit.server.git.InMemoryInserter;
 import com.google.gerrit.server.git.validators.CommitValidationException;
 import com.google.gerrit.server.git.validators.CommitValidationListener;
 import com.google.gerrit.server.git.validators.CommitValidationMessage;
@@ -72,19 +73,20 @@
 import com.google.gerrit.server.logging.TraceContext.TraceTimer;
 import com.google.gerrit.server.notedb.ChangeNotes;
 import com.google.gerrit.server.patch.DiffNotAvailableException;
+import com.google.gerrit.server.patch.DiffOperationsForCommitValidation;
 import com.google.gerrit.server.permissions.PermissionBackend;
 import com.google.gerrit.server.permissions.PermissionBackendException;
 import com.google.gerrit.server.permissions.ProjectPermission;
 import com.google.gerrit.server.permissions.RefPermission;
 import com.google.gerrit.server.project.ProjectCache;
 import com.google.gerrit.server.project.ProjectState;
+import com.google.gerrit.server.update.RepoView;
 import com.google.gerrit.server.validators.ValidationException;
 import com.google.inject.Inject;
 import com.google.inject.Provider;
 import com.google.inject.Singleton;
 import java.io.IOException;
 import java.nio.file.Path;
-import java.nio.file.Paths;
 import java.util.List;
 import java.util.Optional;
 import java.util.stream.Stream;
@@ -154,6 +156,7 @@
   private final SkipCodeOwnerConfigValidationPushOption skipCodeOwnerConfigValidationPushOption;
   private final CodeOwnerMetrics codeOwnerMetrics;
   private final DynamicItem<UrlFormatter> urlFormatter;
+  private final DiffOperationsForCommitValidation.Factory diffOperationsForCommitValidationFactory;
 
   @Inject
   CodeOwnerConfigValidator(
@@ -169,7 +172,8 @@
       IdentifiedUser.GenericFactory userFactory,
       SkipCodeOwnerConfigValidationPushOption skipCodeOwnerConfigValidationPushOption,
       CodeOwnerMetrics codeOwnerMetrics,
-      DynamicItem<UrlFormatter> urlFormatter) {
+      DynamicItem<UrlFormatter> urlFormatter,
+      DiffOperationsForCommitValidation.Factory diffOperationsForCommitValidationFactory) {
     this.pluginName = pluginName;
     this.codeOwnersPluginConfiguration = codeOwnersPluginConfiguration;
     this.repoManager = repoManager;
@@ -183,6 +187,7 @@
     this.skipCodeOwnerConfigValidationPushOption = skipCodeOwnerConfigValidationPushOption;
     this.codeOwnerMetrics = codeOwnerMetrics;
     this.urlFormatter = urlFormatter;
+    this.diffOperationsForCommitValidationFactory = diffOperationsForCommitValidationFactory;
   }
 
   @Override
@@ -216,6 +221,7 @@
         try {
           validationResult =
               validateCodeOwnerConfig(
+                  receiveEvent.diffOperations,
                   receiveEvent.getBranchNameKey(),
                   receiveEvent.commit,
                   receiveEvent.user,
@@ -298,13 +304,17 @@
                     new CommitValidationMessage(
                         "code owners config validation is disabled", ValidationMessage.Type.HINT)));
       } else {
-        try {
+        try (InMemoryInserter ins = new InMemoryInserter(repository);
+            ObjectReader reader = ins.newReader();
+            RevWalk rw = new RevWalk(reader)) {
           ChangeNotes changeNotes =
               changeNotesFactory.create(projectState.getNameKey(), commit.change().getId());
           PatchSet patchSet = patchSetUtil.get(changeNotes, patchSetId);
           IdentifiedUser patchSetUploader = userFactory.create(patchSet.uploader());
           validationResult =
               validateCodeOwnerConfig(
+                  diffOperationsForCommitValidationFactory.create(
+                      new RepoView(repository, rw, ins), ins),
                   branchNameKey,
                   commit,
                   patchSetUploader,
@@ -378,9 +388,14 @@
       } else {
         try {
           try (Repository repo = repoManager.openRepository(refReceivedEvent.getProjectNameKey());
-              RevWalk revWalk = new RevWalk(repo)) {
+              InMemoryInserter ins = new InMemoryInserter(repo);
+              ObjectReader reader = ins.newReader();
+              RevWalk rw = new RevWalk(reader);
+              RevWalk revWalk = new RevWalk(reader)) {
             validationResult =
                 validateCodeOwnerConfig(
+                    diffOperationsForCommitValidationFactory.create(
+                        new RepoView(repo, rw, ins), ins),
                     refReceivedEvent.getBranchNameKey(),
                     revWalk.parseCommit(refReceivedEvent.command.getNewId()),
                     refReceivedEvent.user,
@@ -441,6 +456,8 @@
   /**
    * Validates the code owner config files which are newly added or modified in the given commit.
    *
+   * @param diffOperationsForCommitValidation the {@link DiffOperationsForCommitValidation} instance
+   *     to be used to retrieve the modified files
    * @param branchNameKey the project and branch that contains the provided commit or for which the
    *     commit is being pushed
    * @param revCommit the commit for which newly added and modified code owner configs should be
@@ -453,6 +470,7 @@
    *     the given commit doesn't contain newly added or modified code owner configs
    */
   private Optional<ValidationResult> validateCodeOwnerConfig(
+      DiffOperationsForCommitValidation diffOperationsForCommitValidation,
       BranchNameKey branchNameKey,
       RevCommit revCommit,
       IdentifiedUser user,
@@ -514,7 +532,10 @@
           isBranchCreation
               ? getAllCodeOwnerConfigFiles(codeOwnerBackend, branchNameKey.project(), revCommit)
               : getModifiedCodeOwnerConfigFiles(
-                  codeOwnerBackend, branchNameKey.project(), revCommit);
+                  diffOperationsForCommitValidation,
+                  codeOwnerBackend,
+                  branchNameKey.project(),
+                  revCommit);
 
       if (codeOwnerConfigFilesToValidate.isEmpty()) {
         return Optional.empty();
@@ -559,7 +580,10 @@
   }
 
   public ImmutableList<ChangedFile> getModifiedCodeOwnerConfigFiles(
-      CodeOwnerBackend codeOwnerBackend, Project.NameKey project, ObjectId revCommit)
+      DiffOperationsForCommitValidation diffOperationsForCommitValidation,
+      CodeOwnerBackend codeOwnerBackend,
+      Project.NameKey project,
+      ObjectId revCommit)
       throws IOException, DiffNotAvailableException {
     // For merge commits, always do the comparison against the destination branch
     // (MergeCommitStrategy.ALL_CHANGED_FILES). Doing the comparison against the auto-merge
@@ -568,7 +592,12 @@
     // trying to get the auto merge would fail with a missing object exception. This is why we
     // use MergeCommitStrategy.ALL_CHANGED_FILES here even if
     // MergeCommitStrategy.FILES_WITH_CONFLICT_RESOLUTION is configured.
-    return changedFiles.getFromDiffCache(project, revCommit, MergeCommitStrategy.ALL_CHANGED_FILES)
+    return changedFiles
+        .getDuringCommitValidation(
+            diffOperationsForCommitValidation,
+            project,
+            revCommit,
+            MergeCommitStrategy.ALL_CHANGED_FILES)
         .stream()
         // filter out deletions (files without new path)
         .filter(changedFile -> changedFile.newPath().isPresent())
@@ -577,7 +606,7 @@
             changedFile ->
                 codeOwnerBackend.isCodeOwnerConfigFile(
                     project,
-                    Paths.get(changedFile.newPath().get().toString()).getFileName().toString()))
+                    Path.of(changedFile.newPath().get().toString()).getFileName().toString()))
         .collect(toImmutableList());
   }
 
@@ -711,7 +740,7 @@
     Path folderPath =
         filePath.getParent() != null
             ? JgitPath.of(filePath.getParent()).getAsAbsolutePath()
-            : Paths.get("/");
+            : Path.of("/");
     String fileName = filePath.getFileName().toString();
     return CodeOwnerConfig.Key.create(branchNameKey, folderPath, fileName);
   }
diff --git a/javatests/com/google/gerrit/plugins/codeowners/acceptance/api/CodeOwnersPluginConfigValidatorIT.java b/javatests/com/google/gerrit/plugins/codeowners/acceptance/api/CodeOwnersPluginConfigValidatorIT.java
index b0caf0a..c29a507 100644
--- a/javatests/com/google/gerrit/plugins/codeowners/acceptance/api/CodeOwnersPluginConfigValidatorIT.java
+++ b/javatests/com/google/gerrit/plugins/codeowners/acceptance/api/CodeOwnersPluginConfigValidatorIT.java
@@ -20,7 +20,6 @@
 import static com.google.gerrit.extensions.client.ListChangesOption.CURRENT_REVISION;
 import static com.google.gerrit.plugins.codeowners.testing.RequiredApprovalSubject.assertThat;
 import static com.google.gerrit.testing.GerritJUnit.assertThrows;
-import static com.google.gerrit.truth.OptionalSubject.assertThat;
 
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
@@ -46,6 +45,7 @@
 import com.google.gerrit.plugins.codeowners.backend.config.StatusConfig;
 import com.google.gerrit.plugins.codeowners.backend.proto.ProtoBackend;
 import com.google.gerrit.plugins.codeowners.common.MergeCommitStrategy;
+import com.google.gerrit.truth.OptionalSubject;
 import org.eclipse.jgit.lib.Config;
 import org.eclipse.jgit.revwalk.RevCommit;
 import org.eclipse.jgit.revwalk.RevObject;
@@ -257,7 +257,8 @@
 
     PushResult r = pushRefsMetaConfig();
     assertThat(r.getRemoteUpdate(RefNames.REFS_CONFIG).getStatus()).isEqualTo(Status.OK);
-    assertThat(codeOwnersPluginConfiguration.getProjectConfig(project).getPathExpressions("master"))
+    OptionalSubject.assertThat(
+            codeOwnersPluginConfiguration.getProjectConfig(project).getPathExpressions("master"))
         .value()
         .isEqualTo(PathExpressions.GLOB);
   }
@@ -276,7 +277,8 @@
 
     PushResult r = pushRefsMetaConfig();
     assertThat(r.getRemoteUpdate(RefNames.REFS_CONFIG).getStatus()).isEqualTo(Status.OK);
-    assertThat(codeOwnersPluginConfiguration.getProjectConfig(project).getPathExpressions("master"))
+    OptionalSubject.assertThat(
+            codeOwnersPluginConfiguration.getProjectConfig(project).getPathExpressions("master"))
         .value()
         .isEqualTo(PathExpressions.GLOB);
   }
@@ -669,7 +671,8 @@
     assertThat(r.getMessages())
         .contains(
             "The value for max paths in change messages 'INVALID' that is configured in"
-                + " code-owners.config (parameter codeOwners.maxPathsInChangeMessages) is invalid.");
+                + " code-owners.config (parameter codeOwners.maxPathsInChangeMessages) is"
+                + " invalid.");
   }
 
   @Test
@@ -863,7 +866,8 @@
     r.assertMessage(
         String.format(
             "hint: commit %s: Section 'codeOwners' in project.config is ignored and has no effect."
-                + " The configuration for the code-owners plugin must be done in code-owners.config.",
+                + " The configuration for the code-owners plugin must be done in"
+                + " code-owners.config.",
             ObjectIds.abbreviateName(r.getCommit(), testRepo.getRevWalk().getObjectReader())));
   }
 
diff --git a/javatests/com/google/gerrit/plugins/codeowners/acceptance/api/GetCodeOwnerStatusIT.java b/javatests/com/google/gerrit/plugins/codeowners/acceptance/api/GetCodeOwnerStatusIT.java
index fb87053..b378e3a 100644
--- a/javatests/com/google/gerrit/plugins/codeowners/acceptance/api/GetCodeOwnerStatusIT.java
+++ b/javatests/com/google/gerrit/plugins/codeowners/acceptance/api/GetCodeOwnerStatusIT.java
@@ -32,7 +32,6 @@
 import com.google.gerrit.server.util.AccountTemplateUtil;
 import com.google.inject.Inject;
 import java.nio.file.Path;
-import java.nio.file.Paths;
 import org.junit.Test;
 
 /**
@@ -347,8 +346,8 @@
         .addCodeOwnerEmail(user.email())
         .create();
 
-    Path oldPath = Paths.get("/foo/old.bar");
-    Path newPath = Paths.get("/bar/new.bar");
+    Path oldPath = Path.of("/foo/old.bar");
+    Path newPath = Path.of("/bar/new.bar");
     String changeId = createChangeWithFileRename(oldPath, newPath);
 
     // Add a reviewer that is a code owner of the old path.
diff --git a/javatests/com/google/gerrit/plugins/codeowners/acceptance/api/PutCodeOwnerProjectConfigIT.java b/javatests/com/google/gerrit/plugins/codeowners/acceptance/api/PutCodeOwnerProjectConfigIT.java
index e632f2a..ddddf39 100644
--- a/javatests/com/google/gerrit/plugins/codeowners/acceptance/api/PutCodeOwnerProjectConfigIT.java
+++ b/javatests/com/google/gerrit/plugins/codeowners/acceptance/api/PutCodeOwnerProjectConfigIT.java
@@ -19,7 +19,6 @@
 import static com.google.gerrit.plugins.codeowners.testing.RequiredApprovalSubject.assertThat;
 import static com.google.gerrit.server.project.ProjectCache.illegalState;
 import static com.google.gerrit.testing.GerritJUnit.assertThrows;
-import static com.google.gerrit.truth.OptionalSubject.assertThat;
 
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
@@ -44,6 +43,7 @@
 import com.google.gerrit.plugins.codeowners.common.MergeCommitStrategy;
 import com.google.gerrit.server.project.ProjectState;
 import com.google.gerrit.server.restapi.project.DeleteRef;
+import com.google.gerrit.truth.OptionalSubject;
 import com.google.inject.Inject;
 import org.eclipse.jgit.revwalk.RevCommit;
 import org.junit.Before;
@@ -181,7 +181,8 @@
 
   @Test
   public void setFileExtension() throws Exception {
-    assertThat(codeOwnersPluginConfiguration.getProjectConfig(project).getFileExtension())
+    OptionalSubject.assertThat(
+            codeOwnersPluginConfiguration.getProjectConfig(project).getFileExtension())
         .isEmpty();
 
     CodeOwnerProjectConfigInput input = new CodeOwnerProjectConfigInput();
@@ -189,14 +190,16 @@
     CodeOwnerProjectConfigInfo updatedConfig =
         projectCodeOwnersApiFactory.project(project).updateConfig(input);
     assertThat(updatedConfig.general.fileExtension).isEqualTo("foo");
-    assertThat(codeOwnersPluginConfiguration.getProjectConfig(project).getFileExtension())
+    OptionalSubject.assertThat(
+            codeOwnersPluginConfiguration.getProjectConfig(project).getFileExtension())
         .value()
         .isEqualTo("foo");
 
     input.fileExtension = "";
     updatedConfig = projectCodeOwnersApiFactory.project(project).updateConfig(input);
     assertThat(updatedConfig.general.fileExtension).isNull();
-    assertThat(codeOwnersPluginConfiguration.getProjectConfig(project).getFileExtension())
+    OptionalSubject.assertThat(
+            codeOwnersPluginConfiguration.getProjectConfig(project).getFileExtension())
         .isEmpty();
   }
 
@@ -406,7 +409,8 @@
 
   @Test
   public void setOverrideInfoUrl() throws Exception {
-    assertThat(codeOwnersPluginConfiguration.getProjectConfig(project).getOverrideInfoUrl())
+    OptionalSubject.assertThat(
+            codeOwnersPluginConfiguration.getProjectConfig(project).getOverrideInfoUrl())
         .isEmpty();
 
     CodeOwnerProjectConfigInput input = new CodeOwnerProjectConfigInput();
@@ -414,20 +418,22 @@
     CodeOwnerProjectConfigInfo updatedConfig =
         projectCodeOwnersApiFactory.project(project).updateConfig(input);
     assertThat(updatedConfig.general.overrideInfoUrl).isEqualTo("http://foo.bar");
-    assertThat(codeOwnersPluginConfiguration.getProjectConfig(project).getOverrideInfoUrl())
+    OptionalSubject.assertThat(
+            codeOwnersPluginConfiguration.getProjectConfig(project).getOverrideInfoUrl())
         .value()
         .isEqualTo("http://foo.bar");
 
     input.overrideInfoUrl = "";
     updatedConfig = projectCodeOwnersApiFactory.project(project).updateConfig(input);
     assertThat(updatedConfig.general.overrideInfoUrl).isNull();
-    assertThat(codeOwnersPluginConfiguration.getProjectConfig(project).getOverrideInfoUrl())
+    OptionalSubject.assertThat(
+            codeOwnersPluginConfiguration.getProjectConfig(project).getOverrideInfoUrl())
         .isEmpty();
   }
 
   @Test
   public void setInvalidCodeOwnerConfigInfoUrl() throws Exception {
-    assertThat(
+    OptionalSubject.assertThat(
             codeOwnersPluginConfiguration
                 .getProjectConfig(project)
                 .getInvalidCodeOwnerConfigInfoUrl())
@@ -438,7 +444,7 @@
     CodeOwnerProjectConfigInfo updatedConfig =
         projectCodeOwnersApiFactory.project(project).updateConfig(input);
     assertThat(updatedConfig.general.invalidCodeOwnerConfigInfoUrl).isEqualTo("http://foo.bar");
-    assertThat(
+    OptionalSubject.assertThat(
             codeOwnersPluginConfiguration
                 .getProjectConfig(project)
                 .getInvalidCodeOwnerConfigInfoUrl())
@@ -448,7 +454,7 @@
     input.invalidCodeOwnerConfigInfoUrl = "";
     updatedConfig = projectCodeOwnersApiFactory.project(project).updateConfig(input);
     assertThat(updatedConfig.general.invalidCodeOwnerConfigInfoUrl).isNull();
-    assertThat(
+    OptionalSubject.assertThat(
             codeOwnersPluginConfiguration
                 .getProjectConfig(project)
                 .getInvalidCodeOwnerConfigInfoUrl())
diff --git a/javatests/com/google/gerrit/plugins/codeowners/acceptance/api/RenameEmailIT.java b/javatests/com/google/gerrit/plugins/codeowners/acceptance/api/RenameEmailIT.java
index 0eb2793..9238093 100644
--- a/javatests/com/google/gerrit/plugins/codeowners/acceptance/api/RenameEmailIT.java
+++ b/javatests/com/google/gerrit/plugins/codeowners/acceptance/api/RenameEmailIT.java
@@ -15,7 +15,6 @@
 package com.google.gerrit.plugins.codeowners.acceptance.api;
 
 import static com.google.common.truth.Truth.assertThat;
-import static com.google.common.truth.Truth8.assertThat;
 import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.allow;
 import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.allowCapability;
 import static com.google.gerrit.plugins.codeowners.testing.CodeOwnerConfigSubject.assertThat;
diff --git a/javatests/com/google/gerrit/plugins/codeowners/acceptance/testsuite/CodeOwnerConfigOperationsImplTest.java b/javatests/com/google/gerrit/plugins/codeowners/acceptance/testsuite/CodeOwnerConfigOperationsImplTest.java
index 17e3ccd..85da5bd 100644
--- a/javatests/com/google/gerrit/plugins/codeowners/acceptance/testsuite/CodeOwnerConfigOperationsImplTest.java
+++ b/javatests/com/google/gerrit/plugins/codeowners/acceptance/testsuite/CodeOwnerConfigOperationsImplTest.java
@@ -17,7 +17,6 @@
 import static com.google.common.truth.Truth.assertThat;
 import static com.google.gerrit.plugins.codeowners.testing.CodeOwnerConfigSubject.assertThat;
 import static com.google.gerrit.testing.GerritJUnit.assertThrows;
-import static com.google.gerrit.truth.OptionalSubject.assertThat;
 
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableSet;
@@ -37,9 +36,10 @@
 import com.google.gerrit.plugins.codeowners.backend.CodeOwners;
 import com.google.gerrit.plugins.codeowners.backend.CodeOwnersUpdate;
 import com.google.gerrit.server.ServerInitiated;
+import com.google.gerrit.truth.OptionalSubject;
 import com.google.inject.Key;
 import com.google.inject.Provider;
-import java.nio.file.Paths;
+import java.nio.file.Path;
 import org.junit.Before;
 import org.junit.Test;
 
@@ -176,7 +176,7 @@
             .folderPath(folderPath)
             .addCodeOwnerEmail(admin.email())
             .create();
-    Truth8.assertThat(codeOwnerConfigKey.folderPath()).isEqualTo(Paths.get(folderPath));
+    Truth8.assertThat(codeOwnerConfigKey.folderPath()).isEqualTo(Path.of(folderPath));
     assertThat(getCodeOwnerConfigFromServer(codeOwnerConfigKey))
         .hasCodeOwnerSetsThat()
         .onlyElement()
@@ -195,7 +195,7 @@
             .fileName("OWNERS_foo")
             .addCodeOwnerEmail(admin.email())
             .create();
-    assertThat(codeOwnerConfigKey.fileName()).value().isEqualTo("OWNERS_foo");
+    OptionalSubject.assertThat(codeOwnerConfigKey.fileName()).value().isEqualTo("OWNERS_foo");
     assertThat(getCodeOwnerConfigFromServer(codeOwnerConfigKey))
         .hasCodeOwnerSetsThat()
         .onlyElement()
@@ -441,7 +441,7 @@
     // was dropped.
     // Since this made the code owner config empty it caused a deletion of the code owner config
     // file.
-    assertThat(codeOwners.getFromCurrentRevision(codeOwnerConfig.key())).isEmpty();
+    OptionalSubject.assertThat(codeOwners.getFromCurrentRevision(codeOwnerConfig.key())).isEmpty();
   }
 
   @Test
@@ -507,7 +507,7 @@
         .update();
 
     // Removing all code owner sets leads to a deletion of the code owner config file.
-    assertThat(codeOwners.getFromCurrentRevision(codeOwnerConfig.key())).isEmpty();
+    OptionalSubject.assertThat(codeOwners.getFromCurrentRevision(codeOwnerConfig.key())).isEmpty();
   }
 
   @Test
@@ -570,7 +570,7 @@
         .update();
 
     // Removing all code owner sets leads to a deletion of the code owner config file.
-    assertThat(codeOwners.getFromCurrentRevision(codeOwnerConfig.key())).isEmpty();
+    OptionalSubject.assertThat(codeOwners.getFromCurrentRevision(codeOwnerConfig.key())).isEmpty();
   }
 
   @Test
diff --git a/javatests/com/google/gerrit/plugins/codeowners/backend/AbstractFileBasedCodeOwnerBackendTest.java b/javatests/com/google/gerrit/plugins/codeowners/backend/AbstractFileBasedCodeOwnerBackendTest.java
index 7ec9295..7731055 100644
--- a/javatests/com/google/gerrit/plugins/codeowners/backend/AbstractFileBasedCodeOwnerBackendTest.java
+++ b/javatests/com/google/gerrit/plugins/codeowners/backend/AbstractFileBasedCodeOwnerBackendTest.java
@@ -15,10 +15,10 @@
 package com.google.gerrit.plugins.codeowners.backend;
 
 import static com.google.common.truth.Truth.assertThat;
-import static com.google.common.truth.Truth8.assertThat;
 import static com.google.gerrit.plugins.codeowners.testing.CodeOwnerConfigSubject.assertThatOptional;
 import static com.google.gerrit.testing.GerritJUnit.assertThrows;
 
+import com.google.common.truth.Truth8;
 import com.google.gerrit.acceptance.config.GerritConfig;
 import com.google.gerrit.common.Nullable;
 import com.google.gerrit.entities.BranchNameKey;
@@ -26,7 +26,7 @@
 import com.google.gerrit.plugins.codeowners.testing.backend.TestCodeOwnerConfigStorage;
 import com.google.gerrit.plugins.codeowners.util.JgitPath;
 import com.google.gerrit.server.IdentifiedUser;
-import java.nio.file.Paths;
+import java.nio.file.Path;
 import java.util.Optional;
 import org.eclipse.jgit.errors.ConfigInvalidException;
 import org.eclipse.jgit.errors.MissingObjectException;
@@ -476,17 +476,16 @@
   @Test
   public void getFilePathForCodeOwnerConfigKeyWithoutFileName() throws Exception {
     CodeOwnerConfig.Key codeOwnerConfigKey = CodeOwnerConfig.Key.create(project, "master", "/");
-    assertThat(codeOwnerBackend.getFilePath(codeOwnerConfigKey))
-        .isEqualTo(Paths.get(codeOwnerConfigKey.folderPath() + getFileName()));
+    Truth8.assertThat(codeOwnerBackend.getFilePath(codeOwnerConfigKey))
+        .isEqualTo(Path.of(codeOwnerConfigKey.folderPath() + getFileName()));
   }
 
   @Test
   public void getFilePathForCodeOwnerConfigKeyWithFileName() throws Exception {
     CodeOwnerConfig.Key codeOwnerConfigKey =
         CodeOwnerConfig.Key.create(project, "master", "/", getFileName() + "_foo_bar");
-    assertThat(codeOwnerBackend.getFilePath(codeOwnerConfigKey))
-        .isEqualTo(
-            Paths.get(codeOwnerConfigKey.folderPath() + codeOwnerConfigKey.fileName().get()));
+    Truth8.assertThat(codeOwnerBackend.getFilePath(codeOwnerConfigKey))
+        .isEqualTo(Path.of(codeOwnerConfigKey.folderPath() + codeOwnerConfigKey.fileName().get()));
   }
 
   @Test
diff --git a/javatests/com/google/gerrit/plugins/codeowners/backend/AbstractPathExpressionMatcherTest.java b/javatests/com/google/gerrit/plugins/codeowners/backend/AbstractPathExpressionMatcherTest.java
index 752eb01..33ace1f 100644
--- a/javatests/com/google/gerrit/plugins/codeowners/backend/AbstractPathExpressionMatcherTest.java
+++ b/javatests/com/google/gerrit/plugins/codeowners/backend/AbstractPathExpressionMatcherTest.java
@@ -18,7 +18,7 @@
 
 import com.google.common.collect.ImmutableList;
 import com.google.gerrit.plugins.codeowners.acceptance.AbstractCodeOwnersTest;
-import java.nio.file.Paths;
+import java.nio.file.Path;
 
 /** Base class for testing {@link PathExpressionMatcher}s. */
 public abstract class AbstractPathExpressionMatcherTest extends AbstractCodeOwnersTest {
@@ -37,7 +37,7 @@
       boolean expectedToMatch, String pathExpression, String firstPath, String... morePaths) {
     for (String path : toList(firstPath, morePaths)) {
       assertWithMessage("path expression %s matches path %s", pathExpression, path)
-          .that(getPathExpressionMatcher().matches(pathExpression, Paths.get(path)))
+          .that(getPathExpressionMatcher().matches(pathExpression, Path.of(path)))
           .isEqualTo(expectedToMatch);
     }
   }
diff --git a/javatests/com/google/gerrit/plugins/codeowners/backend/ChangedFileTest.java b/javatests/com/google/gerrit/plugins/codeowners/backend/ChangedFileTest.java
index 2c84634..b6b6389 100644
--- a/javatests/com/google/gerrit/plugins/codeowners/backend/ChangedFileTest.java
+++ b/javatests/com/google/gerrit/plugins/codeowners/backend/ChangedFileTest.java
@@ -16,7 +16,6 @@
 
 import static com.google.common.truth.Truth.assertThat;
 import static com.google.gerrit.testing.GerritJUnit.assertThrows;
-import static com.google.gerrit.truth.OptionalSubject.assertThat;
 import static org.mockito.Mockito.when;
 
 import com.google.gerrit.common.Nullable;
@@ -25,7 +24,8 @@
 import com.google.gerrit.plugins.codeowners.common.ChangedFile;
 import com.google.gerrit.server.patch.PatchListEntry;
 import com.google.gerrit.server.patch.filediff.FileDiffOutput;
-import java.nio.file.Paths;
+import com.google.gerrit.truth.OptionalSubject;
+import java.nio.file.Path;
 import java.util.Optional;
 import org.eclipse.jgit.diff.DiffEntry;
 import org.eclipse.jgit.diff.DiffEntry.ChangeType;
@@ -48,43 +48,45 @@
   public void getNewPath_diffEntry() throws Exception {
     String newPath = "foo/bar/baz.txt";
     setupDiffEntry(newPath, /* oldPath= */ null, ChangeType.ADD);
-    assertThat(ChangedFile.create(diffEntry).newPath()).value().isEqualTo(Paths.get("/" + newPath));
+    OptionalSubject.assertThat(ChangedFile.create(diffEntry).newPath())
+        .value()
+        .isEqualTo(Path.of("/" + newPath));
   }
 
   @Test
   public void getNewPath_patchListEntry() throws Exception {
     String newPath = "foo/bar/baz.txt";
     setupPatchListEntry(newPath, /* oldPath= */ null, Patch.ChangeType.ADDED);
-    assertThat(ChangedFile.create(patchListEntry).newPath())
+    OptionalSubject.assertThat(ChangedFile.create(patchListEntry).newPath())
         .value()
-        .isEqualTo(Paths.get("/" + newPath));
+        .isEqualTo(Path.of("/" + newPath));
   }
 
   @Test
   public void getNewPath_fileDiffOutput() throws Exception {
     String newPath = "foo/bar/baz.txt";
     setupFileDiffOutput(newPath, /* oldPath= */ null, Patch.ChangeType.ADDED);
-    assertThat(ChangedFile.create(fileDiffOutput).newPath())
+    OptionalSubject.assertThat(ChangedFile.create(fileDiffOutput).newPath())
         .value()
-        .isEqualTo(Paths.get("/" + newPath));
+        .isEqualTo(Path.of("/" + newPath));
   }
 
   @Test
   public void getNewPathWhenNewPathIsNotSet_diffEntry() throws Exception {
     setupDiffEntry(/* newPath= */ null, /* oldPath= */ null, ChangeType.ADD);
-    assertThat(ChangedFile.create(diffEntry).newPath()).isEmpty();
+    OptionalSubject.assertThat(ChangedFile.create(diffEntry).newPath()).isEmpty();
   }
 
   @Test
   public void getNewPathWhenNewPathIsNotSet_patchListEntry() throws Exception {
     setupPatchListEntry(/* newPath= */ null, /* oldPath= */ null, Patch.ChangeType.ADDED);
-    assertThat(ChangedFile.create(patchListEntry).newPath()).isEmpty();
+    OptionalSubject.assertThat(ChangedFile.create(patchListEntry).newPath()).isEmpty();
   }
 
   @Test
   public void getNewPathWhenNewPathIsNotSet_fileDiffOutput() throws Exception {
     setupFileDiffOutput(/* newPath= */ null, /* oldPath= */ null, Patch.ChangeType.ADDED);
-    assertThat(ChangedFile.create(fileDiffOutput).newPath()).isEmpty();
+    OptionalSubject.assertThat(ChangedFile.create(fileDiffOutput).newPath()).isEmpty();
   }
 
   @Test
@@ -93,8 +95,8 @@
     setupDiffEntry(newPath, /* oldPath= */ null, ChangeType.ADD);
 
     ChangedFile changedFile = ChangedFile.create(diffEntry);
-    assertThat(changedFile.hasNewPath(Paths.get("/" + newPath))).isTrue();
-    assertThat(changedFile.hasNewPath(Paths.get("/otherPath"))).isFalse();
+    assertThat(changedFile.hasNewPath(Path.of("/" + newPath))).isTrue();
+    assertThat(changedFile.hasNewPath(Path.of("/otherPath"))).isFalse();
   }
 
   @Test
@@ -103,8 +105,8 @@
     setupPatchListEntry(newPath, /* oldPath= */ null, Patch.ChangeType.ADDED);
 
     ChangedFile changedFile = ChangedFile.create(patchListEntry);
-    assertThat(changedFile.hasNewPath(Paths.get("/" + newPath))).isTrue();
-    assertThat(changedFile.hasNewPath(Paths.get("/otherPath"))).isFalse();
+    assertThat(changedFile.hasNewPath(Path.of("/" + newPath))).isTrue();
+    assertThat(changedFile.hasNewPath(Path.of("/otherPath"))).isFalse();
   }
 
   @Test
@@ -113,8 +115,8 @@
     setupFileDiffOutput(newPath, /* oldPath= */ null, Patch.ChangeType.ADDED);
 
     ChangedFile changedFile = ChangedFile.create(fileDiffOutput);
-    assertThat(changedFile.hasNewPath(Paths.get("/" + newPath))).isTrue();
-    assertThat(changedFile.hasNewPath(Paths.get("/otherPath"))).isFalse();
+    assertThat(changedFile.hasNewPath(Path.of("/" + newPath))).isTrue();
+    assertThat(changedFile.hasNewPath(Path.of("/otherPath"))).isFalse();
   }
 
   @Test
@@ -157,7 +159,7 @@
     IllegalStateException exception =
         assertThrows(
             IllegalStateException.class,
-            () -> ChangedFile.create(diffEntry).hasNewPath(Paths.get(relativePath)));
+            () -> ChangedFile.create(diffEntry).hasNewPath(Path.of(relativePath)));
     assertThat(exception)
         .hasMessageThat()
         .isEqualTo(String.format("path %s must be absolute", relativePath));
@@ -170,7 +172,7 @@
     IllegalStateException exception =
         assertThrows(
             IllegalStateException.class,
-            () -> ChangedFile.create(patchListEntry).hasNewPath(Paths.get(relativePath)));
+            () -> ChangedFile.create(patchListEntry).hasNewPath(Path.of(relativePath)));
     assertThat(exception)
         .hasMessageThat()
         .isEqualTo(String.format("path %s must be absolute", relativePath));
@@ -183,7 +185,7 @@
     IllegalStateException exception =
         assertThrows(
             IllegalStateException.class,
-            () -> ChangedFile.create(fileDiffOutput).hasNewPath(Paths.get(relativePath)));
+            () -> ChangedFile.create(fileDiffOutput).hasNewPath(Path.of(relativePath)));
     assertThat(exception)
         .hasMessageThat()
         .isEqualTo(String.format("path %s must be absolute", relativePath));
@@ -193,44 +195,46 @@
   public void getOldPath_diffEntry() throws Exception {
     String oldPath = "foo/bar/baz.txt";
     setupDiffEntry(/* newPath= */ null, oldPath, ChangeType.DELETE);
-    assertThat(ChangedFile.create(diffEntry).oldPath()).value().isEqualTo(Paths.get("/" + oldPath));
+    OptionalSubject.assertThat(ChangedFile.create(diffEntry).oldPath())
+        .value()
+        .isEqualTo(Path.of("/" + oldPath));
   }
 
   @Test
   public void getOldPath_patchListEntry() throws Exception {
     String oldPath = "foo/bar/baz.txt";
     setupPatchListEntry(/* newPath= */ null, oldPath, Patch.ChangeType.DELETED);
-    assertThat(ChangedFile.create(patchListEntry).oldPath())
+    OptionalSubject.assertThat(ChangedFile.create(patchListEntry).oldPath())
         .value()
-        .isEqualTo(Paths.get("/" + oldPath));
+        .isEqualTo(Path.of("/" + oldPath));
   }
 
   @Test
   public void getOldPath_fileDiffOutput() throws Exception {
     String oldPath = "foo/bar/baz.txt";
     setupFileDiffOutput(/* newPath= */ null, oldPath, Patch.ChangeType.DELETED);
-    assertThat(ChangedFile.create(fileDiffOutput).oldPath())
+    OptionalSubject.assertThat(ChangedFile.create(fileDiffOutput).oldPath())
         .value()
-        .isEqualTo(Paths.get("/" + oldPath));
+        .isEqualTo(Path.of("/" + oldPath));
   }
 
   @Test
   public void getOldPathWhenOldPathIsNotSet_diffEntry() throws Exception {
     setupDiffEntry(/* newPath= */ null, /* oldPath= */ null, ChangeType.DELETE);
     when(diffEntry.getOldPath()).thenReturn(DiffEntry.DEV_NULL);
-    assertThat(ChangedFile.create(diffEntry).oldPath()).isEmpty();
+    OptionalSubject.assertThat(ChangedFile.create(diffEntry).oldPath()).isEmpty();
   }
 
   @Test
   public void getOldPathWhenOldPathIsNotSet_patchListEntry() throws Exception {
     setupPatchListEntry(/* newPath= */ null, /* oldPath= */ null, Patch.ChangeType.DELETED);
-    assertThat(ChangedFile.create(patchListEntry).oldPath()).isEmpty();
+    OptionalSubject.assertThat(ChangedFile.create(patchListEntry).oldPath()).isEmpty();
   }
 
   @Test
   public void getOldPathWhenOldPathIsNotSet_fileDiffOutput() throws Exception {
     setupFileDiffOutput(/* newPath= */ null, /* oldPath= */ null, Patch.ChangeType.DELETED);
-    assertThat(ChangedFile.create(fileDiffOutput).oldPath()).isEmpty();
+    OptionalSubject.assertThat(ChangedFile.create(fileDiffOutput).oldPath()).isEmpty();
   }
 
   @Test
@@ -239,8 +243,8 @@
     setupDiffEntry(/* newPath= */ null, oldPath, ChangeType.DELETE);
 
     ChangedFile changedFile = ChangedFile.create(diffEntry);
-    assertThat(changedFile.hasOldPath(Paths.get("/" + oldPath))).isTrue();
-    assertThat(changedFile.hasOldPath(Paths.get("/otherPath"))).isFalse();
+    assertThat(changedFile.hasOldPath(Path.of("/" + oldPath))).isTrue();
+    assertThat(changedFile.hasOldPath(Path.of("/otherPath"))).isFalse();
   }
 
   @Test
@@ -249,8 +253,8 @@
     setupPatchListEntry(/* newPath= */ null, oldPath, Patch.ChangeType.DELETED);
 
     ChangedFile changedFile = ChangedFile.create(patchListEntry);
-    assertThat(changedFile.hasOldPath(Paths.get("/" + oldPath))).isTrue();
-    assertThat(changedFile.hasOldPath(Paths.get("/otherPath"))).isFalse();
+    assertThat(changedFile.hasOldPath(Path.of("/" + oldPath))).isTrue();
+    assertThat(changedFile.hasOldPath(Path.of("/otherPath"))).isFalse();
   }
 
   @Test
@@ -259,8 +263,8 @@
     setupFileDiffOutput(/* newPath= */ null, oldPath, Patch.ChangeType.DELETED);
 
     ChangedFile changedFile = ChangedFile.create(fileDiffOutput);
-    assertThat(changedFile.hasOldPath(Paths.get("/" + oldPath))).isTrue();
-    assertThat(changedFile.hasOldPath(Paths.get("/otherPath"))).isFalse();
+    assertThat(changedFile.hasOldPath(Path.of("/" + oldPath))).isTrue();
+    assertThat(changedFile.hasOldPath(Path.of("/otherPath"))).isFalse();
   }
 
   @Test
@@ -300,7 +304,7 @@
     IllegalStateException exception =
         assertThrows(
             IllegalStateException.class,
-            () -> ChangedFile.create(diffEntry).hasOldPath(Paths.get(relativePath)));
+            () -> ChangedFile.create(diffEntry).hasOldPath(Path.of(relativePath)));
     assertThat(exception)
         .hasMessageThat()
         .isEqualTo(String.format("path %s must be absolute", relativePath));
@@ -313,7 +317,7 @@
     IllegalStateException exception =
         assertThrows(
             IllegalStateException.class,
-            () -> ChangedFile.create(patchListEntry).hasOldPath(Paths.get(relativePath)));
+            () -> ChangedFile.create(patchListEntry).hasOldPath(Path.of(relativePath)));
     assertThat(exception)
         .hasMessageThat()
         .isEqualTo(String.format("path %s must be absolute", relativePath));
@@ -326,7 +330,7 @@
     IllegalStateException exception =
         assertThrows(
             IllegalStateException.class,
-            () -> ChangedFile.create(fileDiffOutput).hasOldPath(Paths.get(relativePath)));
+            () -> ChangedFile.create(fileDiffOutput).hasOldPath(Path.of(relativePath)));
     assertThat(exception)
         .hasMessageThat()
         .isEqualTo(String.format("path %s must be absolute", relativePath));
diff --git a/javatests/com/google/gerrit/plugins/codeowners/backend/ChangedFilesTest.java b/javatests/com/google/gerrit/plugins/codeowners/backend/ChangedFilesTest.java
index d72e981..e82a2aa 100644
--- a/javatests/com/google/gerrit/plugins/codeowners/backend/ChangedFilesTest.java
+++ b/javatests/com/google/gerrit/plugins/codeowners/backend/ChangedFilesTest.java
@@ -45,7 +45,7 @@
 import com.google.gerrit.server.change.RevisionResource;
 import com.google.gerrit.server.restapi.change.ChangesCollection;
 import com.google.inject.Inject;
-import java.nio.file.Paths;
+import java.nio.file.Path;
 import org.eclipse.jgit.lib.ObjectId;
 import org.eclipse.jgit.revwalk.RevCommit;
 import org.junit.Before;
@@ -134,7 +134,7 @@
         changedFiles.getFromDiffCache(project, commit, MergeCommitStrategy.ALL_CHANGED_FILES);
     assertThat(changedFilesSet).hasSize(1);
     ChangedFile changedFile = Iterables.getOnlyElement(changedFilesSet);
-    assertThat(changedFile).hasNewPath().value().isEqualTo(Paths.get(path));
+    assertThat(changedFile).hasNewPath().value().isEqualTo(Path.of(path));
     assertThat(changedFile).hasOldPath().isEmpty();
     assertThat(changedFile).isNoRename();
     assertThat(changedFile).isNoDeletion();
@@ -153,8 +153,8 @@
         changedFiles.getFromDiffCache(project, commit, MergeCommitStrategy.ALL_CHANGED_FILES);
     assertThat(changedFilesSet).hasSize(1);
     ChangedFile changedFile = Iterables.getOnlyElement(changedFilesSet);
-    assertThat(changedFile).hasNewPath().value().isEqualTo(Paths.get(path));
-    assertThat(changedFile).hasOldPath().value().isEqualTo(Paths.get(path));
+    assertThat(changedFile).hasNewPath().value().isEqualTo(Path.of(path));
+    assertThat(changedFile).hasOldPath().value().isEqualTo(Path.of(path));
     assertThat(changedFile).isNoRename();
     assertThat(changedFile).isNoDeletion();
   }
@@ -172,7 +172,7 @@
     assertThat(changedFilesSet).hasSize(1);
     ChangedFile changedFile = Iterables.getOnlyElement(changedFilesSet);
     assertThat(changedFile).hasNewPath().isEmpty();
-    assertThat(changedFile).hasOldPath().value().isEqualTo(Paths.get(path));
+    assertThat(changedFile).hasOldPath().value().isEqualTo(Path.of(path));
     assertThat(changedFile).isNoRename();
     assertThat(changedFile).isDeletion();
   }
@@ -191,8 +191,8 @@
             getRevisionResource(changeId).getPatchSet().commitId(),
             MergeCommitStrategy.ALL_CHANGED_FILES);
     ChangedFileSubject changedFile = assertThatCollection(changedFilesSet).onlyElement();
-    changedFile.hasNewPath().value().isEqualTo(Paths.get(newPath));
-    changedFile.hasOldPath().value().isEqualTo(Paths.get(oldPath));
+    changedFile.hasNewPath().value().isEqualTo(Path.of(newPath));
+    changedFile.hasOldPath().value().isEqualTo(Path.of(oldPath));
     changedFile.isRename();
     changedFile.isNoDeletion();
   }
@@ -209,7 +209,7 @@
         changedFiles.getFromDiffCache(project, commit, MergeCommitStrategy.ALL_CHANGED_FILES);
     assertThat(changedFilesSet).hasSize(1);
     ChangedFile changedFile = Iterables.getOnlyElement(changedFilesSet);
-    assertThat(changedFile).hasNewPath().value().isEqualTo(Paths.get(path));
+    assertThat(changedFile).hasNewPath().value().isEqualTo(Path.of(path));
     assertThat(changedFile).hasOldPath().isEmpty();
     assertThat(changedFile).isNoRename();
     assertThat(changedFile).isNoDeletion();
diff --git a/javatests/com/google/gerrit/plugins/codeowners/backend/CodeOwnerApprovalCheckForAccountTest.java b/javatests/com/google/gerrit/plugins/codeowners/backend/CodeOwnerApprovalCheckForAccountTest.java
index 499f42f..680c642 100644
--- a/javatests/com/google/gerrit/plugins/codeowners/backend/CodeOwnerApprovalCheckForAccountTest.java
+++ b/javatests/com/google/gerrit/plugins/codeowners/backend/CodeOwnerApprovalCheckForAccountTest.java
@@ -33,7 +33,6 @@
 import com.google.gerrit.truth.ListSubject;
 import com.google.inject.Inject;
 import java.nio.file.Path;
-import java.nio.file.Paths;
 import java.util.stream.Stream;
 import org.junit.Before;
 import org.junit.Test;
@@ -58,7 +57,7 @@
 
   @Test
   public void notApprovedByUser() throws Exception {
-    Path path = Paths.get("/foo/bar.baz");
+    Path path = Path.of("/foo/bar.baz");
     String changeId =
         createChange("Change Adding A File", JgitPath.of(path).get(), "file content").getChangeId();
     ChangeNotes changeNotes = getChangeNotes(changeId);
@@ -92,7 +91,7 @@
         .addCodeOwnerEmail(codeOwner.email())
         .create();
 
-    Path path = Paths.get("/foo/bar.baz");
+    Path path = Path.of("/foo/bar.baz");
     String changeId =
         createChange("Change Adding A File", JgitPath.of(path).get(), "file content").getChangeId();
     ChangeNotes changeNotes = getChangeNotes(changeId);
@@ -130,7 +129,7 @@
         .addCodeOwnerEmail(codeOwner.email())
         .create();
 
-    Path path = Paths.get("/foo/bar.baz");
+    Path path = Path.of("/foo/bar.baz");
     String changeId =
         createChange("Change Adding A File", JgitPath.of(path).get(), "file content").getChangeId();
     ChangeNotes changeNotes = getChangeNotes(changeId);
@@ -176,7 +175,7 @@
         .addCodeOwnerEmail(codeOwner.email())
         .create();
 
-    Path path = Paths.get("/foo/bar.baz");
+    Path path = Path.of("/foo/bar.baz");
     String changeId =
         createChange("Change Adding A File", JgitPath.of(path).get(), "file content").getChangeId();
     ChangeNotes changeNotes = getChangeNotes(changeId);
@@ -211,7 +210,7 @@
         .addCodeOwnerEmail(user.email())
         .create();
 
-    Path path = Paths.get("/foo/bar.baz");
+    Path path = Path.of("/foo/bar.baz");
     String changeId =
         createChange("Change Adding A File", JgitPath.of(path).get(), "file content").getChangeId();
     ChangeNotes changeNotes = getChangeNotes(changeId);
@@ -241,13 +240,13 @@
         .addCodeOwnerEmail(user.email())
         .create();
 
-    Path path1 = Paths.get("/foo/bar.baz");
+    Path path1 = Path.of("/foo/bar.baz");
     String changeId =
         createChange("Change Adding A File", JgitPath.of(path1).get(), "file content")
             .getChangeId();
 
     // amend change and add another file
-    Path path2 = Paths.get("/foo/baz.bar");
+    Path path2 = Path.of("/foo/baz.bar");
     PushOneCommit push =
         pushFactory.create(
             admin.newIdent(),
@@ -305,7 +304,7 @@
   @GerritConfig(name = "plugin.code-owners.fallbackCodeOwners", value = "ALL_USERS")
   @Test
   public void approvedByFallbackCodeOwner() throws Exception {
-    Path path = Paths.get("/foo/bar.baz");
+    Path path = Path.of("/foo/bar.baz");
     String changeId =
         createChange("Change Adding A File", JgitPath.of(path).get(), "file content").getChangeId();
     ChangeNotes changeNotes = getChangeNotes(changeId);
@@ -340,7 +339,7 @@
         .addCodeOwnerEmail(codeOwner.email())
         .create();
 
-    Path path = Paths.get("/foo/bar.baz");
+    Path path = Path.of("/foo/bar.baz");
     String changeId =
         createChange("Change Adding A File", JgitPath.of(path).get(), "file content").getChangeId();
     ChangeNotes changeNotes = getChangeNotes(changeId);
diff --git a/javatests/com/google/gerrit/plugins/codeowners/backend/CodeOwnerApprovalCheckInputTest.java b/javatests/com/google/gerrit/plugins/codeowners/backend/CodeOwnerApprovalCheckInputTest.java
index 0054f2e..9f2a585 100644
--- a/javatests/com/google/gerrit/plugins/codeowners/backend/CodeOwnerApprovalCheckInputTest.java
+++ b/javatests/com/google/gerrit/plugins/codeowners/backend/CodeOwnerApprovalCheckInputTest.java
@@ -16,7 +16,6 @@
 
 import static com.google.common.collect.ImmutableSet.toImmutableSet;
 import static com.google.common.truth.Truth.assertThat;
-import static com.google.common.truth.Truth8.assertThat;
 import static com.google.gerrit.server.group.SystemGroupBackend.REGISTERED_USERS;
 
 import com.google.common.collect.ArrayListMultimap;
diff --git a/javatests/com/google/gerrit/plugins/codeowners/backend/CodeOwnerApprovalCheckTest.java b/javatests/com/google/gerrit/plugins/codeowners/backend/CodeOwnerApprovalCheckTest.java
index 54d4e67..a497853 100644
--- a/javatests/com/google/gerrit/plugins/codeowners/backend/CodeOwnerApprovalCheckTest.java
+++ b/javatests/com/google/gerrit/plugins/codeowners/backend/CodeOwnerApprovalCheckTest.java
@@ -50,7 +50,6 @@
 import com.google.gerrit.server.util.AccountTemplateUtil;
 import com.google.inject.Inject;
 import java.nio.file.Path;
-import java.nio.file.Paths;
 import org.junit.Before;
 import org.junit.Test;
 
@@ -93,7 +92,7 @@
   public void getStatusForFileAddition_insufficientReviewers() throws Exception {
     TestAccount user2 = accountCreator.user2();
 
-    Path path = Paths.get("/foo/bar.baz");
+    Path path = Path.of("/foo/bar.baz");
     String changeId =
         createChange("Change Adding A File", JgitPath.of(path).get(), "file content").getChangeId();
 
@@ -114,7 +113,7 @@
   public void getStatusForFileModification_insufficientReviewers() throws Exception {
     TestAccount user2 = accountCreator.user2();
 
-    Path path = Paths.get("/foo/bar.baz");
+    Path path = Path.of("/foo/bar.baz");
     createChange("Test Change", JgitPath.of(path).get(), "file content").getChangeId();
     String changeId =
         createChange("Change Modifying A File", JgitPath.of(path).get(), "new file content")
@@ -137,7 +136,7 @@
   public void getStatusForFileDeletion_insufficientReviewers() throws Exception {
     TestAccount user2 = accountCreator.user2();
 
-    Path path = Paths.get("/foo/bar.baz");
+    Path path = Path.of("/foo/bar.baz");
     String changeId = createChangeWithFileDeletion(path);
 
     // Add a reviewer that is not a code owner.
@@ -157,8 +156,8 @@
   public void getStatusForFileRename_insufficientReviewers() throws Exception {
     TestAccount user2 = accountCreator.user2();
 
-    Path oldPath = Paths.get("/foo/old.bar");
-    Path newPath = Paths.get("/foo/new.bar");
+    Path oldPath = Path.of("/foo/old.bar");
+    Path newPath = Path.of("/foo/new.bar");
     String changeId = createChangeWithFileRename(oldPath, newPath);
 
     // Add a reviewer that is not a code owner.
@@ -184,7 +183,7 @@
 
     setAsRootCodeOwners(user);
 
-    Path path = Paths.get("/foo/bar.baz");
+    Path path = Path.of("/foo/bar.baz");
     String changeId =
         createChange("Change Adding A File", JgitPath.of(path).get(), "file content").getChangeId();
 
@@ -212,7 +211,7 @@
 
     setAsRootCodeOwners(user);
 
-    Path path = Paths.get("/foo/bar.baz");
+    Path path = Path.of("/foo/bar.baz");
     createChange("Test Change", JgitPath.of(path).get(), "file content").getChangeId();
     String changeId =
         createChange("Change Modifying A File", JgitPath.of(path).get(), "new file content")
@@ -242,7 +241,7 @@
 
     setAsRootCodeOwners(user);
 
-    Path path = Paths.get("/foo/bar.baz");
+    Path path = Path.of("/foo/bar.baz");
     String changeId = createChangeWithFileDeletion(path);
 
     // Add a reviewer that is a code owner.
@@ -269,8 +268,8 @@
 
     setAsCodeOwners("/foo/bar/", user);
 
-    Path oldPath = Paths.get("/foo/bar/abc.txt");
-    Path newPath = Paths.get("/foo/baz/abc.txt");
+    Path oldPath = Path.of("/foo/bar/abc.txt");
+    Path newPath = Path.of("/foo/baz/abc.txt");
     String changeId = createChangeWithFileRename(oldPath, newPath);
 
     // Add a reviewer that is a code owner old path.
@@ -300,8 +299,8 @@
 
     setAsCodeOwners("/foo/baz/", user);
 
-    Path oldPath = Paths.get("/foo/bar/abc.txt");
-    Path newPath = Paths.get("/foo/baz/abc.txt");
+    Path oldPath = Path.of("/foo/bar/abc.txt");
+    Path newPath = Path.of("/foo/baz/abc.txt");
     String changeId = createChangeWithFileRename(oldPath, newPath);
 
     // Add a reviewer that is a code owner of the new path.
@@ -329,7 +328,7 @@
   public void getStatusForFileAddition_approved() throws Exception {
     setAsRootCodeOwners(user);
 
-    Path path = Paths.get("/foo/bar.baz");
+    Path path = Path.of("/foo/bar.baz");
     String changeId =
         createChange("Change Adding A File", JgitPath.of(path).get(), "file content").getChangeId();
 
@@ -352,7 +351,7 @@
   public void getStatusForFileModification_approved() throws Exception {
     setAsRootCodeOwners(user);
 
-    Path path = Paths.get("/foo/bar.baz");
+    Path path = Path.of("/foo/bar.baz");
     createChange("Test Change", JgitPath.of(path).get(), "file content").getChangeId();
     String changeId =
         createChange("Change Modifying A File", JgitPath.of(path).get(), "new file content")
@@ -377,7 +376,7 @@
   public void getStatusForFileDeletion_approved() throws Exception {
     setAsRootCodeOwners(user);
 
-    Path path = Paths.get("/foo/bar.baz");
+    Path path = Path.of("/foo/bar.baz");
     String changeId = createChangeWithFileDeletion(path);
 
     // Add a Code-Review+1 from a code owner (by default this counts as code owner approval).
@@ -399,8 +398,8 @@
   public void getStatusForFileRename_approvedOldPath() throws Exception {
     setAsCodeOwners("/foo/bar/", user);
 
-    Path oldPath = Paths.get("/foo/bar/abc.txt");
-    Path newPath = Paths.get("/foo/baz/abc.txt");
+    Path oldPath = Path.of("/foo/bar/abc.txt");
+    Path newPath = Path.of("/foo/baz/abc.txt");
     String changeId = createChangeWithFileRename(oldPath, newPath);
 
     // Add a Code-Review+1 from a code owner of the old path (by default this counts as code owner
@@ -426,8 +425,8 @@
   public void getStatusForFileRename_approvedNewPath() throws Exception {
     setAsCodeOwners("/foo/baz/", user);
 
-    Path oldPath = Paths.get("/foo/bar/abc.txt");
-    Path newPath = Paths.get("/foo/baz/abc.txt");
+    Path oldPath = Path.of("/foo/bar/abc.txt");
+    Path newPath = Path.of("/foo/baz/abc.txt");
     String changeId = createChangeWithFileRename(oldPath, newPath);
 
     // Add a Code-Review+1 from a code owner of the new path (by default this counts as code owner
@@ -479,7 +478,7 @@
 
     setAsRootCodeOwners(changeOwner, otherCodeOwner);
 
-    Path path = Paths.get("/foo/bar.baz");
+    Path path = Path.of("/foo/bar.baz");
     String changeId =
         createChange("Change Adding A File", JgitPath.of(path).get(), "file content").getChangeId();
 
@@ -537,7 +536,7 @@
 
     setAsRootCodeOwners(changeOwner, otherCodeOwner);
 
-    Path path = Paths.get("/foo/bar.baz");
+    Path path = Path.of("/foo/bar.baz");
     createChange("Test Change", JgitPath.of(path).get(), "file content");
     String changeId =
         createChange("Change Modifying A File", JgitPath.of(path).get(), "new file content")
@@ -597,7 +596,7 @@
 
     setAsRootCodeOwners(changeOwner, otherCodeOwner);
 
-    Path path = Paths.get("/foo/bar.baz");
+    Path path = Path.of("/foo/bar.baz");
     String changeId = createChangeWithFileDeletion(path);
 
     if (uploaderMatchesChangeOwner) {
@@ -654,8 +653,8 @@
 
     setAsCodeOwners("/foo/bar/", changeOwner, otherCodeOwner);
 
-    Path oldPath = Paths.get("/foo/bar/abc.txt");
-    Path newPath = Paths.get("/foo/baz/abc.txt");
+    Path oldPath = Path.of("/foo/bar/abc.txt");
+    Path newPath = Path.of("/foo/baz/abc.txt");
     String changeId = createChangeWithFileRename(oldPath, newPath);
 
     if (uploaderMatchesChangeOwner) {
@@ -719,8 +718,8 @@
 
     setAsCodeOwners("/foo/baz/", changeOwner, otherCodeOwner);
 
-    Path oldPath = Paths.get("/foo/bar/abc.txt");
-    Path newPath = Paths.get("/foo/baz/abc.txt");
+    Path oldPath = Path.of("/foo/bar/abc.txt");
+    Path newPath = Path.of("/foo/baz/abc.txt");
     String changeId = createChangeWithFileRename(oldPath, newPath);
 
     if (uploaderMatchesChangeOwner) {
@@ -761,7 +760,7 @@
           throws Exception {
     setAsRootCodeOwners(admin);
 
-    Path path = Paths.get("/foo/bar.baz");
+    Path path = Path.of("/foo/bar.baz");
     String changeId =
         createChange("Change Adding A File", JgitPath.of(path).get(), "file content").getChangeId();
     amendChange(user, changeId);
@@ -784,7 +783,7 @@
         .create();
 
     // Create a change.
-    Path path = Paths.get("/foo/bar.baz");
+    Path path = Path.of("/foo/bar.baz");
     String changeId =
         createChange(user, "Change Adding A File", JgitPath.of(path).get(), "file content")
             .getChangeId();
@@ -848,7 +847,7 @@
         .create();
 
     // Create a change as a user that is a code owner.
-    Path path = Paths.get("/foo/bar.baz");
+    Path path = Path.of("/foo/bar.baz");
     String changeId =
         createChange("Change Adding A File", JgitPath.of(path).get(), "file content").getChangeId();
 
@@ -889,7 +888,7 @@
         .create();
 
     // Create a change as a user that is a code owner.
-    Path path = Paths.get("/foo/bar.baz");
+    Path path = Path.of("/foo/bar.baz");
     String changeId =
         createChange("Change Adding A File", JgitPath.of(path).get(), "file content").getChangeId();
 
@@ -923,7 +922,7 @@
         accountCreator.create("bot", "bot@example.com", "Bot", /* displayName= */ null);
 
     // Create a change as a user that is not a code owner.
-    Path path = Paths.get("/foo/bar.baz");
+    Path path = Path.of("/foo/bar.baz");
     String changeId =
         createChange(user, "Change Adding A File", JgitPath.of(path).get(), "file content")
             .getChangeId();
@@ -993,7 +992,7 @@
         accountCreator.create(
             "other_bot", "otherBot@example.com", "Other Bot", /* displayName= */ null);
 
-    Path path = Paths.get("/foo/bar.baz");
+    Path path = Path.of("/foo/bar.baz");
     String changeId =
         createChange(bot, "Change Adding A File", JgitPath.of(path).get(), "file content")
             .getChangeId();
@@ -1031,7 +1030,7 @@
         accountCreator.create("bot", "bot@example.com", "Bot", /* displayName= */ null);
 
     // Create a change as a user that is not a code owner.
-    Path path = Paths.get("/foo/bar.baz");
+    Path path = Path.of("/foo/bar.baz");
     String changeId =
         createChange(user, "Change Adding A File", JgitPath.of(path).get(), "file content")
             .getChangeId();
@@ -1083,7 +1082,7 @@
   @GerritConfig(name = "plugin.code-owners.globalCodeOwner", value = "*")
   public void approvedByAnyoneWhenEveryoneIsGlobalCodeOwner() throws Exception {
     // Create a change.
-    Path path = Paths.get("/foo/bar.baz");
+    Path path = Path.of("/foo/bar.baz");
     String changeId =
         createChange(user, "Change Adding A File", JgitPath.of(path).get(), "file content")
             .getChangeId();
@@ -1141,7 +1140,7 @@
     TestAccount changeOwner = admin;
     TestAccount otherCodeOwner = user;
     // Create a change as a user that is a code owner only through the global code ownership.
-    Path path = Paths.get("/foo/bar.baz");
+    Path path = Path.of("/foo/bar.baz");
     String changeId =
         createChange("Change Adding A File", JgitPath.of(path).get(), "file content").getChangeId();
 
@@ -1174,7 +1173,7 @@
   @GerritConfig(name = "plugin.code-owners.globalCodeOwner", value = "*")
   public void anyReviewerWhenEveryoneIsGlobalCodeOwner() throws Exception {
     // Create a change as a user that is a code owner only through the global code ownership.
-    Path path = Paths.get("/foo/bar.baz");
+    Path path = Path.of("/foo/bar.baz");
     String changeId =
         createChange("Change Adding A File", JgitPath.of(path).get(), "file content").getChangeId();
 
@@ -1210,7 +1209,7 @@
     setAsCodeOwners("/foo/", user2);
     setAsCodeOwners("/foo/bar/", user3);
 
-    Path path = Paths.get("/foo/bar/baz.txt");
+    Path path = Path.of("/foo/bar/baz.txt");
     String changeId =
         createChange("Change Adding A File", JgitPath.of(path).get(), "file content").getChangeId();
 
@@ -1486,7 +1485,7 @@
     createBranch(BranchNameKey.create(project, branchName));
 
     // Create a change as a user that is not a code owner.
-    Path path = Paths.get("/foo/bar.baz");
+    Path path = Path.of("/foo/bar.baz");
     String changeId =
         createChange(user, "Change Adding A File", JgitPath.of(path).get(), "file content")
             .getChangeId();
@@ -1502,7 +1501,7 @@
   @TestProjectInput(createEmptyCommit = false)
   public void getStatus_initialChange_defaultCodeOwner() throws Exception {
     // Create a change as a user that is not a code owner.
-    Path path = Paths.get("/foo/bar.baz");
+    Path path = Path.of("/foo/bar.baz");
     String changeId =
         createChange(user, "Change Adding A File", JgitPath.of(path).get(), "file content")
             .getChangeId();
@@ -1557,7 +1556,7 @@
     createBranch(BranchNameKey.create(project, branchName));
 
     // Create a change as a user that is not a code owner.
-    Path path = Paths.get("/foo/bar.baz");
+    Path path = Path.of("/foo/bar.baz");
     String changeId =
         createChange(admin, "Change Adding A File", JgitPath.of(path).get(), "file content")
             .getChangeId();
@@ -1578,7 +1577,7 @@
         accountCreator.create("bot", "bot@example.com", "Bot", /* displayName= */ null);
 
     // Create a change as a user that is not a code owner.
-    Path path = Paths.get("/foo/bar.baz");
+    Path path = Path.of("/foo/bar.baz");
     String changeId =
         createChange(admin, "Change Adding A File", JgitPath.of(path).get(), "file content")
             .getChangeId();
@@ -1633,7 +1632,7 @@
     createBranch(BranchNameKey.create(project, branchName));
 
     // Create a change as a user that is not a code owner.
-    Path path = Paths.get("/foo/bar.baz");
+    Path path = Path.of("/foo/bar.baz");
     String changeId =
         createChange(admin, "Change Adding A File", JgitPath.of(path).get(), "file content")
             .getChangeId();
@@ -1650,7 +1649,7 @@
   @GerritConfig(name = "plugin.code-owners.overrideApproval", value = "Owners-Override+1")
   public void getStatus_initialChange_override() throws Exception {
     // Create a change as a user that is not a code owner.
-    Path path = Paths.get("/foo/bar.baz");
+    Path path = Path.of("/foo/bar.baz");
     String changeId =
         createChange(admin, "Change Adding A File", JgitPath.of(path).get(), "file content")
             .getChangeId();
@@ -1689,7 +1688,7 @@
     setAsRootCodeOwners(user);
 
     // Create a change as a user that is not a code owner.
-    Path path = Paths.get("/foo/bar.baz");
+    Path path = Path.of("/foo/bar.baz");
     String changeId =
         createChange(user2, "Change Adding A File", JgitPath.of(path).get(), "file content")
             .getChangeId();
@@ -1759,7 +1758,7 @@
     gApi.projects().name(project.get()).label("Owners-Override").update(input);
 
     // Create a change as a user that is not a code owner.
-    Path path = Paths.get("/foo/bar.baz");
+    Path path = Path.of("/foo/bar.baz");
     String changeId =
         createChange(user, "Change Adding A File", JgitPath.of(path).get(), "file content")
             .getChangeId();
@@ -1819,7 +1818,7 @@
     setAsRootCodeOwners(user);
 
     // Create a change as 'user2' that is not a code owner.
-    Path path = Paths.get("/foo/bar.baz");
+    Path path = Path.of("/foo/bar.baz");
     String changeId =
         createChange(user2, "Change Adding A File", JgitPath.of(path).get(), "file content")
             .getChangeId();
@@ -1876,7 +1875,7 @@
     setAsRootCodeOwners(admin);
 
     // Create a change as 'user' that is not a code owner.
-    Path path = Paths.get("/foo/bar.baz");
+    Path path = Path.of("/foo/bar.baz");
     String changeId =
         createChange(user, "Change Adding A File", JgitPath.of(path).get(), "file content")
             .getChangeId();
@@ -1911,7 +1910,7 @@
     setAsDefaultCodeOwners(user);
 
     // Create a change as a user that is not a code owner.
-    Path path = Paths.get("/foo/bar.baz");
+    Path path = Path.of("/foo/bar.baz");
     String changeId =
         createChange(user2, "Change Adding A File", JgitPath.of(path).get(), "file content")
             .getChangeId();
@@ -1974,7 +1973,7 @@
 
     setAsDefaultCodeOwners(changeOwner, otherCodeOwner);
 
-    Path path = Paths.get("/foo/bar.baz");
+    Path path = Path.of("/foo/bar.baz");
     String changeId =
         createChange("Change Adding A File", JgitPath.of(path).get(), "file content").getChangeId();
 
@@ -2009,7 +2008,7 @@
     setAsDefaultCodeOwners(user);
 
     // Create a change as a user that is not a code owner.
-    Path path = Paths.get("/foo/bar.baz");
+    Path path = Path.of("/foo/bar.baz");
     String changeId =
         createChange(user2, "Change Adding A File", JgitPath.of(path).get(), "file content")
             .getChangeId();
@@ -2061,7 +2060,7 @@
   public void pureRevertsAreNotExemptedByDefault() throws Exception {
     setAsRootCodeOwners(admin);
 
-    Path path = Paths.get("/foo/bar.baz");
+    Path path = Path.of("/foo/bar.baz");
     String changeId =
         createChange("Change Adding A File", JgitPath.of(path).get(), "file content").getChangeId();
     approve(changeId);
@@ -2083,7 +2082,7 @@
   public void pureRevertsAreExemptedIfConfigured() throws Exception {
     setAsRootCodeOwners(admin);
 
-    Path path = Paths.get("/foo/bar.baz");
+    Path path = Path.of("/foo/bar.baz");
     String changeId =
         createChange("Change Adding A File", JgitPath.of(path).get(), "file content").getChangeId();
     approve(changeId);
@@ -2108,7 +2107,7 @@
   public void nonPureRevertsAreNotExempted() throws Exception {
     setAsRootCodeOwners(admin);
 
-    Path path = Paths.get("/foo/bar.baz");
+    Path path = Path.of("/foo/bar.baz");
     String changeId =
         createChange("Change Adding A File", JgitPath.of(path).get(), "file content").getChangeId();
     approve(changeId);
@@ -2147,7 +2146,7 @@
         accountCreator.create(
             "exemptedUser", "exempted-user@example.com", "Exempted User", /* displayName= */ null);
 
-    Path path = Paths.get("/foo/bar.baz");
+    Path path = Path.of("/foo/bar.baz");
     String changeId =
         createChange(exemptedUser, "Change Adding A File", JgitPath.of(path).get(), "file content")
             .getChangeId();
@@ -2183,7 +2182,7 @@
     TestAccount changeOwner = admin;
     setAsRootCodeOwners(changeOwner);
 
-    Path path = Paths.get("/foo/bar.baz");
+    Path path = Path.of("/foo/bar.baz");
     String changeId =
         createChange("Change Adding A File", JgitPath.of(path).get(), "file content").getChangeId();
 
diff --git a/javatests/com/google/gerrit/plugins/codeowners/backend/CodeOwnerApprovalCheckWithAllUsersAsFallbackCodeOwnersTest.java b/javatests/com/google/gerrit/plugins/codeowners/backend/CodeOwnerApprovalCheckWithAllUsersAsFallbackCodeOwnersTest.java
index b6c3a43..5fdef9f 100644
--- a/javatests/com/google/gerrit/plugins/codeowners/backend/CodeOwnerApprovalCheckWithAllUsersAsFallbackCodeOwnersTest.java
+++ b/javatests/com/google/gerrit/plugins/codeowners/backend/CodeOwnerApprovalCheckWithAllUsersAsFallbackCodeOwnersTest.java
@@ -35,7 +35,6 @@
 import com.google.gerrit.testing.ConfigSuite;
 import com.google.inject.Inject;
 import java.nio.file.Path;
-import java.nio.file.Paths;
 import org.eclipse.jgit.lib.Config;
 import org.junit.Before;
 import org.junit.Test;
@@ -75,7 +74,7 @@
             "codeOwner", "codeOwner@example.com", "CodeOwner", /* displayName= */ null);
     setAsRootCodeOwners(codeOwner);
 
-    Path path = Paths.get("/foo/bar.baz");
+    Path path = Path.of("/foo/bar.baz");
     String changeId =
         createChange("Change Adding A File", JgitPath.of(path).get(), "file content").getChangeId();
 
@@ -115,7 +114,7 @@
             "codeOwner", "codeOwner@example.com", "CodeOwner", /* displayName= */ null);
     setAsRootCodeOwners(codeOwner);
 
-    Path path = Paths.get("/foo/bar.baz");
+    Path path = Path.of("/foo/bar.baz");
     String changeId =
         createChange("Change Adding A File", JgitPath.of(path).get(), "file content").getChangeId();
 
@@ -136,7 +135,7 @@
         .addCodeOwnerEmail("non-resolvable-code-owner@example.com")
         .create();
 
-    Path path = Paths.get("/foo/bar.baz");
+    Path path = Path.of("/foo/bar.baz");
     String changeId =
         createChange("Change Adding A File", JgitPath.of(path).get(), "file content").getChangeId();
 
@@ -180,7 +179,7 @@
         .addCodeOwnerEmail("non-resolvable-code-owner@example.com")
         .create();
 
-    Path path = Paths.get("/foo/bar.baz");
+    Path path = Path.of("/foo/bar.baz");
     String changeId =
         createChange("Change Adding A File", JgitPath.of(path).get(), "file content").getChangeId();
 
@@ -193,7 +192,7 @@
 
   @Test
   public void approvedByFallbackCodeOwner() throws Exception {
-    Path path = Paths.get("/foo/bar.baz");
+    Path path = Path.of("/foo/bar.baz");
     String changeId =
         createChange("Change Adding A File", JgitPath.of(path).get(), "file content").getChangeId();
 
@@ -238,7 +237,7 @@
   @Test
   @GerritConfig(name = "plugin.code-owners.enableImplicitApprovals", value = "true")
   public void implicitlyApprovedByFallbackCodeOwner() throws Exception {
-    Path path = Paths.get("/foo/bar.baz");
+    Path path = Path.of("/foo/bar.baz");
     String changeId =
         createChange("Change Adding A File", JgitPath.of(path).get(), "file content").getChangeId();
 
@@ -266,7 +265,7 @@
         .ignoreParentCodeOwners()
         .create();
 
-    Path path = Paths.get("/foo/bar.baz");
+    Path path = Path.of("/foo/bar.baz");
     String changeId =
         createChange("Change Adding A File", JgitPath.of(path).get(), "file content").getChangeId();
 
@@ -309,7 +308,7 @@
         .ignoreParentCodeOwners()
         .create();
 
-    Path path = Paths.get("/foo/bar.baz");
+    Path path = Path.of("/foo/bar.baz");
     String changeId =
         createChange("Change Adding A File", JgitPath.of(path).get(), "file content").getChangeId();
 
@@ -331,7 +330,7 @@
             CodeOwnerConfigReference.create(CodeOwnerConfigImportMode.ALL, "/non-existing/OWNERS"))
         .create();
 
-    Path path = Paths.get("/foo/bar.baz");
+    Path path = Path.of("/foo/bar.baz");
     String changeId =
         createChange("Change Adding A File", JgitPath.of(path).get(), "file content").getChangeId();
 
@@ -375,7 +374,7 @@
             CodeOwnerConfigReference.create(CodeOwnerConfigImportMode.ALL, "/non-existing/OWNERS"))
         .create();
 
-    Path path = Paths.get("/foo/bar.baz");
+    Path path = Path.of("/foo/bar.baz");
     String changeId =
         createChange("Change Adding A File", JgitPath.of(path).get(), "file content").getChangeId();
 
@@ -402,7 +401,7 @@
                 .autoBuild())
         .create();
 
-    Path path = Paths.get("/foo/bar.md");
+    Path path = Path.of("/foo/bar.md");
     String changeId =
         createChange("Change Adding A File", JgitPath.of(path).get(), "file content").getChangeId();
 
@@ -452,7 +451,7 @@
                 .autoBuild())
         .create();
 
-    Path path = Paths.get("/foo/bar.md");
+    Path path = Path.of("/foo/bar.md");
     String changeId =
         createChange("Change Adding A File", JgitPath.of(path).get(), "file content").getChangeId();
 
@@ -469,7 +468,7 @@
     createBranch(BranchNameKey.create(project, branchName));
 
     // Create a change as a user that is not a code owner.
-    Path path = Paths.get("/foo/bar.baz");
+    Path path = Path.of("/foo/bar.baz");
     String changeId =
         createChange(user, "Change Adding A File", JgitPath.of(path).get(), "file content")
             .getChangeId();
@@ -485,7 +484,7 @@
   @TestProjectInput(createEmptyCommit = false)
   public void getStatus_initialChange() throws Exception {
     // Create a change as a user that is not a code owner.
-    Path path = Paths.get("/foo/bar.baz");
+    Path path = Path.of("/foo/bar.baz");
     String changeId =
         createChange(user, "Change Adding A File", JgitPath.of(path).get(), "file content")
             .getChangeId();
diff --git a/javatests/com/google/gerrit/plugins/codeowners/backend/CodeOwnerApprovalCheckWithSelfApprovalsIgnoredTest.java b/javatests/com/google/gerrit/plugins/codeowners/backend/CodeOwnerApprovalCheckWithSelfApprovalsIgnoredTest.java
index 43ab903..566af4d 100644
--- a/javatests/com/google/gerrit/plugins/codeowners/backend/CodeOwnerApprovalCheckWithSelfApprovalsIgnoredTest.java
+++ b/javatests/com/google/gerrit/plugins/codeowners/backend/CodeOwnerApprovalCheckWithSelfApprovalsIgnoredTest.java
@@ -32,7 +32,6 @@
 import com.google.gerrit.testing.ConfigSuite;
 import com.google.inject.Inject;
 import java.nio.file.Path;
-import java.nio.file.Paths;
 import org.eclipse.jgit.lib.Config;
 import org.junit.Before;
 import org.junit.Test;
@@ -77,7 +76,7 @@
             "codeOwner", "codeOwner@example.com", "CodeOwner", /* displayName= */ null);
     setAsRootCodeOwners(codeOwner);
 
-    Path path = Paths.get("/foo/bar.baz");
+    Path path = Path.of("/foo/bar.baz");
     String changeId =
         createChange(codeOwner, "Change Adding A File", JgitPath.of(path).get(), "file content")
             .getChangeId();
@@ -106,7 +105,7 @@
             "changeOwner", "changeOwner@example.com", "ChangeOwner", /* displayName= */ null);
     setAsRootCodeOwners(changeOwner);
 
-    Path path = Paths.get("/foo/bar.baz");
+    Path path = Path.of("/foo/bar.baz");
     String changeId =
         createChange(changeOwner, "Change Adding A File", JgitPath.of(path).get(), "file content")
             .getChangeId();
@@ -148,7 +147,7 @@
             "codeOwner", "codeOwner@example.com", "CodeOwner", /* displayName= */ null);
     setAsRootCodeOwners(codeOwner);
 
-    Path path = Paths.get("/foo/bar.baz");
+    Path path = Path.of("/foo/bar.baz");
     String changeId =
         createChange(changeOwner, "Change Adding A File", JgitPath.of(path).get(), "file content")
             .getChangeId();
@@ -192,7 +191,7 @@
             "codeOwner", "codeOwner@example.com", "CodeOwner", /* displayName= */ null);
     setAsRootCodeOwners(codeOwner);
 
-    Path path = Paths.get("/foo/bar.baz");
+    Path path = Path.of("/foo/bar.baz");
     String changeId =
         createChange(codeOwner, "Change Adding A File", JgitPath.of(path).get(), "file content")
             .getChangeId();
@@ -216,7 +215,7 @@
             "codeOwner", "codeOwner@example.com", "CodeOwner", /* displayName= */ null);
     setAsRootCodeOwners(codeOwner);
 
-    Path path = Paths.get("/foo/bar.baz");
+    Path path = Path.of("/foo/bar.baz");
     String changeId =
         createChange(changeOwner, "Change Adding A File", JgitPath.of(path).get(), "file content")
             .getChangeId();
@@ -239,7 +238,7 @@
             "codeOwner", "codeOwner@example.com", "CodeOwner", /* displayName= */ null);
     setAsRootCodeOwners(codeOwner);
 
-    Path path = Paths.get("/foo/bar.baz");
+    Path path = Path.of("/foo/bar.baz");
     String changeId =
         createChange(codeOwner, "Change Adding A File", JgitPath.of(path).get(), "file content")
             .getChangeId();
@@ -268,7 +267,7 @@
             "codeOwner", "codeOwner@example.com", "CodeOwner", /* displayName= */ null);
     setAsRootCodeOwners(codeOwner);
 
-    Path path = Paths.get("/foo/bar.baz");
+    Path path = Path.of("/foo/bar.baz");
     String changeId =
         createChange(changeOwner, "Change Adding A File", JgitPath.of(path).get(), "file content")
             .getChangeId();
@@ -289,7 +288,7 @@
         accountCreator.create(
             "changeOwner", "changeOwner@example.com", "ChangeOwner", /* displayName= */ null);
 
-    Path path = Paths.get("/foo/bar.baz");
+    Path path = Path.of("/foo/bar.baz");
     String changeId =
         createChange(changeOwner, "Change Adding A File", JgitPath.of(path).get(), "file content")
             .getChangeId();
@@ -318,7 +317,7 @@
         accountCreator.create(
             "changeOwner", "changeOwner@example.com", "ChangeOwner", /* displayName= */ null);
 
-    Path path = Paths.get("/foo/bar.baz");
+    Path path = Path.of("/foo/bar.baz");
     String changeId =
         createChange(changeOwner, "Change Adding A File", JgitPath.of(path).get(), "file content")
             .getChangeId();
@@ -355,7 +354,7 @@
         accountCreator.create(
             "changeOwner", "changeOwner@example.com", "ChangeOwner", /* displayName= */ null);
 
-    Path path = Paths.get("/foo/bar.baz");
+    Path path = Path.of("/foo/bar.baz");
     String changeId =
         createChange(changeOwner, "Change Adding A File", JgitPath.of(path).get(), "file content")
             .getChangeId();
diff --git a/javatests/com/google/gerrit/plugins/codeowners/backend/CodeOwnerApprovalCheckWithStickyApprovalsTest.java b/javatests/com/google/gerrit/plugins/codeowners/backend/CodeOwnerApprovalCheckWithStickyApprovalsTest.java
index 28f83f5..b26dcd3 100644
--- a/javatests/com/google/gerrit/plugins/codeowners/backend/CodeOwnerApprovalCheckWithStickyApprovalsTest.java
+++ b/javatests/com/google/gerrit/plugins/codeowners/backend/CodeOwnerApprovalCheckWithStickyApprovalsTest.java
@@ -37,7 +37,6 @@
 import com.google.gerrit.testing.ConfigSuite;
 import com.google.inject.Inject;
 import java.nio.file.Path;
-import java.nio.file.Paths;
 import java.util.Map;
 import org.eclipse.jgit.lib.Config;
 import org.junit.Before;
@@ -70,7 +69,7 @@
 
   @Test
   public void notApproved_noStickyApproval() throws Exception {
-    Path path = Paths.get("/foo/bar.baz");
+    Path path = Path.of("/foo/bar.baz");
     String changeId =
         createChange("Change Adding A File", JgitPath.of(path).get(), "file content").getChangeId();
 
@@ -93,7 +92,7 @@
 
   @Test
   public void notApproved_byPreviousApprovalOfNonCodeOwner() throws Exception {
-    Path path = Paths.get("/foo/bar.baz");
+    Path path = Path.of("/foo/bar.baz");
     String changeId =
         createChange("Change Adding A File", JgitPath.of(path).get(), "file content").getChangeId();
 
@@ -118,7 +117,7 @@
             "codeOwner", "codeOwner@example.com", "CodeOwner", /* displayName= */ null);
     setAsRootCodeOwners(codeOwner);
 
-    Path path = Paths.get("/foo/bar.baz");
+    Path path = Path.of("/foo/bar.baz");
     String changeId =
         createChange("Change Adding A File", JgitPath.of(path).get(), "file content").getChangeId();
 
@@ -149,7 +148,7 @@
             "codeOwner", "codeOwner@example.com", "CodeOwner", /* displayName= */ null);
     setAsRootCodeOwners(codeOwner);
 
-    Path path = Paths.get("/foo/bar.baz");
+    Path path = Path.of("/foo/bar.baz");
     String changeId =
         createChange("Change Adding A File", JgitPath.of(path).get(), "file content").getChangeId();
 
@@ -189,8 +188,8 @@
             "codeOwner2", "codeOwner2@example.com", "CodeOwner2", /* displayName= */ null);
     setAsCodeOwners("/bar/", codeOwner2);
 
-    Path path1 = Paths.get("/foo/bar.baz");
-    Path path2 = Paths.get("/bar/foo.baz");
+    Path path1 = Path.of("/foo/bar.baz");
+    Path path2 = Path.of("/bar/foo.baz");
     String changeId =
         createChange(
                 "Change Adding A File",
@@ -269,7 +268,7 @@
             "codeOwner", "codeOwner@example.com", "CodeOwner", /* displayName= */ null);
     setAsRootCodeOwners(codeOwner);
 
-    Path path = Paths.get("/foo/bar.baz");
+    Path path = Path.of("/foo/bar.baz");
     String changeId =
         createChange("Change Adding A File", JgitPath.of(path).get(), "file content").getChangeId();
 
@@ -325,7 +324,7 @@
             "codeOwner", "codeOwner@example.com", "CodeOwner", /* displayName= */ null);
     setAsRootCodeOwners(codeOwner);
 
-    Path path = Paths.get("/foo/bar.baz");
+    Path path = Path.of("/foo/bar.baz");
     String changeId =
         createChange("Change Adding A File", JgitPath.of(path).get(), "file content").getChangeId();
 
@@ -376,7 +375,7 @@
             "codeOwner", "codeOwner@example.com", "CodeOwner", /* displayName= */ null);
     setAsRootCodeOwners(codeOwner);
 
-    Path path = Paths.get("/foo/bar.baz");
+    Path path = Path.of("/foo/bar.baz");
     String changeId =
         createChange("Change Adding A File", JgitPath.of(path).get(), "file content").getChangeId();
 
@@ -424,7 +423,7 @@
     TestAccount implicitCodeOwner = admin; // the changes is created by the admit user
     setAsRootCodeOwners(implicitCodeOwner);
 
-    Path path = Paths.get("/foo/bar.baz");
+    Path path = Path.of("/foo/bar.baz");
     String changeId =
         createChange("Change Adding A File", JgitPath.of(path).get(), "file content").getChangeId();
 
@@ -457,7 +456,7 @@
             "codeOwner", "codeOwner@example.com", "CodeOwner", /* displayName= */ null);
     setAsRootCodeOwners(codeOwner);
 
-    Path path = Paths.get("/foo/bar.baz");
+    Path path = Path.of("/foo/bar.baz");
     String changeId =
         createChange("Change Adding A File", JgitPath.of(path).get(), "file content").getChangeId();
 
@@ -466,7 +465,7 @@
     recommend(changeId);
 
     // create a second patch set that adds a new file
-    Path path2 = Paths.get("/foo/abc.xyz");
+    Path path2 = Path.of("/foo/abc.xyz");
     amendChange(
             changeId,
             "Change Adding A File",
@@ -526,7 +525,7 @@
         .addCodeOwnerEmail("*")
         .create();
 
-    Path path = Paths.get("/foo/bar.baz");
+    Path path = Path.of("/foo/bar.baz");
     String changeId =
         createChange("Change Adding A File", JgitPath.of(path).get(), "file content").getChangeId();
 
@@ -557,7 +556,7 @@
             "codeOwner", "codeOwner@example.com", "CodeOwner", /* displayName= */ null);
     setAsDefaultCodeOwners(codeOwner);
 
-    Path path = Paths.get("/foo/bar.baz");
+    Path path = Path.of("/foo/bar.baz");
     String changeId =
         createChange("Change Adding A File", JgitPath.of(path).get(), "file content").getChangeId();
 
@@ -593,7 +592,7 @@
         .addCodeOwnerEmail("*")
         .create();
 
-    Path path = Paths.get("/foo/bar.baz");
+    Path path = Path.of("/foo/bar.baz");
     String changeId =
         createChange("Change Adding A File", JgitPath.of(path).get(), "file content").getChangeId();
 
@@ -625,7 +624,7 @@
     TestAccount bot =
         accountCreator.create("bot", "bot@example.com", "Bot", /* displayName= */ null);
 
-    Path path = Paths.get("/foo/bar.baz");
+    Path path = Path.of("/foo/bar.baz");
     String changeId =
         createChange("Change Adding A File", JgitPath.of(path).get(), "file content").getChangeId();
 
@@ -653,7 +652,7 @@
   @GerritConfig(name = "plugin.code-owners.globalCodeOwner", value = "*")
   public void approved_byStickyApprovalOfGlobalCodeOnPreviousPatchSet_everyoneIsGlobalCodeOwner()
       throws Exception {
-    Path path = Paths.get("/foo/bar.baz");
+    Path path = Path.of("/foo/bar.baz");
     String changeId =
         createChange("Change Adding A File", JgitPath.of(path).get(), "file content").getChangeId();
 
diff --git a/javatests/com/google/gerrit/plugins/codeowners/backend/CodeOwnerConfigFileUpdateScannerTest.java b/javatests/com/google/gerrit/plugins/codeowners/backend/CodeOwnerConfigFileUpdateScannerTest.java
index ea8af79..4a014a8 100644
--- a/javatests/com/google/gerrit/plugins/codeowners/backend/CodeOwnerConfigFileUpdateScannerTest.java
+++ b/javatests/com/google/gerrit/plugins/codeowners/backend/CodeOwnerConfigFileUpdateScannerTest.java
@@ -15,7 +15,6 @@
 package com.google.gerrit.plugins.codeowners.backend;
 
 import static com.google.common.truth.Truth.assertThat;
-import static com.google.common.truth.Truth8.assertThat;
 import static com.google.gerrit.testing.GerritJUnit.assertThrows;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.Mockito.verifyNoInteractions;
@@ -30,7 +29,6 @@
 import com.google.gerrit.plugins.codeowners.util.JgitPath;
 import com.google.inject.Inject;
 import java.nio.file.Path;
-import java.nio.file.Paths;
 import java.util.Optional;
 import org.eclipse.jgit.junit.TestRepository;
 import org.eclipse.jgit.lib.Ref;
@@ -170,7 +168,7 @@
             .addCodeOwnerEmail(admin.email())
             .create();
     Path path =
-        Paths.get(codeOwnerConfigOperations.codeOwnerConfig(codeOwnerConfigKey).getFilePath());
+        Path.of(codeOwnerConfigOperations.codeOwnerConfig(codeOwnerConfigKey).getFilePath());
     String content = codeOwnerConfigOperations.codeOwnerConfig(codeOwnerConfigKey).getContent();
 
     RevCommit oldHead = projectOperations.project(project).getHead("master");
@@ -204,7 +202,7 @@
             .addCodeOwnerEmail(admin.email())
             .create();
     Path path1 =
-        Paths.get(codeOwnerConfigOperations.codeOwnerConfig(codeOwnerConfigKey1).getFilePath());
+        Path.of(codeOwnerConfigOperations.codeOwnerConfig(codeOwnerConfigKey1).getFilePath());
     String oldContent1 =
         codeOwnerConfigOperations.codeOwnerConfig(codeOwnerConfigKey1).getContent();
     String newContent1 = user.email() + "\n";
@@ -220,7 +218,7 @@
             .addCodeOwnerEmail(user.email())
             .create();
     Path path2 =
-        Paths.get(codeOwnerConfigOperations.codeOwnerConfig(codeOwnerConfigKey2).getFilePath());
+        Path.of(codeOwnerConfigOperations.codeOwnerConfig(codeOwnerConfigKey2).getFilePath());
     String oldContent2 =
         codeOwnerConfigOperations.codeOwnerConfig(codeOwnerConfigKey2).getContent();
     String newContent2 = user2.email() + "\n";
@@ -265,7 +263,7 @@
     assertThat(update).isPresent();
 
     // Verify that we received the expected callbacks for the invalid code onwer config.
-    Mockito.verify(updater).update(Paths.get("/OWNERS"), "INVALID");
+    Mockito.verify(updater).update(Path.of("/OWNERS"), "INVALID");
     verifyNoMoreInteractions(updater);
 
     // Verify the code owner config file was updated.
@@ -282,7 +280,7 @@
     approve(changeId);
     gApi.changes().id(changeId).current().submit();
     enableCodeOwnersForProject(project);
-    Path path = Paths.get(filePath);
+    Path path = Path.of(filePath);
     return CodeOwnerConfig.Key.create(
         project, "master", path.getParent().toString(), path.getFileName().toString());
   }
diff --git a/javatests/com/google/gerrit/plugins/codeowners/backend/CodeOwnerConfigHierarchyTest.java b/javatests/com/google/gerrit/plugins/codeowners/backend/CodeOwnerConfigHierarchyTest.java
index 0422551..670ecf1 100644
--- a/javatests/com/google/gerrit/plugins/codeowners/backend/CodeOwnerConfigHierarchyTest.java
+++ b/javatests/com/google/gerrit/plugins/codeowners/backend/CodeOwnerConfigHierarchyTest.java
@@ -35,7 +35,7 @@
 import com.google.gerrit.server.restapi.project.DeleteRef;
 import com.google.inject.Inject;
 import java.io.IOException;
-import java.nio.file.Paths;
+import java.nio.file.Path;
 import java.util.function.Consumer;
 import org.eclipse.jgit.lib.ObjectId;
 import org.eclipse.jgit.lib.Ref;
@@ -83,7 +83,7 @@
                 codeOwnerConfigHierarchy.visit(
                     /* branchNameKey= */ null,
                     getCurrentRevision(BranchNameKey.create(project, "master")),
-                    Paths.get("/foo/bar/baz.md"),
+                    Path.of("/foo/bar/baz.md"),
                     visitor));
     assertThat(npe).hasMessageThat().isEqualTo("branch");
   }
@@ -93,7 +93,7 @@
     codeOwnerConfigHierarchy.visit(
         BranchNameKey.create(project, "master"),
         /* revision= */ null,
-        Paths.get("/foo/bar/baz.md"),
+        Path.of("/foo/bar/baz.md"),
         visitor);
     verifyNoInteractions(visitor);
   }
@@ -124,7 +124,7 @@
                 codeOwnerConfigHierarchy.visit(
                     branchNameKey,
                     getCurrentRevision(branchNameKey),
-                    Paths.get(relativePath),
+                    Path.of(relativePath),
                     visitor));
     assertThat(exception)
         .hasMessageThat()
@@ -141,7 +141,7 @@
                 codeOwnerConfigHierarchy.visit(
                     branchNameKey,
                     getCurrentRevision(branchNameKey),
-                    Paths.get("/foo/bar/baz.md"),
+                    Path.of("/foo/bar/baz.md"),
                     /* codeOwnerConfigVisitor= */ null));
     assertThat(npe).hasMessageThat().isEqualTo("codeOwnerConfigVisitor");
   }
@@ -156,7 +156,7 @@
                 codeOwnerConfigHierarchy.visit(
                     branchNameKey,
                     getCurrentRevision(branchNameKey),
-                    Paths.get("/foo/bar/baz.md"),
+                    Path.of("/foo/bar/baz.md"),
                     visitor,
                     /* parentCodeOwnersIgnoredCallback= */ null));
     assertThat(npe).hasMessageThat().isEqualTo("parentCodeOwnersIgnoredCallback");
@@ -320,7 +320,7 @@
 
     when(visitor.visit(any(CodeOwnerConfig.class))).thenReturn(true);
     codeOwnerConfigHierarchy.visit(
-        BranchNameKey.create(project, branch), revision1, Paths.get("/foo/bar/baz.md"), visitor);
+        BranchNameKey.create(project, branch), revision1, Path.of("/foo/bar/baz.md"), visitor);
 
     // Verify that we received the callbacks for the code owner configs from the old revison, in
     // the right order, starting from the folder of the given path up to the root folder.
@@ -593,7 +593,7 @@
     codeOwnerConfigHierarchy.visit(
         BranchNameKey.create(project, "master"),
         /* revision= */ null,
-        Paths.get("/foo/bar/baz.md"),
+        Path.of("/foo/bar/baz.md"),
         visitor);
     verify(visitor).visit(codeOwnerConfigOperations.codeOwnerConfig(metaCodeOwnerConfigKey).get());
     verifyNoMoreInteractions(visitor);
@@ -781,7 +781,7 @@
     codeOwnerConfigHierarchy.visit(
         branchNameKey,
         getCurrentRevision(branchNameKey),
-        Paths.get(path),
+        Path.of(path),
         visitor,
         parentCodeOwnersIgnoredCallback);
   }
diff --git a/javatests/com/google/gerrit/plugins/codeowners/backend/CodeOwnerConfigReferenceTest.java b/javatests/com/google/gerrit/plugins/codeowners/backend/CodeOwnerConfigReferenceTest.java
index 42d3696..f82b4cf 100644
--- a/javatests/com/google/gerrit/plugins/codeowners/backend/CodeOwnerConfigReferenceTest.java
+++ b/javatests/com/google/gerrit/plugins/codeowners/backend/CodeOwnerConfigReferenceTest.java
@@ -17,12 +17,11 @@
 import static com.google.common.truth.PathSubject.paths;
 import static com.google.common.truth.Truth.assertThat;
 import static com.google.common.truth.Truth.assertWithMessage;
-import static com.google.common.truth.Truth8.assertThat;
 import static com.google.gerrit.testing.GerritJUnit.assertThrows;
 
+import com.google.common.truth.Truth8;
 import com.google.gerrit.plugins.codeowners.acceptance.AbstractCodeOwnersTest;
 import java.nio.file.Path;
-import java.nio.file.Paths;
 import java.util.Optional;
 import org.junit.Test;
 
@@ -53,7 +52,7 @@
 
   @Test
   public void absoluteFilePathCanBeSpecifiedInDifferentFormats() throws Exception {
-    Path expectedPath = Paths.get("/foo/OWNERS");
+    Path expectedPath = Path.of("/foo/OWNERS");
     for (String inputPath : new String[] {"/foo/OWNERS", "//foo/OWNERS"}) {
       Path path =
           CodeOwnerConfigReference.create(CodeOwnerConfigImportMode.ALL, inputPath).filePath();
@@ -66,7 +65,7 @@
   public void relativeFilePathCanBeSpecified() throws Exception {
     Path path =
         CodeOwnerConfigReference.create(CodeOwnerConfigImportMode.ALL, "foo/OWNERS").filePath();
-    assertThat(path).isEqualTo(Paths.get("foo/OWNERS"));
+    Truth8.assertThat(path).isEqualTo(Path.of("foo/OWNERS"));
     assertThat(path.isAbsolute()).isFalse();
   }
 }
diff --git a/javatests/com/google/gerrit/plugins/codeowners/backend/CodeOwnerConfigScannerTest.java b/javatests/com/google/gerrit/plugins/codeowners/backend/CodeOwnerConfigScannerTest.java
index 18fff7f..0d33dc6 100644
--- a/javatests/com/google/gerrit/plugins/codeowners/backend/CodeOwnerConfigScannerTest.java
+++ b/javatests/com/google/gerrit/plugins/codeowners/backend/CodeOwnerConfigScannerTest.java
@@ -27,7 +27,7 @@
 import com.google.gerrit.entities.RefNames;
 import com.google.gerrit.plugins.codeowners.acceptance.AbstractCodeOwnersTest;
 import com.google.gerrit.plugins.codeowners.acceptance.testsuite.CodeOwnerConfigOperations;
-import java.nio.file.Paths;
+import java.nio.file.Path;
 import org.eclipse.jgit.junit.TestRepository;
 import org.eclipse.jgit.lib.Ref;
 import org.eclipse.jgit.lib.Repository;
@@ -159,7 +159,7 @@
     // Verify that we received the expected callbacks for the invalid code onwer config.
     Mockito.verify(invalidCodeOwnerConfigCallback)
         .onInvalidCodeOwnerConfig(
-            eq(Paths.get("/OWNERS")), any(InvalidCodeOwnerConfigException.class));
+            eq(Path.of("/OWNERS")), any(InvalidCodeOwnerConfigException.class));
     verifyNoMoreInteractions(invalidCodeOwnerConfigCallback);
   }
 
@@ -190,7 +190,7 @@
     // Verify that we received the expected callbacks for the invalid code onwer config.
     Mockito.verify(invalidCodeOwnerConfigCallback)
         .onInvalidCodeOwnerConfig(
-            eq(Paths.get("/OWNERS")), any(InvalidCodeOwnerConfigException.class));
+            eq(Path.of("/OWNERS")), any(InvalidCodeOwnerConfigException.class));
     verifyNoMoreInteractions(invalidCodeOwnerConfigCallback);
   }
 
diff --git a/javatests/com/google/gerrit/plugins/codeowners/backend/CodeOwnerConfigTest.java b/javatests/com/google/gerrit/plugins/codeowners/backend/CodeOwnerConfigTest.java
index 433922f..764a576 100644
--- a/javatests/com/google/gerrit/plugins/codeowners/backend/CodeOwnerConfigTest.java
+++ b/javatests/com/google/gerrit/plugins/codeowners/backend/CodeOwnerConfigTest.java
@@ -15,15 +15,14 @@
 package com.google.gerrit.plugins.codeowners.backend;
 
 import static com.google.common.truth.Truth.assertThat;
-import static com.google.common.truth.Truth8.assertThat;
 import static com.google.gerrit.testing.GerritJUnit.assertThrows;
 
+import com.google.common.truth.Truth8;
 import com.google.gerrit.entities.BranchNameKey;
 import com.google.gerrit.entities.Project;
 import com.google.gerrit.entities.RefNames;
 import com.google.gerrit.plugins.codeowners.acceptance.AbstractCodeOwnersTest;
 import java.nio.file.Path;
-import java.nio.file.Paths;
 import org.eclipse.jgit.lib.ObjectId;
 import org.junit.Test;
 
@@ -40,7 +39,7 @@
     CodeOwnerConfig.Key codeOwnerConfigKeyCreatedByCustomConstructor =
         CodeOwnerConfig.Key.create(project, branch, folderPath);
     CodeOwnerConfig.Key codeOwnerConfigKeyCreatedByAutoValueConstructor =
-        CodeOwnerConfig.Key.create(BranchNameKey.create(project, branch), Paths.get(folderPath));
+        CodeOwnerConfig.Key.create(BranchNameKey.create(project, branch), Path.of(folderPath));
     assertThat(codeOwnerConfigKeyCreatedByCustomConstructor)
         .isEqualTo(codeOwnerConfigKeyCreatedByAutoValueConstructor);
   }
@@ -88,7 +87,8 @@
     String folderPath = "/foo/bar/";
     CodeOwnerConfig.Key codeOwnerConfigKey =
         CodeOwnerConfig.Key.create(Project.nameKey("project"), "master", folderPath);
-    assertThat(codeOwnerConfigKey.filePath("OWNERS")).isEqualTo(Paths.get(folderPath, "OWNERS"));
+    Truth8.assertThat(codeOwnerConfigKey.filePath("OWNERS"))
+        .isEqualTo(Path.of(folderPath, "OWNERS"));
   }
 
   @Test
@@ -98,8 +98,8 @@
     CodeOwnerConfig.Key codeOwnerConfigKey =
         CodeOwnerConfig.Key.create(
             Project.nameKey("project"), "master", folderPath, customFileName);
-    assertThat(codeOwnerConfigKey.filePath("OWNERS"))
-        .isEqualTo(Paths.get(folderPath, customFileName));
+    Truth8.assertThat(codeOwnerConfigKey.filePath("OWNERS"))
+        .isEqualTo(Path.of(folderPath, customFileName));
   }
 
   @Test
@@ -137,17 +137,17 @@
         CodeOwnerConfig.builder(
                 CodeOwnerConfig.Key.create(
                     BranchNameKey.create(Project.nameKey("project"), "master"),
-                    Paths.get("/foo/bar/")),
+                    Path.of("/foo/bar/")),
                 TEST_REVISION)
             .build();
-    Path relativizedPath = codeOwnerConfig.relativize(Paths.get("/foo/bar/baz.md"));
-    assertThat(relativizedPath).isEqualTo(Paths.get("baz.md"));
+    Path relativizedPath = codeOwnerConfig.relativize(Path.of("/foo/bar/baz.md"));
+    Truth8.assertThat(relativizedPath).isEqualTo(Path.of("baz.md"));
   }
 
   private static CodeOwnerConfig.Builder createCodeOwnerBuilder() {
     return CodeOwnerConfig.builder(
         CodeOwnerConfig.Key.create(
-            BranchNameKey.create(Project.nameKey("project"), "master"), Paths.get("/")),
+            BranchNameKey.create(Project.nameKey("project"), "master"), Path.of("/")),
         TEST_REVISION);
   }
 }
diff --git a/javatests/com/google/gerrit/plugins/codeowners/backend/CodeOwnerResolverTest.java b/javatests/com/google/gerrit/plugins/codeowners/backend/CodeOwnerResolverTest.java
index 6171aca..e64c53e 100644
--- a/javatests/com/google/gerrit/plugins/codeowners/backend/CodeOwnerResolverTest.java
+++ b/javatests/com/google/gerrit/plugins/codeowners/backend/CodeOwnerResolverTest.java
@@ -35,7 +35,7 @@
 import com.google.inject.Inject;
 import com.google.inject.Key;
 import com.google.inject.Provider;
-import java.nio.file.Paths;
+import java.nio.file.Path;
 import java.util.Optional;
 import java.util.Set;
 import org.eclipse.jgit.lib.ObjectId;
@@ -358,7 +358,7 @@
     CodeOwnerResolverResult result =
         codeOwnerResolverProvider
             .get()
-            .resolvePathCodeOwners(codeOwnerConfig, Paths.get("/README.md"));
+            .resolvePathCodeOwners(codeOwnerConfig, Path.of("/README.md"));
     assertThat(result.codeOwners()).isEmpty();
     assertThat(result.ownedByAllUsers()).isFalse();
     assertThat(result.hasUnresolvedCodeOwners()).isFalse();
@@ -374,7 +374,7 @@
     CodeOwnerResolverResult result =
         codeOwnerResolverProvider
             .get()
-            .resolvePathCodeOwners(codeOwnerConfig, Paths.get("/README.md"));
+            .resolvePathCodeOwners(codeOwnerConfig, Path.of("/README.md"));
     assertThat(result.codeOwnersAccountIds()).containsExactly(admin.id(), user.id());
     assertThat(result.ownedByAllUsers()).isFalse();
     assertThat(result.hasUnresolvedCodeOwners()).isFalse();
@@ -391,7 +391,7 @@
     CodeOwnerResolverResult result =
         codeOwnerResolverProvider
             .get()
-            .resolvePathCodeOwners(codeOwnerConfig, Paths.get("/README.md"));
+            .resolvePathCodeOwners(codeOwnerConfig, Path.of("/README.md"));
     assertThat(result.codeOwnersAccountIds()).isEmpty();
     assertThat(result.ownedByAllUsers()).isTrue();
     assertThat(result.hasUnresolvedCodeOwners()).isFalse();
@@ -408,7 +408,7 @@
     CodeOwnerResolverResult result =
         codeOwnerResolverProvider
             .get()
-            .resolvePathCodeOwners(codeOwnerConfig, Paths.get("/README.md"));
+            .resolvePathCodeOwners(codeOwnerConfig, Path.of("/README.md"));
     assertThat(result.codeOwnersAccountIds()).containsExactly(admin.id());
     assertThat(result.ownedByAllUsers()).isFalse();
     assertThat(result.hasUnresolvedCodeOwners()).isTrue();
@@ -426,7 +426,7 @@
     CodeOwnerResolverResult result =
         codeOwnerResolverProvider
             .get()
-            .resolvePathCodeOwners(codeOwnerConfig, Paths.get("/README.md"));
+            .resolvePathCodeOwners(codeOwnerConfig, Path.of("/README.md"));
     assertThat(result.codeOwnersAccountIds()).containsExactly(admin.id());
     assertThat(result.ownedByAllUsers()).isTrue();
     assertThat(result.hasUnresolvedCodeOwners()).isTrue();
@@ -452,7 +452,7 @@
     CodeOwnerResolverResult result =
         codeOwnerResolverProvider
             .get()
-            .resolvePathCodeOwners(codeOwnerConfig, Paths.get("/README.md"));
+            .resolvePathCodeOwners(codeOwnerConfig, Path.of("/README.md"));
     assertThat(result.codeOwnersAccountIds()).containsExactly(admin.id(), user.id(), user2.id());
     assertThat(result.annotations().keySet())
         .containsExactly(CodeOwner.create(admin.id()), CodeOwner.create(user.id()));
@@ -480,7 +480,7 @@
     CodeOwnerResolverResult result =
         codeOwnerResolverProvider
             .get()
-            .resolvePathCodeOwners(codeOwnerConfig, Paths.get("/README.md"));
+            .resolvePathCodeOwners(codeOwnerConfig, Path.of("/README.md"));
     assertThat(result.codeOwnersAccountIds()).containsExactly(admin.id(), user.id());
     assertThat(result.annotations().keySet())
         .containsExactly(CodeOwner.create(admin.id()), CodeOwner.create(user.id()));
@@ -513,7 +513,7 @@
     CodeOwnerResolverResult result =
         codeOwnerResolverProvider
             .get()
-            .resolvePathCodeOwners(codeOwnerConfig, Paths.get("/README.md"));
+            .resolvePathCodeOwners(codeOwnerConfig, Path.of("/README.md"));
     assertThat(result.codeOwnersAccountIds()).containsExactly(user.id());
     assertThat(result.annotations().keySet()).containsExactly(CodeOwner.create(user.id()));
     assertThat(result.annotations().get(CodeOwner.create(user.id())))
@@ -528,7 +528,7 @@
             () ->
                 codeOwnerResolverProvider
                     .get()
-                    .resolvePathCodeOwners(/* codeOwnerConfig= */ null, Paths.get("/README.md")));
+                    .resolvePathCodeOwners(/* codeOwnerConfig= */ null, Path.of("/README.md")));
     assertThat(npe).hasMessageThat().isEqualTo("codeOwnerConfig");
   }
 
@@ -571,7 +571,7 @@
             () ->
                 codeOwnerResolverProvider
                     .get()
-                    .resolvePathCodeOwners(codeOwnerConfig, Paths.get(relativePath)));
+                    .resolvePathCodeOwners(codeOwnerConfig, Path.of(relativePath)));
     assertThat(npe)
         .hasMessageThat()
         .isEqualTo(String.format("path %s must be absolute", relativePath));
diff --git a/javatests/com/google/gerrit/plugins/codeowners/backend/CodeOwnerScoringTest.java b/javatests/com/google/gerrit/plugins/codeowners/backend/CodeOwnerScoringTest.java
index 43498c6..8c562c0 100644
--- a/javatests/com/google/gerrit/plugins/codeowners/backend/CodeOwnerScoringTest.java
+++ b/javatests/com/google/gerrit/plugins/codeowners/backend/CodeOwnerScoringTest.java
@@ -15,7 +15,6 @@
 package com.google.gerrit.plugins.codeowners.backend;
 
 import static com.google.common.truth.Truth.assertThat;
-import static com.google.common.truth.Truth8.assertThat;
 import static com.google.gerrit.testing.GerritJUnit.assertThrows;
 
 import com.google.gerrit.plugins.codeowners.acceptance.AbstractCodeOwnersTest;
diff --git a/javatests/com/google/gerrit/plugins/codeowners/backend/CodeOwnerSubmitRuleTest.java b/javatests/com/google/gerrit/plugins/codeowners/backend/CodeOwnerSubmitRuleTest.java
index a2470e6..08c45f1 100644
--- a/javatests/com/google/gerrit/plugins/codeowners/backend/CodeOwnerSubmitRuleTest.java
+++ b/javatests/com/google/gerrit/plugins/codeowners/backend/CodeOwnerSubmitRuleTest.java
@@ -15,7 +15,6 @@
 package com.google.gerrit.plugins.codeowners.backend;
 
 import static com.google.common.truth.Truth.assertThat;
-import static com.google.common.truth.Truth8.assertThat;
 import static com.google.gerrit.plugins.codeowners.testing.SubmitRecordSubject.assertThatOptional;
 import static com.google.gerrit.testing.GerritJUnit.assertThrows;
 import static org.mockito.Mockito.mock;
diff --git a/javatests/com/google/gerrit/plugins/codeowners/backend/CodeOwnersExceptionHookTest.java b/javatests/com/google/gerrit/plugins/codeowners/backend/CodeOwnersExceptionHookTest.java
index e1786d3..2f64510 100644
--- a/javatests/com/google/gerrit/plugins/codeowners/backend/CodeOwnersExceptionHookTest.java
+++ b/javatests/com/google/gerrit/plugins/codeowners/backend/CodeOwnersExceptionHookTest.java
@@ -15,13 +15,13 @@
 package com.google.gerrit.plugins.codeowners.backend;
 
 import static com.google.common.truth.Truth.assertThat;
-import static com.google.gerrit.truth.OptionalSubject.assertThat;
 
 import com.google.common.collect.ImmutableList;
 import com.google.gerrit.acceptance.config.GerritConfig;
 import com.google.gerrit.plugins.codeowners.acceptance.AbstractCodeOwnersTest;
 import com.google.gerrit.plugins.codeowners.backend.config.InvalidPluginConfigurationException;
 import com.google.gerrit.server.ExceptionHook.Status;
+import com.google.gerrit.truth.OptionalSubject;
 import java.nio.file.InvalidPathException;
 import java.util.Optional;
 import org.junit.Before;
@@ -114,29 +114,36 @@
   @Test
   public void getStatus() throws Exception {
     Status conflictStatus = Status.create(409, "Conflict");
-    assertThat(getStatus(newInvalidPluginConfigurationException()))
+    OptionalSubject.assertThat(getStatus(newInvalidPluginConfigurationException()))
         .value()
         .isEqualTo(conflictStatus);
-    assertThat(getStatus(newExceptionWithCause(newInvalidPluginConfigurationException())))
+    OptionalSubject.assertThat(
+            getStatus(newExceptionWithCause(newInvalidPluginConfigurationException())))
         .value()
         .isEqualTo(conflictStatus);
 
-    assertThat(getStatus(newInvalidCodeOwnerConfigException())).value().isEqualTo(conflictStatus);
-    assertThat(getStatus(newExceptionWithCause(newInvalidCodeOwnerConfigException())))
+    OptionalSubject.assertThat(getStatus(newInvalidCodeOwnerConfigException()))
+        .value()
+        .isEqualTo(conflictStatus);
+    OptionalSubject.assertThat(
+            getStatus(newExceptionWithCause(newInvalidCodeOwnerConfigException())))
         .value()
         .isEqualTo(conflictStatus);
 
-    assertThat(getStatus(newInvalidPathException())).value().isEqualTo(conflictStatus);
-    assertThat(getStatus(newExceptionWithCause(newInvalidPathException())))
+    OptionalSubject.assertThat(getStatus(newInvalidPathException()))
+        .value()
+        .isEqualTo(conflictStatus);
+    OptionalSubject.assertThat(getStatus(newExceptionWithCause(newInvalidPathException())))
         .value()
         .isEqualTo(conflictStatus);
 
-    assertThat(getStatus(new Exception())).isEmpty();
-    assertThat(getStatus(newExceptionWithCause(new Exception()))).isEmpty();
+    OptionalSubject.assertThat(getStatus(new Exception())).isEmpty();
+    OptionalSubject.assertThat(getStatus(newExceptionWithCause(new Exception()))).isEmpty();
 
-    assertThat(getStatus(CodeOwnersInternalServerErrorException.newInternalServerError("msg")))
+    OptionalSubject.assertThat(
+            getStatus(CodeOwnersInternalServerErrorException.newInternalServerError("msg")))
         .isEmpty();
-    assertThat(
+    OptionalSubject.assertThat(
             getStatus(
                 newExceptionWithCause(
                     CodeOwnersInternalServerErrorException.newInternalServerError("msg"))))
diff --git a/javatests/com/google/gerrit/plugins/codeowners/backend/CodeOwnersTest.java b/javatests/com/google/gerrit/plugins/codeowners/backend/CodeOwnersTest.java
index fafc620..294dfd0 100644
--- a/javatests/com/google/gerrit/plugins/codeowners/backend/CodeOwnersTest.java
+++ b/javatests/com/google/gerrit/plugins/codeowners/backend/CodeOwnersTest.java
@@ -16,7 +16,6 @@
 
 import static com.google.common.truth.Truth.assertThat;
 import static com.google.gerrit.testing.GerritJUnit.assertThrows;
-import static com.google.gerrit.truth.OptionalSubject.assertThat;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
@@ -26,6 +25,7 @@
 import com.google.gerrit.extensions.registration.PrivateInternals_DynamicMapImpl;
 import com.google.gerrit.extensions.registration.RegistrationHandle;
 import com.google.gerrit.plugins.codeowners.acceptance.AbstractCodeOwnersTest;
+import com.google.gerrit.truth.OptionalSubject;
 import com.google.inject.Key;
 import com.google.inject.util.Providers;
 import java.util.Optional;
@@ -92,7 +92,7 @@
     try (AutoCloseable registration = registerTestBackend("test-backend", codeOwnerBackendMock)) {
       Optional<CodeOwnerConfig> codeOwnerConfig =
           codeOwners.getFromCurrentRevision(codeOwnerConfigKey);
-      assertThat(codeOwnerConfig).value().isEqualTo(expectedCodeOwnersConfig);
+      OptionalSubject.assertThat(codeOwnerConfig).value().isEqualTo(expectedCodeOwnersConfig);
       verify(codeOwnerBackendMock).getCodeOwnerConfig(codeOwnerConfigKey, /* revision= */ null);
     }
   }
@@ -110,7 +110,7 @@
         .thenReturn(Optional.of(expectedCodeOwnersConfig));
     try (AutoCloseable registration = registerTestBackend("test-backend", codeOwnerBackendMock)) {
       Optional<CodeOwnerConfig> codeOwnerConfig = codeOwners.get(codeOwnerConfigKey, TEST_REVISION);
-      assertThat(codeOwnerConfig).value().isEqualTo(expectedCodeOwnersConfig);
+      OptionalSubject.assertThat(codeOwnerConfig).value().isEqualTo(expectedCodeOwnersConfig);
       verify(codeOwnerBackendMock).getCodeOwnerConfig(codeOwnerConfigKey, TEST_REVISION);
     }
   }
diff --git a/javatests/com/google/gerrit/plugins/codeowners/backend/PathCodeOwnersResultTest.java b/javatests/com/google/gerrit/plugins/codeowners/backend/PathCodeOwnersResultTest.java
index d9b3a71..a33835d 100644
--- a/javatests/com/google/gerrit/plugins/codeowners/backend/PathCodeOwnersResultTest.java
+++ b/javatests/com/google/gerrit/plugins/codeowners/backend/PathCodeOwnersResultTest.java
@@ -15,7 +15,7 @@
 package com.google.gerrit.plugins.codeowners.backend;
 
 import com.google.common.collect.ImmutableList;
-import java.nio.file.Paths;
+import java.nio.file.Path;
 import org.eclipse.jgit.lib.ObjectId;
 import org.junit.Test;
 
@@ -33,7 +33,7 @@
         CodeOwnerConfigReference.create(CodeOwnerConfigImportMode.ALL, "/baz/OWNERS");
     PathCodeOwnersResult pathCodeOwnersResult =
         PathCodeOwnersResult.create(
-            Paths.get("/foo/bar/baz.md"),
+            Path.of("/foo/bar/baz.md"),
             CodeOwnerConfig.builder(codeOwnerConfigKey, TEST_REVISION)
                 .addImport(resolvableCodeOwnerConfigReference)
                 .addImport(unresolvableCodeOwnerConfigReference)
diff --git a/javatests/com/google/gerrit/plugins/codeowners/backend/PathCodeOwnersTest.java b/javatests/com/google/gerrit/plugins/codeowners/backend/PathCodeOwnersTest.java
index bbae5bd..8927cdb 100644
--- a/javatests/com/google/gerrit/plugins/codeowners/backend/PathCodeOwnersTest.java
+++ b/javatests/com/google/gerrit/plugins/codeowners/backend/PathCodeOwnersTest.java
@@ -15,7 +15,6 @@
 package com.google.gerrit.plugins.codeowners.backend;
 
 import static com.google.common.truth.Truth.assertThat;
-import static com.google.common.truth.Truth8.assertThat;
 import static com.google.gerrit.plugins.codeowners.testing.CodeOwnerSetSubject.hasEmail;
 import static com.google.gerrit.testing.GerritJUnit.assertThrows;
 import static org.mockito.ArgumentMatchers.any;
@@ -45,7 +44,6 @@
 import com.google.inject.Provider;
 import com.google.inject.util.Providers;
 import java.nio.file.Path;
-import java.nio.file.Paths;
 import java.util.Optional;
 import org.eclipse.jgit.lib.ObjectId;
 import org.eclipse.jgit.revwalk.RevCommit;
@@ -78,7 +76,7 @@
   public void createPathCodeOwnersForCodeOwnerConfig() throws Exception {
     PathCodeOwners pathCodeOwners =
         pathCodeOwnersFactory.createWithoutCache(
-            createCodeOwnerBuilder().build(), Paths.get("/foo/bar/baz.md"));
+            createCodeOwnerBuilder().build(), Path.of("/foo/bar/baz.md"));
     assertThat(pathCodeOwners).isNotNull();
   }
 
@@ -89,7 +87,7 @@
             NullPointerException.class,
             () ->
                 pathCodeOwnersFactory.createWithoutCache(
-                    /* codeOwnerConfig= */ null, Paths.get("/foo/bar/baz.md")));
+                    /* codeOwnerConfig= */ null, Path.of("/foo/bar/baz.md")));
     assertThat(npe).hasMessageThat().isEqualTo("codeOwnerConfig");
   }
 
@@ -112,8 +110,7 @@
     IllegalStateException exception =
         assertThrows(
             IllegalStateException.class,
-            () ->
-                pathCodeOwnersFactory.createWithoutCache(codeOwnerConfig, Paths.get(relativePath)));
+            () -> pathCodeOwnersFactory.createWithoutCache(codeOwnerConfig, Path.of(relativePath)));
     assertThat(exception)
         .hasMessageThat()
         .isEqualTo(String.format("path %s must be absolute", relativePath));
@@ -135,7 +132,7 @@
             transientCodeOwnerConfigCacheProvider.get(),
             codeOwnerConfigKey,
             projectOperations.project(project).getHead("master"),
-            Paths.get("/foo/bar/baz.md"));
+            Path.of("/foo/bar/baz.md"));
     assertThat(pathCodeOwners).isPresent();
   }
 
@@ -148,9 +145,9 @@
                 pathCodeOwnersFactory.create(
                     /* transientCodeOwnerConfigCache= */ null,
                     CodeOwnerConfig.Key.create(
-                        BranchNameKey.create(project, "master"), Paths.get("/")),
+                        BranchNameKey.create(project, "master"), Path.of("/")),
                     projectOperations.project(project).getHead("master"),
-                    Paths.get("/foo/bar/baz.md")));
+                    Path.of("/foo/bar/baz.md")));
     assertThat(npe).hasMessageThat().isEqualTo("transientCodeOwnerConfigCache");
   }
 
@@ -164,7 +161,7 @@
                     transientCodeOwnerConfigCacheProvider.get(),
                     /* codeOwnerConfigKey= */ null,
                     projectOperations.project(project).getHead("master"),
-                    Paths.get("/foo/bar/baz.md")));
+                    Path.of("/foo/bar/baz.md")));
     assertThat(npe).hasMessageThat().isEqualTo("codeOwnerConfigKey");
   }
 
@@ -177,9 +174,9 @@
                 pathCodeOwnersFactory.create(
                     transientCodeOwnerConfigCacheProvider.get(),
                     CodeOwnerConfig.Key.create(
-                        BranchNameKey.create(project, "master"), Paths.get("/")),
+                        BranchNameKey.create(project, "master"), Path.of("/")),
                     /* revision= */ null,
-                    Paths.get("/foo/bar/baz.md")));
+                    Path.of("/foo/bar/baz.md")));
     assertThat(npe).hasMessageThat().isEqualTo("revision");
   }
 
@@ -226,7 +223,7 @@
                     transientCodeOwnerConfigCacheProvider.get(),
                     codeOwnerConfigKey,
                     projectOperations.project(project).getHead("master"),
-                    Paths.get(relativePath)));
+                    Path.of(relativePath)));
     assertThat(exception)
         .hasMessageThat()
         .isEqualTo(String.format("path %s must be absolute", relativePath));
@@ -236,8 +233,7 @@
   public void getEmptyPathCodeOwners() throws Exception {
     CodeOwnerConfig emptyCodeOwnerConfig = createCodeOwnerBuilder().build();
     PathCodeOwners pathCodeOwners =
-        pathCodeOwnersFactory.createWithoutCache(
-            emptyCodeOwnerConfig, Paths.get("/foo/bar/baz.md"));
+        pathCodeOwnersFactory.createWithoutCache(emptyCodeOwnerConfig, Path.of("/foo/bar/baz.md"));
     assertThat(pathCodeOwners.resolveCodeOwnerConfig().get().getPathCodeOwners()).isEmpty();
     assertThat(pathCodeOwners.resolveCodeOwnerConfig().get().resolvedImports()).isEmpty();
     assertThat(pathCodeOwners.resolveCodeOwnerConfig().get().unresolvedImports()).isEmpty();
@@ -250,7 +246,7 @@
             .addCodeOwnerSet(CodeOwnerSet.createWithoutPathExpressions(admin.email(), user.email()))
             .build();
     PathCodeOwners pathCodeOwners =
-        pathCodeOwnersFactory.createWithoutCache(codeOwnerConfig, Paths.get("/foo/bar/baz.md"));
+        pathCodeOwnersFactory.createWithoutCache(codeOwnerConfig, Path.of("/foo/bar/baz.md"));
     assertThat(pathCodeOwners.resolveCodeOwnerConfig().get().getPathCodeOwners())
         .comparingElementsUsing(hasEmail())
         .containsExactly(admin.email(), user.email());
@@ -288,7 +284,7 @@
               .addCodeOwnerSet(nonMatchingCodeOwnerSet)
               .build();
       PathCodeOwners pathCodeOwners =
-          pathCodeOwnersFactory.createWithoutCache(codeOwnerConfig, Paths.get("/foo/bar/baz.md"));
+          pathCodeOwnersFactory.createWithoutCache(codeOwnerConfig, Path.of("/foo/bar/baz.md"));
       assertThat(pathCodeOwners.resolveCodeOwnerConfig().get().getPathCodeOwners())
           .comparingElementsUsing(hasEmail())
           .containsExactly(admin.email(), user.email());
@@ -309,7 +305,7 @@
                       .build())
               .build();
       PathCodeOwners pathCodeOwners =
-          pathCodeOwnersFactory.createWithoutCache(codeOwnerConfig, Paths.get("/foo/bar/baz.md"));
+          pathCodeOwnersFactory.createWithoutCache(codeOwnerConfig, Path.of("/foo/bar/baz.md"));
       assertThat(pathCodeOwners.resolveCodeOwnerConfig().get().getPathCodeOwners()).isEmpty();
     }
   }
@@ -341,7 +337,7 @@
               .addCodeOwnerSet(globalCodeOwnerSet)
               .build();
       PathCodeOwners pathCodeOwners =
-          pathCodeOwnersFactory.createWithoutCache(codeOwnerConfig, Paths.get("/foo/bar/baz.md"));
+          pathCodeOwnersFactory.createWithoutCache(codeOwnerConfig, Path.of("/foo/bar/baz.md"));
       assertThat(pathCodeOwners.resolveCodeOwnerConfig().get().getPathCodeOwners())
           .comparingElementsUsing(hasEmail())
           .containsExactly(admin.email());
@@ -375,7 +371,7 @@
               .addCodeOwnerSet(globalCodeOwnerSet)
               .build();
       PathCodeOwners pathCodeOwners =
-          pathCodeOwnersFactory.createWithoutCache(codeOwnerConfig, Paths.get("/foo/bar/baz.md"));
+          pathCodeOwnersFactory.createWithoutCache(codeOwnerConfig, Path.of("/foo/bar/baz.md"));
       assertThat(pathCodeOwners.resolveCodeOwnerConfig().get().getPathCodeOwners())
           .comparingElementsUsing(hasEmail())
           .containsExactly(admin.email(), user.email());
@@ -410,7 +406,7 @@
               .addCodeOwnerSet(perFileCodeOwnerSet2)
               .build();
       PathCodeOwners pathCodeOwners =
-          pathCodeOwnersFactory.createWithoutCache(codeOwnerConfig, Paths.get("/foo/bar/baz.md"));
+          pathCodeOwnersFactory.createWithoutCache(codeOwnerConfig, Path.of("/foo/bar/baz.md"));
       assertThat(pathCodeOwners.resolveCodeOwnerConfig().get().getPathCodeOwners())
           .comparingElementsUsing(hasEmail())
           .containsExactly(admin.email(), user.email());
@@ -423,7 +419,7 @@
     PathCodeOwners pathCodeOwners =
         pathCodeOwnersFactory.createWithoutCache(
             createCodeOwnerBuilder().setIgnoreParentCodeOwners().build(),
-            Paths.get("/foo/bar/baz.md"));
+            Path.of("/foo/bar/baz.md"));
     assertThat(pathCodeOwners.resolveCodeOwnerConfig().get().ignoreParentCodeOwners()).isTrue();
   }
 
@@ -433,7 +429,7 @@
     PathCodeOwners pathCodeOwners =
         pathCodeOwnersFactory.createWithoutCache(
             createCodeOwnerBuilder().setIgnoreParentCodeOwners(false).build(),
-            Paths.get("/foo/bar/baz.md"));
+            Path.of("/foo/bar/baz.md"));
     assertThat(pathCodeOwners.resolveCodeOwnerConfig().get().ignoreParentCodeOwners()).isFalse();
   }
 
@@ -449,7 +445,7 @@
                         .addPathExpression("*.md")
                         .build())
                 .build(),
-            Paths.get("/foo.md"));
+            Path.of("/foo.md"));
     assertThat(pathCodeOwners.resolveCodeOwnerConfig().get().ignoreParentCodeOwners()).isTrue();
   }
 
@@ -466,7 +462,7 @@
                         .addPathExpression("*.txt")
                         .build())
                 .build(),
-            Paths.get("/foo.md"));
+            Path.of("/foo.md"));
     assertThat(pathCodeOwners.resolveCodeOwnerConfig().get().ignoreParentCodeOwners()).isFalse();
   }
 
@@ -493,7 +489,7 @@
             transientCodeOwnerConfigCacheProvider.get(),
             importingCodeOwnerConfigKey,
             projectOperations.project(project).getHead("master"),
-            Paths.get("/foo.md"));
+            Path.of("/foo.md"));
     assertThat(pathCodeOwners).isPresent();
 
     // Expectation: we get the global code owner from the importing code owner config, the
@@ -549,7 +545,7 @@
             transientCodeOwnerConfigCacheProvider.get(),
             importingCodeOwnerConfigKey,
             projectOperations.project(project).getHead("master"),
-            Paths.get("/foo.md"));
+            Path.of("/foo.md"));
     assertThat(pathCodeOwners).isPresent();
 
     // Expectation: we get the global code owner from the importing code owner config, the
@@ -608,7 +604,7 @@
             transientCodeOwnerConfigCacheProvider.get(),
             importingCodeOwnerConfigKey,
             projectOperations.project(project).getHead("master"),
-            Paths.get("/foo.md"));
+            Path.of("/foo.md"));
     assertThat(pathCodeOwners).isPresent();
 
     // Expectation: we get the global code owner from the importing code owner config, the
@@ -669,7 +665,7 @@
             transientCodeOwnerConfigCacheProvider.get(),
             importingCodeOwnerConfigKey,
             projectOperations.project(project).getHead("master"),
-            Paths.get("/foo.md"));
+            Path.of("/foo.md"));
     assertThat(pathCodeOwners).isPresent();
 
     // Expectation: we get the global code owner from the importing code owner config and the global
@@ -727,7 +723,7 @@
             transientCodeOwnerConfigCacheProvider.get(),
             importingCodeOwnerConfigKey,
             projectOperations.project(project).getHead("master"),
-            Paths.get("/foo.md"));
+            Path.of("/foo.md"));
     assertThat(pathCodeOwners).isPresent();
 
     // Expectation: we get the global code owners from the importing and the imported code owner
@@ -784,7 +780,7 @@
             transientCodeOwnerConfigCacheProvider.get(),
             importingCodeOwnerConfigKey,
             projectOperations.project(project).getHead("master"),
-            Paths.get("/foo.md"));
+            Path.of("/foo.md"));
     assertThat(pathCodeOwners).isPresent();
 
     // Expectation: we get the matching per-file code owners from the importing and the imported
@@ -841,7 +837,7 @@
             transientCodeOwnerConfigCacheProvider.get(),
             importingCodeOwnerConfigKey,
             projectOperations.project(project).getHead("master"),
-            Paths.get("/foo.md"));
+            Path.of("/foo.md"));
     assertThat(pathCodeOwners).isPresent();
 
     // Expectation: we only get the matching per-file code owners from the importing code owner
@@ -900,7 +896,7 @@
             transientCodeOwnerConfigCacheProvider.get(),
             importingCodeOwnerConfigKey,
             projectOperations.project(project).getHead("master"),
-            Paths.get("/foo.md"));
+            Path.of("/foo.md"));
     assertThat(pathCodeOwners).isPresent();
 
     // Expectation: we only get the matching per-file code owners from the importing code owner
@@ -958,7 +954,7 @@
             transientCodeOwnerConfigCacheProvider.get(),
             importingCodeOwnerConfigKey,
             projectOperations.project(project).getHead("master"),
-            Paths.get("/foo.md"));
+            Path.of("/foo.md"));
     assertThat(pathCodeOwners).isPresent();
 
     // Expectation: we only get the matching per-file code owners from the imported code owner
@@ -1019,7 +1015,7 @@
             transientCodeOwnerConfigCacheProvider.get(),
             importingCodeOwnerConfigKey,
             projectOperations.project(project).getHead("master"),
-            Paths.get("/foo.md"));
+            Path.of("/foo.md"));
     assertThat(pathCodeOwners).isPresent();
 
     // Expectation: we only get the global code owners from the importing code owner config, the
@@ -1079,7 +1075,7 @@
             transientCodeOwnerConfigCacheProvider.get(),
             importingCodeOwnerConfigKey,
             projectOperations.project(project).getHead("master"),
-            Paths.get("/foo.md"));
+            Path.of("/foo.md"));
     assertThat(pathCodeOwners).isPresent();
 
     // Expectation: we only get the global code owners from the importing code owner config, the
@@ -1131,7 +1127,7 @@
             transientCodeOwnerConfigCacheProvider.get(),
             importingCodeOwnerConfigKey,
             projectOperations.project(project).getHead("master"),
-            Paths.get("/foo.md"));
+            Path.of("/foo.md"));
     assertThat(pathCodeOwners).isPresent();
 
     // Expectation: ignoreParentCodeOwners is true because the ignoreParentCodeOwners flag in the
@@ -1180,7 +1176,7 @@
             transientCodeOwnerConfigCacheProvider.get(),
             importingCodeOwnerConfigKey,
             projectOperations.project(project).getHead("master"),
-            Paths.get("/foo.md"));
+            Path.of("/foo.md"));
     assertThat(pathCodeOwners).isPresent();
 
     // Expectation: ignoreParentCodeOwners is false because the ignoreParentCodeOwners flag in the
@@ -1255,7 +1251,7 @@
             transientCodeOwnerConfigCacheProvider.get(),
             importingCodeOwnerConfigKey,
             projectOperations.project(project).getHead("master"),
-            Paths.get("/foo.md"));
+            Path.of("/foo.md"));
     assertThat(pathCodeOwners).isPresent();
 
     // Expectation: we get the global owners from the importing code owner config, the imported code
@@ -1332,7 +1328,7 @@
             transientCodeOwnerConfigCacheProvider.get(),
             importingCodeOwnerConfigKey,
             projectOperations.project(project).getHead("master"),
-            Paths.get("/foo.md"));
+            Path.of("/foo.md"));
     assertThat(pathCodeOwners).isPresent();
 
     // Expectation: we get the global owners from the importing code owner config and the imported
@@ -1410,7 +1406,7 @@
             transientCodeOwnerConfigCacheProvider.get(),
             importingCodeOwnerConfigKey,
             projectOperations.project(project).getHead("master"),
-            Paths.get("/foo.md"));
+            Path.of("/foo.md"));
     assertThat(pathCodeOwners).isPresent();
 
     // Expectation: we get the global code owners from the importing and the imported code owner
@@ -1464,7 +1460,7 @@
             transientCodeOwnerConfigCacheProvider.get(),
             importingCodeOwnerConfigKey,
             projectOperations.project(project).getHead("master"),
-            Paths.get("/foo.md"));
+            Path.of("/foo.md"));
     assertThat(pathCodeOwners).isPresent();
 
     // Expectation: we get the global owners from the importing and the imported code owner config
@@ -1526,7 +1522,7 @@
             transientCodeOwnerConfigCacheProvider.get(),
             rootCodeOwnerConfigKey,
             oldRevision,
-            Paths.get("/foo.md"));
+            Path.of("/foo.md"));
     assertThat(pathCodeOwners).isPresent();
 
     // Expectation: we get the global owners from the importing and the imported code owner config
@@ -1567,7 +1563,7 @@
             transientCodeOwnerConfigCacheProvider.get(),
             importingCodeOwnerConfigKey,
             projectOperations.project(project).getHead("master"),
-            Paths.get("/foo/bar/baz.md"));
+            Path.of("/foo/bar/baz.md"));
     assertThat(pathCodeOwners).isPresent();
 
     // Expectation: we get the global owners from the importing and the imported code owner config
@@ -1607,7 +1603,7 @@
             transientCodeOwnerConfigCacheProvider.get(),
             importingCodeOwnerConfigKey,
             projectOperations.project(project).getHead("master"),
-            Paths.get("/foo/bar/baz.md"));
+            Path.of("/foo/bar/baz.md"));
     assertThat(pathCodeOwners).isPresent();
 
     // Expectation: we get the global owners from the importing code owner config
@@ -1660,7 +1656,7 @@
             transientCodeOwnerConfigCacheProvider.get(),
             importingCodeOwnerConfigKey,
             projectOperations.project(project).getHead("master"),
-            Paths.get("/foo/bar/baz.md"));
+            Path.of("/foo/bar/baz.md"));
     assertThat(pathCodeOwners).isPresent();
 
     // Expectation: we get the global owners from the importing code owner config, the global code
@@ -1705,7 +1701,7 @@
             transientCodeOwnerConfigCacheProvider.get(),
             importingCodeOwnerConfigKey,
             projectOperations.project(project).getHead("master"),
-            Paths.get("/foo/bar/baz.md"));
+            Path.of("/foo/bar/baz.md"));
     assertThat(pathCodeOwners).isPresent();
 
     // Expectation: we get the global owners from the importing code owner config
@@ -1756,7 +1752,7 @@
             transientCodeOwnerConfigCacheProvider.get(),
             importingCodeOwnerConfigKey,
             projectOperations.project(project).getHead("master"),
-            Paths.get("/foo/bar/baz.md"));
+            Path.of("/foo/bar/baz.md"));
     assertThat(pathCodeOwners).isPresent();
 
     // Expectation: we get the global owners from the importing and the imported code owner config
@@ -1815,7 +1811,7 @@
             transientCodeOwnerConfigCacheProvider.get(),
             importingCodeOwnerConfigKey,
             projectOperations.project(project).getHead(branchName),
-            Paths.get("/foo.md"));
+            Path.of("/foo.md"));
     assertThat(pathCodeOwners).isPresent();
 
     // Expectation: we get the global owners from the importing and the imported code owner config
@@ -1867,7 +1863,7 @@
             transientCodeOwnerConfigCacheProvider.get(),
             importingCodeOwnerConfigKey,
             projectOperations.project(project).getHead("master"),
-            Paths.get("/foo/bar/baz.md"));
+            Path.of("/foo/bar/baz.md"));
     assertThat(pathCodeOwners).isPresent();
 
     // Expectation: we get the global owners from the importing and the imported code owner config
@@ -1921,7 +1917,7 @@
             transientCodeOwnerConfigCacheProvider.get(),
             importingCodeOwnerConfigKey,
             projectOperations.project(project).getHead("master"),
-            Paths.get("/foo/bar/baz.md"));
+            Path.of("/foo/bar/baz.md"));
     assertThat(pathCodeOwners).isPresent();
 
     // Expectation: we get the global owners from the importing and the imported code owner config
@@ -1966,7 +1962,7 @@
             transientCodeOwnerConfigCacheProvider.get(),
             importingCodeOwnerConfigKey,
             projectOperations.project(project).getHead("master"),
-            Paths.get("/foo.md"));
+            Path.of("/foo.md"));
     assertThat(pathCodeOwners).isPresent();
 
     // Expectation: we get the per file code owner from the importing code owner config, the
@@ -2035,7 +2031,7 @@
             transientCodeOwnerConfigCacheProvider.get(),
             importingCodeOwnerConfigKey,
             projectOperations.project(project).getHead("master"),
-            Paths.get("/foo.md"));
+            Path.of("/foo.md"));
     assertThat(pathCodeOwners).isPresent();
 
     // Expectation: we get the per file code owners from the importing and the global code owner
@@ -2111,7 +2107,7 @@
             transientCodeOwnerConfigCacheProvider.get(),
             importingCodeOwnerConfigKey,
             projectOperations.project(project).getHead("master"),
-            Paths.get("/foo.md"));
+            Path.of("/foo.md"));
     assertThat(pathCodeOwners).isPresent();
 
     // Expectation: we get the global owners from the importing code owner config, the imported code
@@ -2189,7 +2185,7 @@
             transientCodeOwnerConfigCacheProvider.get(),
             importingCodeOwnerConfigKey,
             projectOperations.project(project).getHead("master"),
-            Paths.get("/foo.md"));
+            Path.of("/foo.md"));
     assertThat(pathCodeOwners).isPresent();
 
     // Expectation: we get the global owners from the importing code owner config and the imported
@@ -2286,7 +2282,7 @@
             transientCodeOwnerConfigCacheProvider.get(),
             importingCodeOwnerConfigKey,
             projectOperations.project(project).getHead("master"),
-            Paths.get("/foo.xyz"));
+            Path.of("/foo.xyz"));
     assertThat(pathCodeOwners).isPresent();
     PathCodeOwnersResult pathCodeOwnersResult = pathCodeOwners.get().resolveCodeOwnerConfig().get();
     assertThat(pathCodeOwnersResult.getPathCodeOwners()).isEmpty();
@@ -2304,7 +2300,7 @@
             transientCodeOwnerConfigCacheProvider.get(),
             importingCodeOwnerConfigKey,
             projectOperations.project(project).getHead("master"),
-            Paths.get("/foo.md"));
+            Path.of("/foo.md"));
     assertThat(pathCodeOwners).isPresent();
     pathCodeOwnersResult = pathCodeOwners.get().resolveCodeOwnerConfig().get();
     assertThat(pathCodeOwnersResult.getPathCodeOwners())
@@ -2329,7 +2325,7 @@
             transientCodeOwnerConfigCacheProvider.get(),
             importingCodeOwnerConfigKey,
             projectOperations.project(project).getHead("master"),
-            Paths.get("/foo.txt"));
+            Path.of("/foo.txt"));
     assertThat(pathCodeOwners).isPresent();
     pathCodeOwnersResult = pathCodeOwners.get().resolveCodeOwnerConfig().get();
     assertThat(pathCodeOwnersResult.getPathCodeOwners())
@@ -2355,7 +2351,7 @@
             () ->
                 PathCodeOwners.matches(
                     /* codeOwnerSet= */ null,
-                    Paths.get("bar/baz.md"),
+                    Path.of("bar/baz.md"),
                     mock(PathExpressionMatcher.class)));
     assertThat(npe).hasMessageThat().isEqualTo("codeOwnerSet");
   }
@@ -2382,7 +2378,7 @@
             () ->
                 PathCodeOwners.matches(
                     CodeOwnerSet.createWithoutPathExpressions(admin.email()),
-                    Paths.get(absolutePath),
+                    Path.of(absolutePath),
                     mock(PathExpressionMatcher.class)));
     assertThat(exception)
         .hasMessageThat()
@@ -2397,7 +2393,7 @@
             () ->
                 PathCodeOwners.matches(
                     CodeOwnerSet.createWithoutPathExpressions(admin.email()),
-                    Paths.get("bar/baz.md"),
+                    Path.of("bar/baz.md"),
                     /* matcher= */ null));
     assertThat(npe).hasMessageThat().isEqualTo("matcher");
   }
@@ -2411,7 +2407,7 @@
             () ->
                 PathCodeOwners.matches(
                     CodeOwnerSet.createWithoutPathExpressions(admin.email()),
-                    Paths.get("bar/baz.md"),
+                    Path.of("bar/baz.md"),
                     pathExpressionMatcher));
     assertThat(exception).hasMessageThat().isEqualTo("code owner set must have path expressions");
   }
@@ -2426,7 +2422,7 @@
                     .addPathExpression("*.md")
                     .addCodeOwnerEmail(admin.email())
                     .build(),
-                Paths.get("bar/baz.md"),
+                Path.of("bar/baz.md"),
                 pathExpressionMatcher))
         .isTrue();
   }
@@ -2441,7 +2437,7 @@
                     .addPathExpression("*.md")
                     .addCodeOwnerEmail(admin.email())
                     .build(),
-                Paths.get("bar/baz.md"),
+                Path.of("bar/baz.md"),
                 pathExpressionMatcher))
         .isFalse();
   }
@@ -2460,7 +2456,7 @@
                     .addPathExpression("build/*")
                     .addCodeOwnerEmail(admin.email())
                     .build(),
-                Paths.get("bar/baz.md"),
+                Path.of("bar/baz.md"),
                 pathExpressionMatcher))
         .isTrue();
   }
@@ -2506,7 +2502,7 @@
             transientCodeOwnerConfigCacheProvider.get(),
             importingCodeOwnerConfigKey,
             projectOperations.project(project).getHead("master"),
-            Paths.get("/foo.md"));
+            Path.of("/foo.md"));
     assertThat(pathCodeOwners).isPresent();
 
     // Expectation: we get the global code owner from the imported code owner config (since it is
@@ -2574,7 +2570,7 @@
             transientCodeOwnerConfigCacheProvider.get(),
             importingCodeOwnerConfigKey,
             projectOperations.project(project).getHead("master"),
-            Paths.get("/foo.md"));
+            Path.of("/foo.md"));
     assertThat(pathCodeOwners).isPresent();
 
     // Expectation: we get the code owner from the matching per-file rule in the importing code
@@ -2645,7 +2641,7 @@
             transientCodeOwnerConfigCacheProvider.get(),
             importingCodeOwnerConfigKey,
             projectOperations.project(project).getHead("master"),
-            Paths.get("/foo.md"));
+            Path.of("/foo.md"));
     assertThat(pathCodeOwners).isPresent();
 
     // Expectation: we get the global owners from the importing code owner config and from the
@@ -2718,7 +2714,7 @@
             transientCodeOwnerConfigCacheProvider.get(),
             importingCodeOwnerConfigKey,
             projectOperations.project(project).getHead("master"),
-            Paths.get("/foo.md"));
+            Path.of("/foo.md"));
     assertThat(pathCodeOwners).isPresent();
 
     // Expectation: we get the global owners from the importing code owner config and from the
@@ -2742,7 +2738,7 @@
 
   private CodeOwnerConfig.Builder createCodeOwnerBuilder() {
     return CodeOwnerConfig.builder(
-        CodeOwnerConfig.Key.create(BranchNameKey.create(project, "master"), Paths.get("/")),
+        CodeOwnerConfig.Key.create(BranchNameKey.create(project, "master"), Path.of("/")),
         ObjectId.fromString("deadbeefdeadbeefdeadbeefdeadbeefdeadbeef"));
   }
 
diff --git a/javatests/com/google/gerrit/plugins/codeowners/backend/config/BackendConfigTest.java b/javatests/com/google/gerrit/plugins/codeowners/backend/config/BackendConfigTest.java
index dcc9cb3..fffc267 100644
--- a/javatests/com/google/gerrit/plugins/codeowners/backend/config/BackendConfigTest.java
+++ b/javatests/com/google/gerrit/plugins/codeowners/backend/config/BackendConfigTest.java
@@ -19,7 +19,6 @@
 import static com.google.gerrit.plugins.codeowners.backend.config.BackendConfig.KEY_PATH_EXPRESSIONS;
 import static com.google.gerrit.plugins.codeowners.backend.config.CodeOwnersPluginConfiguration.SECTION_CODE_OWNERS;
 import static com.google.gerrit.testing.GerritJUnit.assertThrows;
-import static com.google.gerrit.truth.OptionalSubject.assertThat;
 
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Iterables;
@@ -32,6 +31,7 @@
 import com.google.gerrit.plugins.codeowners.backend.proto.ProtoBackend;
 import com.google.gerrit.server.git.validators.CommitValidationMessage;
 import com.google.gerrit.server.git.validators.ValidationMessage;
+import com.google.gerrit.truth.OptionalSubject;
 import org.eclipse.jgit.lib.Config;
 import org.junit.Before;
 import org.junit.Test;
@@ -65,7 +65,7 @@
 
   @Test
   public void getBackendForBranchWhenBackendIsNotSet() throws Exception {
-    assertThat(
+    OptionalSubject.assertThat(
             backendConfig.getBackendForBranch(
                 new Config(), BranchNameKey.create(project, "master")))
         .isEmpty();
@@ -79,7 +79,8 @@
         "refs/heads/master",
         KEY_BACKEND,
         CodeOwnerBackendId.FIND_OWNERS.getBackendId());
-    assertThat(backendConfig.getBackendForBranch(cfg, BranchNameKey.create(project, "master")))
+    OptionalSubject.assertThat(
+            backendConfig.getBackendForBranch(cfg, BranchNameKey.create(project, "master")))
         .value()
         .isInstanceOf(FindOwnersBackend.class);
   }
@@ -89,7 +90,8 @@
     Config cfg = new Config();
     cfg.setString(
         SECTION_CODE_OWNERS, "master", KEY_BACKEND, CodeOwnerBackendId.FIND_OWNERS.getBackendId());
-    assertThat(backendConfig.getBackendForBranch(cfg, BranchNameKey.create(project, "master")))
+    OptionalSubject.assertThat(
+            backendConfig.getBackendForBranch(cfg, BranchNameKey.create(project, "master")))
         .value()
         .isInstanceOf(FindOwnersBackend.class);
   }
@@ -131,7 +133,7 @@
 
   @Test
   public void getBackendForProjectWhenBackendIsNotSet() throws Exception {
-    assertThat(backendConfig.getBackendForProject(new Config(), project)).isEmpty();
+    OptionalSubject.assertThat(backendConfig.getBackendForProject(new Config(), project)).isEmpty();
   }
 
   @Test
@@ -139,7 +141,7 @@
     Config cfg = new Config();
     cfg.setString(
         SECTION_CODE_OWNERS, null, KEY_BACKEND, CodeOwnerBackendId.FIND_OWNERS.getBackendId());
-    assertThat(backendConfig.getBackendForProject(cfg, project))
+    OptionalSubject.assertThat(backendConfig.getBackendForProject(cfg, project))
         .value()
         .isInstanceOf(FindOwnersBackend.class);
   }
@@ -209,7 +211,7 @@
 
   @Test
   public void getPathExpressionsForBranchWhenPathExpressionsAreNotSet() throws Exception {
-    assertThat(
+    OptionalSubject.assertThat(
             backendConfig.getPathExpressionsForBranch(
                 new Config(), BranchNameKey.create(project, "master")))
         .isEmpty();
@@ -223,7 +225,7 @@
         "refs/heads/master",
         KEY_PATH_EXPRESSIONS,
         PathExpressions.GLOB.name());
-    assertThat(
+    OptionalSubject.assertThat(
             backendConfig.getPathExpressionsForBranch(cfg, BranchNameKey.create(project, "master")))
         .value()
         .isEqualTo(PathExpressions.GLOB);
@@ -233,7 +235,7 @@
   public void getPathExpressionsForBranchShortName() throws Exception {
     Config cfg = new Config();
     cfg.setString(SECTION_CODE_OWNERS, "master", KEY_PATH_EXPRESSIONS, PathExpressions.GLOB.name());
-    assertThat(
+    OptionalSubject.assertThat(
             backendConfig.getPathExpressionsForBranch(cfg, BranchNameKey.create(project, "master")))
         .value()
         .isEqualTo(PathExpressions.GLOB);
@@ -243,7 +245,7 @@
   public void getPathExpressionsForBranchIfConfigIsInvalid() throws Exception {
     Config cfg = new Config();
     cfg.setString(SECTION_CODE_OWNERS, "master", KEY_PATH_EXPRESSIONS, "INVALID");
-    assertThat(
+    OptionalSubject.assertThat(
             backendConfig.getPathExpressionsForBranch(cfg, BranchNameKey.create(project, "master")))
         .isEmpty();
   }
@@ -268,14 +270,15 @@
 
   @Test
   public void getPathExpressionsForProjectWhenBackendIsNotSet() throws Exception {
-    assertThat(backendConfig.getPathExpressionsForProject(new Config(), project)).isEmpty();
+    OptionalSubject.assertThat(backendConfig.getPathExpressionsForProject(new Config(), project))
+        .isEmpty();
   }
 
   @Test
   public void getPathExpressionsForProject() throws Exception {
     Config cfg = new Config();
     cfg.setString(SECTION_CODE_OWNERS, null, KEY_PATH_EXPRESSIONS, PathExpressions.GLOB.name());
-    assertThat(backendConfig.getPathExpressionsForProject(cfg, project))
+    OptionalSubject.assertThat(backendConfig.getPathExpressionsForProject(cfg, project))
         .value()
         .isEqualTo(PathExpressions.GLOB);
   }
@@ -284,7 +287,7 @@
   public void getPathExpressionsForProjectIfConfigIsInvalid() throws Exception {
     Config cfg = new Config();
     cfg.setString(SECTION_CODE_OWNERS, null, KEY_PATH_EXPRESSIONS, "INVALID");
-    assertThat(backendConfig.getPathExpressionsForProject(cfg, project)).isEmpty();
+    OptionalSubject.assertThat(backendConfig.getPathExpressionsForProject(cfg, project)).isEmpty();
   }
 
   @Test
@@ -307,19 +310,21 @@
 
   @Test
   public void getDefaultPathExpressions() throws Exception {
-    assertThat(backendConfig.getDefaultPathExpressions()).isEmpty();
+    OptionalSubject.assertThat(backendConfig.getDefaultPathExpressions()).isEmpty();
   }
 
   @Test
   @GerritConfig(name = "plugin.code-owners.pathExpressions", value = "GLOB")
   public void getConfiguredDefaultPathExpressions() throws Exception {
-    assertThat(backendConfig.getDefaultPathExpressions()).value().isEqualTo(PathExpressions.GLOB);
+    OptionalSubject.assertThat(backendConfig.getDefaultPathExpressions())
+        .value()
+        .isEqualTo(PathExpressions.GLOB);
   }
 
   @Test
   @GerritConfig(name = "plugin.code-owners.pathExpressions", value = "INVALID")
   public void getDefaultPathExpressionsIfConfigIsInvalid() throws Exception {
-    assertThat(backendConfig.getDefaultPathExpressions()).isEmpty();
+    OptionalSubject.assertThat(backendConfig.getDefaultPathExpressions()).isEmpty();
   }
 
   @Test
diff --git a/javatests/com/google/gerrit/plugins/codeowners/backend/config/CodeOwnersPluginConfigValidatorTest.java b/javatests/com/google/gerrit/plugins/codeowners/backend/config/CodeOwnersPluginConfigValidatorTest.java
index d712ba4..c3dece0 100644
--- a/javatests/com/google/gerrit/plugins/codeowners/backend/config/CodeOwnersPluginConfigValidatorTest.java
+++ b/javatests/com/google/gerrit/plugins/codeowners/backend/config/CodeOwnersPluginConfigValidatorTest.java
@@ -23,11 +23,16 @@
 import com.google.gerrit.plugins.codeowners.backend.FallbackCodeOwners;
 import com.google.gerrit.server.events.CommitReceivedEvent;
 import com.google.gerrit.server.git.validators.CommitValidationException;
+import com.google.gerrit.server.patch.DiffOperationsForCommitValidation;
+import com.google.gerrit.server.update.RepoView;
 import org.eclipse.jgit.errors.ConfigInvalidException;
 import org.eclipse.jgit.junit.TestRepository;
 import org.eclipse.jgit.lib.Config;
+import org.eclipse.jgit.lib.ObjectInserter;
+import org.eclipse.jgit.lib.ObjectReader;
 import org.eclipse.jgit.lib.Repository;
 import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.jgit.revwalk.RevWalk;
 import org.junit.Before;
 import org.junit.Test;
 
@@ -39,11 +44,14 @@
  */
 public class CodeOwnersPluginConfigValidatorTest extends AbstractCodeOwnersTest {
   private CodeOwnersPluginConfigValidator codeOwnersPluginConfigValidator;
+  private DiffOperationsForCommitValidation.Factory diffOperationsForCommitValidationFactory;
 
   @Before
   public void setUpCodeOwnersPlugin() throws Exception {
     codeOwnersPluginConfigValidator =
         plugin.getSysInjector().getInstance(CodeOwnersPluginConfigValidator.class);
+    diffOperationsForCommitValidationFactory =
+        plugin.getSysInjector().getInstance(DiffOperationsForCommitValidation.Factory.class);
   }
 
   @Test
@@ -55,7 +63,10 @@
         GeneralConfig.KEY_FALLBACK_CODE_OWNERS,
         FallbackCodeOwners.ALL_USERS);
     try (TestRepository<Repository> testRepo =
-        new TestRepository<>(repoManager.openRepository(project))) {
+            new TestRepository<>(repoManager.openRepository(project));
+        ObjectInserter ins = testRepo.getRepository().newObjectInserter();
+        ObjectReader reader = ins.newReader();
+        RevWalk revWalk = new RevWalk(reader)) {
       RevCommit commit =
           testRepo
               .commit()
@@ -70,6 +81,9 @@
       receiveEvent.commit = commit;
       receiveEvent.revWalk = testRepo.getRevWalk();
       receiveEvent.repoConfig = new Config();
+      receiveEvent.diffOperations =
+          diffOperationsForCommitValidationFactory.create(
+              new RepoView(testRepo.getRepository(), revWalk, ins), ins);
       CommitValidationException exception =
           assertThrows(
               CommitValidationException.class,
diff --git a/javatests/com/google/gerrit/plugins/codeowners/backend/config/CodeOwnersPluginGlobalConfigSnapshotTest.java b/javatests/com/google/gerrit/plugins/codeowners/backend/config/CodeOwnersPluginGlobalConfigSnapshotTest.java
index 6a5c03d..e40d437 100644
--- a/javatests/com/google/gerrit/plugins/codeowners/backend/config/CodeOwnersPluginGlobalConfigSnapshotTest.java
+++ b/javatests/com/google/gerrit/plugins/codeowners/backend/config/CodeOwnersPluginGlobalConfigSnapshotTest.java
@@ -16,11 +16,11 @@
 
 import static com.google.common.truth.Truth.assertThat;
 import static com.google.gerrit.testing.GerritJUnit.assertThrows;
-import static com.google.gerrit.truth.OptionalSubject.assertThat;
 
 import com.google.gerrit.acceptance.config.GerritConfig;
 import com.google.gerrit.extensions.restapi.MethodNotAllowedException;
 import com.google.gerrit.plugins.codeowners.acceptance.AbstractCodeOwnersTest;
+import com.google.gerrit.truth.OptionalSubject;
 import org.junit.Before;
 import org.junit.Test;
 
@@ -65,7 +65,7 @@
 
   @Test
   public void codeOwnerConfigCacheSizeIsLimitedByDefault() throws Exception {
-    assertThat(cfgSnapshot().getMaxCodeOwnerConfigCacheSize())
+    OptionalSubject.assertThat(cfgSnapshot().getMaxCodeOwnerConfigCacheSize())
         .value()
         .isEqualTo(CodeOwnersPluginGlobalConfigSnapshot.DEFAULT_MAX_CODE_OWNER_CONFIG_CACHE_SIZE);
   }
@@ -73,26 +73,28 @@
   @Test
   @GerritConfig(name = "plugin.code-owners.maxCodeOwnerConfigCacheSize", value = "0")
   public void codeOwnerConfigCacheSizeIsUnlimited() throws Exception {
-    assertThat(cfgSnapshot().getMaxCodeOwnerConfigCacheSize()).isEmpty();
+    OptionalSubject.assertThat(cfgSnapshot().getMaxCodeOwnerConfigCacheSize()).isEmpty();
   }
 
   @Test
   @GerritConfig(name = "plugin.code-owners.maxCodeOwnerConfigCacheSize", value = "10")
   public void codeOwnerConfigCacheSizeIsLimited() throws Exception {
-    assertThat(cfgSnapshot().getMaxCodeOwnerConfigCacheSize()).value().isEqualTo(10);
+    OptionalSubject.assertThat(cfgSnapshot().getMaxCodeOwnerConfigCacheSize())
+        .value()
+        .isEqualTo(10);
   }
 
   @Test
   @GerritConfig(name = "plugin.code-owners.maxCodeOwnerConfigCacheSize", value = "invalid")
   public void maxCodeOwnerConfigCacheSize_invalidConfig() throws Exception {
-    assertThat(cfgSnapshot().getMaxCodeOwnerConfigCacheSize())
+    OptionalSubject.assertThat(cfgSnapshot().getMaxCodeOwnerConfigCacheSize())
         .value()
         .isEqualTo(CodeOwnersPluginGlobalConfigSnapshot.DEFAULT_MAX_CODE_OWNER_CONFIG_CACHE_SIZE);
   }
 
   @Test
   public void codeOwnerCacheSizeIsLimitedByDefault() throws Exception {
-    assertThat(cfgSnapshot().getMaxCodeOwnerCacheSize())
+    OptionalSubject.assertThat(cfgSnapshot().getMaxCodeOwnerCacheSize())
         .value()
         .isEqualTo(CodeOwnersPluginGlobalConfigSnapshot.DEFAULT_MAX_CODE_OWNER_CACHE_SIZE);
   }
@@ -100,19 +102,19 @@
   @Test
   @GerritConfig(name = "plugin.code-owners.maxCodeOwnerCacheSize", value = "0")
   public void codeOwnerCacheSizeIsUnlimited() throws Exception {
-    assertThat(cfgSnapshot().getMaxCodeOwnerCacheSize()).isEmpty();
+    OptionalSubject.assertThat(cfgSnapshot().getMaxCodeOwnerCacheSize()).isEmpty();
   }
 
   @Test
   @GerritConfig(name = "plugin.code-owners.maxCodeOwnerCacheSize", value = "10")
   public void codeOwnerCacheSizeIsLimited() throws Exception {
-    assertThat(cfgSnapshot().getMaxCodeOwnerCacheSize()).value().isEqualTo(10);
+    OptionalSubject.assertThat(cfgSnapshot().getMaxCodeOwnerCacheSize()).value().isEqualTo(10);
   }
 
   @Test
   @GerritConfig(name = "plugin.code-owners.maxCodeOwnerCacheSize", value = "invalid")
   public void maxCodeOwnerCacheSize_invalidConfig() throws Exception {
-    assertThat(cfgSnapshot().getMaxCodeOwnerCacheSize())
+    OptionalSubject.assertThat(cfgSnapshot().getMaxCodeOwnerCacheSize())
         .value()
         .isEqualTo(CodeOwnersPluginGlobalConfigSnapshot.DEFAULT_MAX_CODE_OWNER_CACHE_SIZE);
   }
diff --git a/javatests/com/google/gerrit/plugins/codeowners/backend/config/CodeOwnersPluginProjectConfigSnapshotTest.java b/javatests/com/google/gerrit/plugins/codeowners/backend/config/CodeOwnersPluginProjectConfigSnapshotTest.java
index 66649f9..77f79bf 100644
--- a/javatests/com/google/gerrit/plugins/codeowners/backend/config/CodeOwnersPluginProjectConfigSnapshotTest.java
+++ b/javatests/com/google/gerrit/plugins/codeowners/backend/config/CodeOwnersPluginProjectConfigSnapshotTest.java
@@ -19,7 +19,6 @@
 import static com.google.gerrit.plugins.codeowners.testing.CodeOwnerSetSubject.hasEmail;
 import static com.google.gerrit.plugins.codeowners.testing.RequiredApprovalSubject.assertThat;
 import static com.google.gerrit.testing.GerritJUnit.assertThrows;
-import static com.google.gerrit.truth.OptionalSubject.assertThat;
 
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
@@ -48,6 +47,7 @@
 import com.google.gerrit.plugins.codeowners.common.CodeOwnerConfigValidationPolicy;
 import com.google.gerrit.plugins.codeowners.common.MergeCommitStrategy;
 import com.google.gerrit.server.IdentifiedUser;
+import com.google.gerrit.truth.OptionalSubject;
 import com.google.inject.Inject;
 import com.google.inject.Key;
 import com.google.inject.util.Providers;
@@ -76,28 +76,28 @@
   @Test
   @GerritConfig(name = "plugin.code-owners.fileExtension", value = "foo")
   public void getFileExtensionIfNoneIsConfiguredOnProjectLevel() throws Exception {
-    assertThat(cfgSnapshot().getFileExtension()).value().isEqualTo("foo");
+    OptionalSubject.assertThat(cfgSnapshot().getFileExtension()).value().isEqualTo("foo");
   }
 
   @Test
   @GerritConfig(name = "plugin.code-owners.fileExtension", value = "foo")
   public void fileExtensionOnProjectLevelOverridesDefaultFileExtension() throws Exception {
     configureFileExtension(project, "bar");
-    assertThat(cfgSnapshot().getFileExtension()).value().isEqualTo("bar");
+    OptionalSubject.assertThat(cfgSnapshot().getFileExtension()).value().isEqualTo("bar");
   }
 
   @Test
   @GerritConfig(name = "plugin.code-owners.fileExtension", value = "foo")
   public void fileExtensionIsInheritedFromParentProject() throws Exception {
     configureFileExtension(allProjects, "bar");
-    assertThat(cfgSnapshot().getFileExtension()).value().isEqualTo("bar");
+    OptionalSubject.assertThat(cfgSnapshot().getFileExtension()).value().isEqualTo("bar");
   }
 
   @Test
   public void inheritedFileExtensionCanBeOverridden() throws Exception {
     configureFileExtension(allProjects, "foo");
     configureFileExtension(project, "bar");
-    assertThat(cfgSnapshot().getFileExtension()).value().isEqualTo("bar");
+    OptionalSubject.assertThat(cfgSnapshot().getFileExtension()).value().isEqualTo("bar");
   }
 
   @Test
@@ -1043,18 +1043,20 @@
 
   @Test
   public void getPathExpressionsForNonExistingBranch() throws Exception {
-    assertThat(cfgSnapshot().getPathExpressions("non-existing")).isEmpty();
+    OptionalSubject.assertThat(cfgSnapshot().getPathExpressions("non-existing")).isEmpty();
   }
 
   @Test
   public void getPathExpressionsWhenNoPathExpressionsAreConfigured() throws Exception {
-    assertThat(cfgSnapshot().getPathExpressions("master")).isEmpty();
+    OptionalSubject.assertThat(cfgSnapshot().getPathExpressions("master")).isEmpty();
   }
 
   @Test
   @GerritConfig(name = "plugin.code-owners.pathExpressions", value = "GLOB")
   public void getConfiguredPathExpressions() throws Exception {
-    assertThat(cfgSnapshot().getPathExpressions("master")).value().isEqualTo(PathExpressions.GLOB);
+    OptionalSubject.assertThat(cfgSnapshot().getPathExpressions("master"))
+        .value()
+        .isEqualTo(PathExpressions.GLOB);
   }
 
   @Test
@@ -1062,13 +1064,15 @@
       name = "plugin.code-owners.pathExpressions",
       value = "non-existing-path-expressions")
   public void getPathExpressionsIfNonExistingPathExpressionsAreConfigured() throws Exception {
-    assertThat(cfgSnapshot().getPathExpressions("master")).isEmpty();
+    OptionalSubject.assertThat(cfgSnapshot().getPathExpressions("master")).isEmpty();
   }
 
   @Test
   public void getPathExpressionsConfiguredOnProjectLevel() throws Exception {
     configurePathExpressions(project, PathExpressions.GLOB.name());
-    assertThat(cfgSnapshot().getPathExpressions("master")).value().isEqualTo(PathExpressions.GLOB);
+    OptionalSubject.assertThat(cfgSnapshot().getPathExpressions("master"))
+        .value()
+        .isEqualTo(PathExpressions.GLOB);
   }
 
   @Test
@@ -1076,7 +1080,7 @@
   public void pathExpressionsConfiguredOnProjectLevelOverrideDefaultPathExpressions()
       throws Exception {
     configurePathExpressions(project, PathExpressions.SIMPLE.name());
-    assertThat(cfgSnapshot().getPathExpressions("master"))
+    OptionalSubject.assertThat(cfgSnapshot().getPathExpressions("master"))
         .value()
         .isEqualTo(PathExpressions.SIMPLE);
   }
@@ -1084,14 +1088,16 @@
   @Test
   public void pathExpressionsAreInheritedFromParentProject() throws Exception {
     configurePathExpressions(allProjects, PathExpressions.GLOB.name());
-    assertThat(cfgSnapshot().getPathExpressions("master")).value().isEqualTo(PathExpressions.GLOB);
+    OptionalSubject.assertThat(cfgSnapshot().getPathExpressions("master"))
+        .value()
+        .isEqualTo(PathExpressions.GLOB);
   }
 
   @Test
   @GerritConfig(name = "plugin.code-owners.pathExpressions", value = "GLOB")
   public void inheritedPathExpressionsOverrideDefaultPathExpressions() throws Exception {
     configurePathExpressions(allProjects, PathExpressions.SIMPLE.name());
-    assertThat(cfgSnapshot().getPathExpressions("master"))
+    OptionalSubject.assertThat(cfgSnapshot().getPathExpressions("master"))
         .value()
         .isEqualTo(PathExpressions.SIMPLE);
   }
@@ -1100,7 +1106,7 @@
   public void projectLevelPathExpressionsOverrideInheritedPathExpressions() throws Exception {
     configurePathExpressions(allProjects, PathExpressions.GLOB.name());
     configurePathExpressions(project, PathExpressions.SIMPLE.name());
-    assertThat(cfgSnapshot().getPathExpressions("master"))
+    OptionalSubject.assertThat(cfgSnapshot().getPathExpressions("master"))
         .value()
         .isEqualTo(PathExpressions.SIMPLE);
   }
@@ -1111,26 +1117,32 @@
       pathExpressionsAreReadFromGlobalConfigIfNonExistingPathExpressionsAreConfiguredOnProjectLevel()
           throws Exception {
     configurePathExpressions(project, "non-existing-path-expressions");
-    assertThat(cfgSnapshot().getPathExpressions("master")).value().isEqualTo(PathExpressions.GLOB);
+    OptionalSubject.assertThat(cfgSnapshot().getPathExpressions("master"))
+        .value()
+        .isEqualTo(PathExpressions.GLOB);
   }
 
   @Test
   public void projectLevelPathExpressionsForOtherProjectHasNoEffect() throws Exception {
     Project.NameKey otherProject = projectOperations.newProject().create();
     configurePathExpressions(otherProject, PathExpressions.GLOB.name());
-    assertThat(cfgSnapshot().getPathExpressions("master")).isEmpty();
+    OptionalSubject.assertThat(cfgSnapshot().getPathExpressions("master")).isEmpty();
   }
 
   @Test
   public void getPathExpressionsConfiguredOnBranchLevel() throws Exception {
     configurePathExpressions(project, "refs/heads/master", PathExpressions.GLOB.name());
-    assertThat(cfgSnapshot().getPathExpressions("master")).value().isEqualTo(PathExpressions.GLOB);
+    OptionalSubject.assertThat(cfgSnapshot().getPathExpressions("master"))
+        .value()
+        .isEqualTo(PathExpressions.GLOB);
   }
 
   @Test
   public void getPathExpressionsConfiguredOnBranchLevelShortName() throws Exception {
     configurePathExpressions(project, "master", PathExpressions.GLOB.name());
-    assertThat(cfgSnapshot().getPathExpressions("master")).value().isEqualTo(PathExpressions.GLOB);
+    OptionalSubject.assertThat(cfgSnapshot().getPathExpressions("master"))
+        .value()
+        .isEqualTo(PathExpressions.GLOB);
   }
 
   @Test
@@ -1139,7 +1151,7 @@
           throws Exception {
     configurePathExpressions(project, "master", PathExpressions.GLOB.name());
     configurePathExpressions(project, "refs/heads/master", PathExpressions.SIMPLE.name());
-    assertThat(cfgSnapshot().getPathExpressions("master"))
+    OptionalSubject.assertThat(cfgSnapshot().getPathExpressions("master"))
         .value()
         .isEqualTo(PathExpressions.SIMPLE);
   }
@@ -1148,7 +1160,7 @@
   public void branchLevelPathExpressionsOverridesProjectLevelPathExpressions() throws Exception {
     configurePathExpressions(project, PathExpressions.GLOB.name());
     configurePathExpressions(project, "master", PathExpressions.SIMPLE.name());
-    assertThat(cfgSnapshot().getPathExpressions("master"))
+    OptionalSubject.assertThat(cfgSnapshot().getPathExpressions("master"))
         .value()
         .isEqualTo(PathExpressions.SIMPLE);
   }
@@ -1171,13 +1183,15 @@
               BackendConfig.KEY_PATH_EXPRESSIONS,
               "non-existing-path-expressions");
         });
-    assertThat(cfgSnapshot().getPathExpressions("master")).value().isEqualTo(PathExpressions.GLOB);
+    OptionalSubject.assertThat(cfgSnapshot().getPathExpressions("master"))
+        .value()
+        .isEqualTo(PathExpressions.GLOB);
   }
 
   @Test
   public void branchLevelPathExpressionsForOtherBranchHaveNoEffect() throws Exception {
     configurePathExpressions(project, "foo", PathExpressions.GLOB.name());
-    assertThat(cfgSnapshot().getPathExpressions("master")).isEmpty();
+    OptionalSubject.assertThat(cfgSnapshot().getPathExpressions("master")).isEmpty();
   }
 
   @Test
diff --git a/javatests/com/google/gerrit/plugins/codeowners/backend/config/GeneralConfigTest.java b/javatests/com/google/gerrit/plugins/codeowners/backend/config/GeneralConfigTest.java
index 17663b2..819411a 100644
--- a/javatests/com/google/gerrit/plugins/codeowners/backend/config/GeneralConfigTest.java
+++ b/javatests/com/google/gerrit/plugins/codeowners/backend/config/GeneralConfigTest.java
@@ -39,7 +39,6 @@
 import static com.google.gerrit.plugins.codeowners.backend.config.GeneralConfig.KEY_REJECT_NON_RESOLVABLE_IMPORTS;
 import static com.google.gerrit.plugins.codeowners.backend.config.GeneralConfig.SECTION_VALIDATION;
 import static com.google.gerrit.testing.GerritJUnit.assertThrows;
-import static com.google.gerrit.truth.OptionalSubject.assertThat;
 
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Iterables;
@@ -54,6 +53,7 @@
 import com.google.gerrit.server.git.validators.CommitValidationMessage;
 import com.google.gerrit.server.git.validators.ValidationMessage;
 import com.google.gerrit.testing.ConfigSuite;
+import com.google.gerrit.truth.OptionalSubject;
 import org.eclipse.jgit.lib.Config;
 import org.junit.Before;
 import org.junit.Test;
@@ -84,14 +84,16 @@
 
   @Test
   public void noFileExtensionConfigured() throws Exception {
-    assertThat(generalConfig.getFileExtension(new Config())).isEmpty();
+    OptionalSubject.assertThat(generalConfig.getFileExtension(new Config())).isEmpty();
   }
 
   @Test
   @GerritConfig(name = "plugin.code-owners.fileExtension", value = "foo")
   public void fileExtensionIsRetrievedFromGerritConfigIfNotSpecifiedOnProjectLevel()
       throws Exception {
-    assertThat(generalConfig.getFileExtension(new Config())).value().isEqualTo("foo");
+    OptionalSubject.assertThat(generalConfig.getFileExtension(new Config()))
+        .value()
+        .isEqualTo("foo");
   }
 
   @Test
@@ -99,7 +101,7 @@
   public void fileExtensionInPluginConfigOverridesFileExtensionInGerritConfig() throws Exception {
     Config cfg = new Config();
     cfg.setString(SECTION_CODE_OWNERS, /* subsection= */ null, KEY_FILE_EXTENSION, "bar");
-    assertThat(generalConfig.getFileExtension(cfg)).value().isEqualTo("bar");
+    OptionalSubject.assertThat(generalConfig.getFileExtension(cfg)).value().isEqualTo("bar");
   }
 
   @Test
@@ -401,7 +403,7 @@
 
   @Test
   public void noBranchSpecificRejectNonResolvableCodeOwnersConfiguration() throws Exception {
-    assertThat(
+    OptionalSubject.assertThat(
             generalConfig.getRejectNonResolvableCodeOwnersForBranch(
                 BranchNameKey.create(project, "master"), new Config()))
         .isEmpty();
@@ -416,7 +418,7 @@
         "refs/heads/foo",
         KEY_REJECT_NON_RESOLVABLE_CODE_OWNERS,
         /* value= */ false);
-    assertThat(
+    OptionalSubject.assertThat(
             generalConfig.getRejectNonResolvableCodeOwnersForBranch(
                 BranchNameKey.create(project, "master"), cfg))
         .isEmpty();
@@ -431,7 +433,7 @@
         "refs/heads/foo/*",
         KEY_REJECT_NON_RESOLVABLE_CODE_OWNERS,
         /* value= */ false);
-    assertThat(
+    OptionalSubject.assertThat(
             generalConfig.getRejectNonResolvableCodeOwnersForBranch(
                 BranchNameKey.create(project, "master"), cfg))
         .isEmpty();
@@ -446,7 +448,7 @@
         "^refs/heads/.*foo.*",
         KEY_REJECT_NON_RESOLVABLE_CODE_OWNERS,
         /* value= */ false);
-    assertThat(
+    OptionalSubject.assertThat(
             generalConfig.getRejectNonResolvableCodeOwnersForBranch(
                 BranchNameKey.create(project, "master"), cfg))
         .isEmpty();
@@ -461,7 +463,7 @@
         "^refs/heads/[",
         KEY_REJECT_NON_RESOLVABLE_CODE_OWNERS,
         /* value= */ false);
-    assertThat(
+    OptionalSubject.assertThat(
             generalConfig.getRejectNonResolvableCodeOwnersForBranch(
                 BranchNameKey.create(project, "master"), cfg))
         .isEmpty();
@@ -476,7 +478,7 @@
         "refs/heads/master",
         KEY_REJECT_NON_RESOLVABLE_CODE_OWNERS,
         /* value= */ false);
-    assertThat(
+    OptionalSubject.assertThat(
             generalConfig.getRejectNonResolvableCodeOwnersForBranch(
                 BranchNameKey.create(project, "master"), cfg))
         .value()
@@ -492,7 +494,7 @@
         "refs/heads/*",
         KEY_REJECT_NON_RESOLVABLE_CODE_OWNERS,
         /* value= */ false);
-    assertThat(
+    OptionalSubject.assertThat(
             generalConfig.getRejectNonResolvableCodeOwnersForBranch(
                 BranchNameKey.create(project, "master"), cfg))
         .value()
@@ -508,7 +510,7 @@
         "^refs/heads/.*bar.*",
         KEY_REJECT_NON_RESOLVABLE_CODE_OWNERS,
         /* value= */ false);
-    assertThat(
+    OptionalSubject.assertThat(
             generalConfig.getRejectNonResolvableCodeOwnersForBranch(
                 BranchNameKey.create(project, "foobarbaz"), cfg))
         .value()
@@ -521,7 +523,7 @@
     Config cfg = new Config();
     cfg.setString(
         SECTION_VALIDATION, "refs/heads/master", KEY_REJECT_NON_RESOLVABLE_CODE_OWNERS, "INVALID");
-    assertThat(
+    OptionalSubject.assertThat(
             generalConfig.getRejectNonResolvableCodeOwnersForBranch(
                 BranchNameKey.create(project, "master"), cfg))
         .isEmpty();
@@ -549,7 +551,7 @@
 
     // it is non-deterministic which of the branch-specific configurations takes precedence, but
     // since they all configure the same value it's not important for this assertion
-    assertThat(
+    OptionalSubject.assertThat(
             generalConfig.getRejectNonResolvableCodeOwnersForBranch(
                 BranchNameKey.create(project, "master"), cfg))
         .value()
@@ -638,7 +640,7 @@
 
   @Test
   public void noBranchSpecificRejectNonResolvableImportsConfiguration() throws Exception {
-    assertThat(
+    OptionalSubject.assertThat(
             generalConfig.getRejectNonResolvableImportsForBranch(
                 BranchNameKey.create(project, "master"), new Config()))
         .isEmpty();
@@ -653,7 +655,7 @@
         "refs/heads/foo",
         KEY_REJECT_NON_RESOLVABLE_IMPORTS,
         /* value= */ false);
-    assertThat(
+    OptionalSubject.assertThat(
             generalConfig.getRejectNonResolvableImportsForBranch(
                 BranchNameKey.create(project, "master"), cfg))
         .isEmpty();
@@ -668,7 +670,7 @@
         "refs/heads/foo/*",
         KEY_REJECT_NON_RESOLVABLE_IMPORTS,
         /* value= */ false);
-    assertThat(
+    OptionalSubject.assertThat(
             generalConfig.getRejectNonResolvableImportsForBranch(
                 BranchNameKey.create(project, "master"), cfg))
         .isEmpty();
@@ -683,7 +685,7 @@
         "^refs/heads/.*foo.*",
         KEY_REJECT_NON_RESOLVABLE_IMPORTS,
         /* value= */ false);
-    assertThat(
+    OptionalSubject.assertThat(
             generalConfig.getRejectNonResolvableImportsForBranch(
                 BranchNameKey.create(project, "master"), cfg))
         .isEmpty();
@@ -695,7 +697,7 @@
     Config cfg = new Config();
     cfg.setBoolean(
         SECTION_VALIDATION, "^refs/heads/[", KEY_REJECT_NON_RESOLVABLE_IMPORTS, /* value= */ false);
-    assertThat(
+    OptionalSubject.assertThat(
             generalConfig.getRejectNonResolvableImportsForBranch(
                 BranchNameKey.create(project, "master"), cfg))
         .isEmpty();
@@ -710,7 +712,7 @@
         "refs/heads/master",
         KEY_REJECT_NON_RESOLVABLE_IMPORTS,
         /* value= */ false);
-    assertThat(
+    OptionalSubject.assertThat(
             generalConfig.getRejectNonResolvableImportsForBranch(
                 BranchNameKey.create(project, "master"), cfg))
         .value()
@@ -723,7 +725,7 @@
     Config cfg = new Config();
     cfg.setBoolean(
         SECTION_VALIDATION, "refs/heads/*", KEY_REJECT_NON_RESOLVABLE_IMPORTS, /* value= */ false);
-    assertThat(
+    OptionalSubject.assertThat(
             generalConfig.getRejectNonResolvableImportsForBranch(
                 BranchNameKey.create(project, "master"), cfg))
         .value()
@@ -739,7 +741,7 @@
         "^refs/heads/.*bar.*",
         KEY_REJECT_NON_RESOLVABLE_IMPORTS,
         /* value= */ false);
-    assertThat(
+    OptionalSubject.assertThat(
             generalConfig.getRejectNonResolvableImportsForBranch(
                 BranchNameKey.create(project, "foobarbaz"), cfg))
         .value()
@@ -752,7 +754,7 @@
     Config cfg = new Config();
     cfg.setString(
         SECTION_VALIDATION, "refs/heads/master", KEY_REJECT_NON_RESOLVABLE_IMPORTS, "INVALID");
-    assertThat(
+    OptionalSubject.assertThat(
             generalConfig.getRejectNonResolvableImportsForBranch(
                 BranchNameKey.create(project, "master"), cfg))
         .isEmpty();
@@ -777,7 +779,7 @@
 
     // it is non-deterministic which of the branch-specific configurations takes precedence, but
     // since they all configure the same value it's not important for this assertion
-    assertThat(
+    OptionalSubject.assertThat(
             generalConfig.getRejectNonResolvableImportsForBranch(
                 BranchNameKey.create(project, "master"), cfg))
         .value()
@@ -889,7 +891,7 @@
 
   @Test
   public void noBranchSpecificEnableValidationOnBranchCreationConfiguration() throws Exception {
-    assertThat(
+    OptionalSubject.assertThat(
             generalConfig.getCodeOwnerConfigValidationPolicyForBranchCreationForBranch(
                 BranchNameKey.create(project, "master"), new Config()))
         .isEmpty();
@@ -901,7 +903,7 @@
     Config cfg = new Config();
     cfg.setString(
         SECTION_VALIDATION, "refs/heads/foo", KEY_ENABLE_VALIDATION_ON_BRANCH_CREATION, "false");
-    assertThat(
+    OptionalSubject.assertThat(
             generalConfig.getCodeOwnerConfigValidationPolicyForBranchCreationForBranch(
                 BranchNameKey.create(project, "master"), cfg))
         .isEmpty();
@@ -913,7 +915,7 @@
     Config cfg = new Config();
     cfg.setString(
         SECTION_VALIDATION, "refs/heads/foo/*", KEY_ENABLE_VALIDATION_ON_COMMIT_RECEIVED, "false");
-    assertThat(
+    OptionalSubject.assertThat(
             generalConfig.getCodeOwnerConfigValidationPolicyForBranchCreationForBranch(
                 BranchNameKey.create(project, "master"), cfg))
         .isEmpty();
@@ -928,7 +930,7 @@
         "^refs/heads/.*foo.*",
         KEY_ENABLE_VALIDATION_ON_BRANCH_CREATION,
         "false");
-    assertThat(
+    OptionalSubject.assertThat(
             generalConfig.getCodeOwnerConfigValidationPolicyForBranchCreationForBranch(
                 BranchNameKey.create(project, "master"), cfg))
         .isEmpty();
@@ -940,7 +942,7 @@
     Config cfg = new Config();
     cfg.setString(
         SECTION_VALIDATION, "^refs/heads/[", KEY_ENABLE_VALIDATION_ON_BRANCH_CREATION, "false");
-    assertThat(
+    OptionalSubject.assertThat(
             generalConfig.getCodeOwnerConfigValidationPolicyForBranchCreationForBranch(
                 BranchNameKey.create(project, "master"), cfg))
         .isEmpty();
@@ -952,7 +954,7 @@
     Config cfg = new Config();
     cfg.setString(
         SECTION_VALIDATION, "refs/heads/master", KEY_ENABLE_VALIDATION_ON_BRANCH_CREATION, "false");
-    assertThat(
+    OptionalSubject.assertThat(
             generalConfig.getCodeOwnerConfigValidationPolicyForBranchCreationForBranch(
                 BranchNameKey.create(project, "master"), cfg))
         .value()
@@ -965,7 +967,7 @@
     Config cfg = new Config();
     cfg.setString(
         SECTION_VALIDATION, "refs/heads/*", KEY_ENABLE_VALIDATION_ON_BRANCH_CREATION, "false");
-    assertThat(
+    OptionalSubject.assertThat(
             generalConfig.getCodeOwnerConfigValidationPolicyForBranchCreationForBranch(
                 BranchNameKey.create(project, "master"), cfg))
         .value()
@@ -981,7 +983,7 @@
         "^refs/heads/.*bar.*",
         KEY_ENABLE_VALIDATION_ON_BRANCH_CREATION,
         "false");
-    assertThat(
+    OptionalSubject.assertThat(
             generalConfig.getCodeOwnerConfigValidationPolicyForBranchCreationForBranch(
                 BranchNameKey.create(project, "foobarbaz"), cfg))
         .value()
@@ -997,7 +999,7 @@
         "refs/heads/master",
         KEY_ENABLE_VALIDATION_ON_BRANCH_CREATION,
         "INVALID");
-    assertThat(
+    OptionalSubject.assertThat(
             generalConfig.getCodeOwnerConfigValidationPolicyForBranchCreationForBranch(
                 BranchNameKey.create(project, "master"), cfg))
         .isEmpty();
@@ -1016,7 +1018,7 @@
 
     // it is non-deterministic which of the branch-specific configurations takes precedence, but
     // since they all configure the same value it's not important for this assertion
-    assertThat(
+    OptionalSubject.assertThat(
             generalConfig.getCodeOwnerConfigValidationPolicyForBranchCreationForBranch(
                 BranchNameKey.create(project, "master"), cfg))
         .value()
@@ -1117,7 +1119,7 @@
 
   @Test
   public void noBranchSpecificEnableValidationOnCommitReceivedConfiguration() throws Exception {
-    assertThat(
+    OptionalSubject.assertThat(
             generalConfig.getCodeOwnerConfigValidationPolicyForCommitReceivedForBranch(
                 BranchNameKey.create(project, "master"), new Config()))
         .isEmpty();
@@ -1129,7 +1131,7 @@
     Config cfg = new Config();
     cfg.setString(
         SECTION_VALIDATION, "refs/heads/foo", KEY_ENABLE_VALIDATION_ON_COMMIT_RECEIVED, "false");
-    assertThat(
+    OptionalSubject.assertThat(
             generalConfig.getCodeOwnerConfigValidationPolicyForCommitReceivedForBranch(
                 BranchNameKey.create(project, "master"), cfg))
         .isEmpty();
@@ -1141,7 +1143,7 @@
     Config cfg = new Config();
     cfg.setString(
         SECTION_VALIDATION, "refs/heads/foo/*", KEY_ENABLE_VALIDATION_ON_COMMIT_RECEIVED, "false");
-    assertThat(
+    OptionalSubject.assertThat(
             generalConfig.getCodeOwnerConfigValidationPolicyForCommitReceivedForBranch(
                 BranchNameKey.create(project, "master"), cfg))
         .isEmpty();
@@ -1156,7 +1158,7 @@
         "^refs/heads/.*foo.*",
         KEY_ENABLE_VALIDATION_ON_COMMIT_RECEIVED,
         "false");
-    assertThat(
+    OptionalSubject.assertThat(
             generalConfig.getCodeOwnerConfigValidationPolicyForCommitReceivedForBranch(
                 BranchNameKey.create(project, "master"), cfg))
         .isEmpty();
@@ -1168,7 +1170,7 @@
     Config cfg = new Config();
     cfg.setString(
         SECTION_VALIDATION, "^refs/heads/[", KEY_ENABLE_VALIDATION_ON_COMMIT_RECEIVED, "false");
-    assertThat(
+    OptionalSubject.assertThat(
             generalConfig.getCodeOwnerConfigValidationPolicyForCommitReceivedForBranch(
                 BranchNameKey.create(project, "master"), cfg))
         .isEmpty();
@@ -1180,7 +1182,7 @@
     Config cfg = new Config();
     cfg.setString(
         SECTION_VALIDATION, "refs/heads/master", KEY_ENABLE_VALIDATION_ON_COMMIT_RECEIVED, "false");
-    assertThat(
+    OptionalSubject.assertThat(
             generalConfig.getCodeOwnerConfigValidationPolicyForCommitReceivedForBranch(
                 BranchNameKey.create(project, "master"), cfg))
         .value()
@@ -1193,7 +1195,7 @@
     Config cfg = new Config();
     cfg.setString(
         SECTION_VALIDATION, "refs/heads/*", KEY_ENABLE_VALIDATION_ON_COMMIT_RECEIVED, "false");
-    assertThat(
+    OptionalSubject.assertThat(
             generalConfig.getCodeOwnerConfigValidationPolicyForCommitReceivedForBranch(
                 BranchNameKey.create(project, "master"), cfg))
         .value()
@@ -1209,7 +1211,7 @@
         "^refs/heads/.*bar.*",
         KEY_ENABLE_VALIDATION_ON_COMMIT_RECEIVED,
         "false");
-    assertThat(
+    OptionalSubject.assertThat(
             generalConfig.getCodeOwnerConfigValidationPolicyForCommitReceivedForBranch(
                 BranchNameKey.create(project, "foobarbaz"), cfg))
         .value()
@@ -1225,7 +1227,7 @@
         "refs/heads/master",
         KEY_ENABLE_VALIDATION_ON_COMMIT_RECEIVED,
         "INVALID");
-    assertThat(
+    OptionalSubject.assertThat(
             generalConfig.getCodeOwnerConfigValidationPolicyForCommitReceivedForBranch(
                 BranchNameKey.create(project, "master"), cfg))
         .isEmpty();
@@ -1244,7 +1246,7 @@
 
     // it is non-deterministic which of the branch-specific configurations takes precedence, but
     // since they all configure the same value it's not important for this assertion
-    assertThat(
+    OptionalSubject.assertThat(
             generalConfig.getCodeOwnerConfigValidationPolicyForCommitReceivedForBranch(
                 BranchNameKey.create(project, "master"), cfg))
         .value()
@@ -1343,7 +1345,7 @@
 
   @Test
   public void noBranchSpecificEnableValidationOnSubmitConfiguration() throws Exception {
-    assertThat(
+    OptionalSubject.assertThat(
             generalConfig.getCodeOwnerConfigValidationPolicyForSubmitForBranch(
                 BranchNameKey.create(project, "master"), new Config()))
         .isEmpty();
@@ -1354,7 +1356,7 @@
       throws Exception {
     Config cfg = new Config();
     cfg.setString(SECTION_VALIDATION, "refs/heads/foo", KEY_ENABLE_VALIDATION_ON_SUBMIT, "false");
-    assertThat(
+    OptionalSubject.assertThat(
             generalConfig.getCodeOwnerConfigValidationPolicyForSubmitForBranch(
                 BranchNameKey.create(project, "master"), cfg))
         .isEmpty();
@@ -1365,7 +1367,7 @@
       throws Exception {
     Config cfg = new Config();
     cfg.setString(SECTION_VALIDATION, "refs/heads/foo/*", KEY_ENABLE_VALIDATION_ON_SUBMIT, "false");
-    assertThat(
+    OptionalSubject.assertThat(
             generalConfig.getCodeOwnerConfigValidationPolicyForSubmitForBranch(
                 BranchNameKey.create(project, "master"), cfg))
         .isEmpty();
@@ -1377,7 +1379,7 @@
     Config cfg = new Config();
     cfg.setString(
         SECTION_VALIDATION, "^refs/heads/.*foo.*", KEY_ENABLE_VALIDATION_ON_SUBMIT, "false");
-    assertThat(
+    OptionalSubject.assertThat(
             generalConfig.getCodeOwnerConfigValidationPolicyForCommitReceivedForBranch(
                 BranchNameKey.create(project, "master"), cfg))
         .isEmpty();
@@ -1388,7 +1390,7 @@
       throws Exception {
     Config cfg = new Config();
     cfg.setString(SECTION_VALIDATION, "^refs/heads/[", KEY_ENABLE_VALIDATION_ON_SUBMIT, "false");
-    assertThat(
+    OptionalSubject.assertThat(
             generalConfig.getCodeOwnerConfigValidationPolicyForSubmitForBranch(
                 BranchNameKey.create(project, "master"), cfg))
         .isEmpty();
@@ -1399,7 +1401,7 @@
     Config cfg = new Config();
     cfg.setString(
         SECTION_VALIDATION, "refs/heads/master", KEY_ENABLE_VALIDATION_ON_SUBMIT, "false");
-    assertThat(
+    OptionalSubject.assertThat(
             generalConfig.getCodeOwnerConfigValidationPolicyForSubmitForBranch(
                 BranchNameKey.create(project, "master"), cfg))
         .value()
@@ -1411,7 +1413,7 @@
       throws Exception {
     Config cfg = new Config();
     cfg.setString(SECTION_VALIDATION, "refs/heads/*", KEY_ENABLE_VALIDATION_ON_SUBMIT, "false");
-    assertThat(
+    OptionalSubject.assertThat(
             generalConfig.getCodeOwnerConfigValidationPolicyForSubmitForBranch(
                 BranchNameKey.create(project, "master"), cfg))
         .value()
@@ -1423,7 +1425,7 @@
     Config cfg = new Config();
     cfg.setString(
         SECTION_VALIDATION, "^refs/heads/.*bar.*", KEY_ENABLE_VALIDATION_ON_SUBMIT, "false");
-    assertThat(
+    OptionalSubject.assertThat(
             generalConfig.getCodeOwnerConfigValidationPolicyForSubmitForBranch(
                 BranchNameKey.create(project, "foobarbaz"), cfg))
         .value()
@@ -1436,7 +1438,7 @@
     Config cfg = new Config();
     cfg.setString(
         SECTION_VALIDATION, "refs/heads/master", KEY_ENABLE_VALIDATION_ON_SUBMIT, "INVALID");
-    assertThat(
+    OptionalSubject.assertThat(
             generalConfig.getCodeOwnerConfigValidationPolicyForSubmitForBranch(
                 BranchNameKey.create(project, "master"), cfg))
         .isEmpty();
@@ -1453,7 +1455,7 @@
 
     // it is non-deterministic which of the branch-specific configurations takes precedence, but
     // since they all configure the same value it's not important for this assertion
-    assertThat(
+    OptionalSubject.assertThat(
             generalConfig.getCodeOwnerConfigValidationPolicyForSubmitForBranch(
                 BranchNameKey.create(project, "master"), cfg))
         .value()
@@ -1856,14 +1858,14 @@
 
   @Test
   public void noOverrideInfoUrlConfigured() throws Exception {
-    assertThat(generalConfig.getOverrideInfoUrl(new Config())).isEmpty();
+    OptionalSubject.assertThat(generalConfig.getOverrideInfoUrl(new Config())).isEmpty();
   }
 
   @Test
   @GerritConfig(name = "plugin.code-owners.overrideInfoUrl", value = "http://foo.example.com")
   public void overrideInfoIsRetrievedFromGerritConfigIfNotSpecifiedOnProjectLevel()
       throws Exception {
-    assertThat(generalConfig.getOverrideInfoUrl(new Config()))
+    OptionalSubject.assertThat(generalConfig.getOverrideInfoUrl(new Config()))
         .value()
         .isEqualTo("http://foo.example.com");
   }
@@ -1878,7 +1880,9 @@
         /* subsection= */ null,
         KEY_OVERRIDE_INFO_URL,
         "http://bar.example.com");
-    assertThat(generalConfig.getOverrideInfoUrl(cfg)).value().isEqualTo("http://bar.example.com");
+    OptionalSubject.assertThat(generalConfig.getOverrideInfoUrl(cfg))
+        .value()
+        .isEqualTo("http://bar.example.com");
   }
 
   @Test
@@ -1892,7 +1896,8 @@
 
   @Test
   public void noInvalidCodeOwnerConfigInfoUrlConfigured() throws Exception {
-    assertThat(generalConfig.getInvalidCodeOwnerConfigInfoUrl(new Config())).isEmpty();
+    OptionalSubject.assertThat(generalConfig.getInvalidCodeOwnerConfigInfoUrl(new Config()))
+        .isEmpty();
   }
 
   @Test
@@ -1901,7 +1906,7 @@
       value = "http://foo.example.com")
   public void invalidCodeOwnerConfigInfoIsRetrievedFromGerritConfigIfNotSpecifiedOnProjectLevel()
       throws Exception {
-    assertThat(generalConfig.getInvalidCodeOwnerConfigInfoUrl(new Config()))
+    OptionalSubject.assertThat(generalConfig.getInvalidCodeOwnerConfigInfoUrl(new Config()))
         .value()
         .isEqualTo("http://foo.example.com");
   }
@@ -1918,7 +1923,7 @@
         /* subsection= */ null,
         KEY_INVALID_CODE_OWNER_CONFIG_INFO_URL,
         "http://bar.example.com");
-    assertThat(generalConfig.getInvalidCodeOwnerConfigInfoUrl(cfg))
+    OptionalSubject.assertThat(generalConfig.getInvalidCodeOwnerConfigInfoUrl(cfg))
         .value()
         .isEqualTo("http://bar.example.com");
   }
diff --git a/javatests/com/google/gerrit/plugins/codeowners/backend/findowners/FindOwnersCodeOwnerConfigParserTest.java b/javatests/com/google/gerrit/plugins/codeowners/backend/findowners/FindOwnersCodeOwnerConfigParserTest.java
index 260e635..199dfc1 100644
--- a/javatests/com/google/gerrit/plugins/codeowners/backend/findowners/FindOwnersCodeOwnerConfigParserTest.java
+++ b/javatests/com/google/gerrit/plugins/codeowners/backend/findowners/FindOwnersCodeOwnerConfigParserTest.java
@@ -36,7 +36,6 @@
 import com.google.gerrit.plugins.codeowners.testing.CodeOwnerConfigReferenceSubject;
 import com.google.gerrit.plugins.codeowners.testing.CodeOwnerSetSubject;
 import java.nio.file.Path;
-import java.nio.file.Paths;
 import java.util.regex.Pattern;
 import org.junit.Test;
 
@@ -221,7 +220,7 @@
 
   @Test
   public void importCodeOwnerConfigWithComment() throws Exception {
-    Path path = Paths.get("/foo/bar/OWNERS");
+    Path path = Path.of("/foo/bar/OWNERS");
     CodeOwnerConfigReference codeOwnerConfigReference =
         CodeOwnerConfigReference.builder(CodeOwnerConfigImportMode.ALL, path).build();
     assertParseAndFormat(
@@ -385,7 +384,7 @@
 
   @Test
   public void importCodeOwnerConfigFromSameProjectAndBranch() throws Exception {
-    Path path = Paths.get("/foo/bar/OWNERS");
+    Path path = Path.of("/foo/bar/OWNERS");
     CodeOwnerConfigReference codeOwnerConfigReference =
         CodeOwnerConfigReference.builder(CodeOwnerConfigImportMode.ALL, path).build();
     assertParseAndFormat(
@@ -402,7 +401,7 @@
   @Test
   public void importCodeOwnerConfigFromOtherProject() throws Exception {
     String otherProject = "otherProject";
-    Path path = Paths.get("/foo/bar/OWNERS");
+    Path path = Path.of("/foo/bar/OWNERS");
     CodeOwnerConfigReference codeOwnerConfigReference =
         CodeOwnerConfigReference.builder(CodeOwnerConfigImportMode.ALL, path)
             .setProject(Project.nameKey(otherProject))
@@ -420,7 +419,7 @@
   @Test
   public void cannotFormatCodeOwnerConfigWithImportThatSpecifiesBranchWithoutProject()
       throws Exception {
-    Path path = Paths.get("/foo/bar/OWNERS");
+    Path path = Path.of("/foo/bar/OWNERS");
     CodeOwnerConfigReference codeOwnerConfigReference =
         CodeOwnerConfigReference.builder(CodeOwnerConfigImportMode.ALL, path)
             .setBranch("refs/heads/foo")
@@ -453,7 +452,7 @@
   }
 
   private void testImportCodeOwnerConfigFromOtherBranch(String branchName) throws Exception {
-    Path path = Paths.get("/foo/bar/OWNERS");
+    Path path = Path.of("/foo/bar/OWNERS");
     CodeOwnerConfigReference codeOwnerConfigReference =
         CodeOwnerConfigReference.builder(CodeOwnerConfigImportMode.ALL, path)
             .setProject(project)
@@ -507,10 +506,10 @@
 
   @Test
   public void importMultipleCodeOwnerConfigs() throws Exception {
-    Path path1 = Paths.get("/foo/bar/OWNERS");
+    Path path1 = Path.of("/foo/bar/OWNERS");
     CodeOwnerConfigReference codeOwnerConfigReference1 =
         CodeOwnerConfigReference.builder(CodeOwnerConfigImportMode.ALL, path1).build();
-    Path path2 = Paths.get("/foo/baz/OWNERS");
+    Path path2 = Path.of("/foo/baz/OWNERS");
     CodeOwnerConfigReference codeOwnerConfigReference2 =
         CodeOwnerConfigReference.builder(
                 CodeOwnerConfigImportMode.GLOBAL_CODE_OWNER_SETS_ONLY, path2)
@@ -569,7 +568,7 @@
 
   @Test
   public void perFileCodeOwnerConfigImportFromSameProjectAndBranch() throws Exception {
-    Path path = Paths.get("/foo/bar/OWNERS");
+    Path path = Path.of("/foo/bar/OWNERS");
     CodeOwnerConfigReference codeOwnerConfigReference =
         CodeOwnerConfigReference.builder(
                 CodeOwnerConfigImportMode.GLOBAL_CODE_OWNER_SETS_ONLY, path)
@@ -600,7 +599,7 @@
   @Test
   public void perFileCodeOwnerConfigImportFromOtherProject() throws Exception {
     String otherProject = "otherProject";
-    Path path = Paths.get("/foo/bar/OWNERS");
+    Path path = Path.of("/foo/bar/OWNERS");
     CodeOwnerConfigReference codeOwnerConfigReference =
         CodeOwnerConfigReference.builder(
                 CodeOwnerConfigImportMode.GLOBAL_CODE_OWNER_SETS_ONLY, path)
@@ -631,7 +630,7 @@
   @Test
   public void cannotFormatCodeOwnerConfigWithPerFileImportThatSpecifiesBranchWithoutProject()
       throws Exception {
-    Path path = Paths.get("/foo/bar/OWNERS");
+    Path path = Path.of("/foo/bar/OWNERS");
     CodeOwnerConfigReference codeOwnerConfigReference =
         CodeOwnerConfigReference.builder(
                 CodeOwnerConfigImportMode.GLOBAL_CODE_OWNER_SETS_ONLY, path)
@@ -670,7 +669,7 @@
 
   private void testPerFileImportOfCodeOwnerConfigFromOtherBranch(String branchName)
       throws Exception {
-    Path path = Paths.get("/foo/bar/OWNERS");
+    Path path = Path.of("/foo/bar/OWNERS");
     CodeOwnerConfigReference codeOwnerConfigReference =
         CodeOwnerConfigReference.builder(
                 CodeOwnerConfigImportMode.GLOBAL_CODE_OWNER_SETS_ONLY, path)
diff --git a/javatests/com/google/gerrit/plugins/codeowners/restapi/CodeOwnerConfigJsonTest.java b/javatests/com/google/gerrit/plugins/codeowners/restapi/CodeOwnerConfigJsonTest.java
index 271ebb5..a5aea59 100644
--- a/javatests/com/google/gerrit/plugins/codeowners/restapi/CodeOwnerConfigJsonTest.java
+++ b/javatests/com/google/gerrit/plugins/codeowners/restapi/CodeOwnerConfigJsonTest.java
@@ -15,7 +15,6 @@
 package com.google.gerrit.plugins.codeowners.restapi;
 
 import static com.google.common.truth.Truth.assertThat;
-import static com.google.common.truth.Truth8.assertThat;
 import static com.google.gerrit.plugins.codeowners.testing.CodeOwnerConfigInfoSubject.assertThat;
 import static com.google.gerrit.plugins.codeowners.testing.CodeOwnerSetInfoSubject.assertThat;
 import static com.google.gerrit.testing.GerritJUnit.assertThrows;
diff --git a/javatests/com/google/gerrit/plugins/codeowners/restapi/CodeOwnerStatusInfoJsonTest.java b/javatests/com/google/gerrit/plugins/codeowners/restapi/CodeOwnerStatusInfoJsonTest.java
index 17fbdb1..67884c0 100644
--- a/javatests/com/google/gerrit/plugins/codeowners/restapi/CodeOwnerStatusInfoJsonTest.java
+++ b/javatests/com/google/gerrit/plugins/codeowners/restapi/CodeOwnerStatusInfoJsonTest.java
@@ -38,7 +38,7 @@
 import com.google.gerrit.plugins.codeowners.testing.FileCodeOwnerStatusInfoSubject;
 import com.google.gerrit.server.util.AccountTemplateUtil;
 import com.google.gerrit.truth.ListSubject;
-import java.nio.file.Paths;
+import java.nio.file.Path;
 import java.util.Optional;
 import org.eclipse.jgit.diff.DiffEntry;
 import org.junit.Before;
@@ -67,7 +67,7 @@
   @Test
   public void formatPathCodeOwnerStatus() throws Exception {
     PathCodeOwnerStatus pathCodeOwnerStatus =
-        PathCodeOwnerStatus.create(Paths.get("/foo/bar.baz"), CodeOwnerStatus.APPROVED);
+        PathCodeOwnerStatus.create(Path.of("/foo/bar.baz"), CodeOwnerStatus.APPROVED);
     PathCodeOwnerStatusInfo pathCodeOwnerStatusInfo =
         CodeOwnerStatusInfoJson.format(pathCodeOwnerStatus);
     assertThat(pathCodeOwnerStatusInfo).hasPathThat().isEqualTo("foo/bar.baz");
@@ -78,7 +78,7 @@
   @Test
   public void formatPathCodeOwnerStatusWithReasons() throws Exception {
     PathCodeOwnerStatus pathCodeOwnerStatus =
-        PathCodeOwnerStatus.builder(Paths.get("/foo/bar.baz"), CodeOwnerStatus.APPROVED)
+        PathCodeOwnerStatus.builder(Path.of("/foo/bar.baz"), CodeOwnerStatus.APPROVED)
             .addReason("one reason")
             .addReason("another reason")
             .build();
@@ -107,7 +107,7 @@
     ChangedFile changedFile = mock(ChangedFile.class);
     when(changedFile.changeType()).thenReturn(DiffEntry.ChangeType.ADD);
     PathCodeOwnerStatus pathCodeOwnerStatus =
-        PathCodeOwnerStatus.create(Paths.get("/foo/bar.baz"), CodeOwnerStatus.APPROVED);
+        PathCodeOwnerStatus.create(Path.of("/foo/bar.baz"), CodeOwnerStatus.APPROVED);
     FileCodeOwnerStatus fileCodeOwnerStatus =
         FileCodeOwnerStatus.create(changedFile, Optional.of(pathCodeOwnerStatus), Optional.empty());
     FileCodeOwnerStatusInfo fileCodeOwnerStatusInfo =
@@ -131,7 +131,7 @@
     ChangedFile changedFile = mock(ChangedFile.class);
     when(changedFile.changeType()).thenReturn(DiffEntry.ChangeType.MODIFY);
     PathCodeOwnerStatus pathCodeOwnerStatus =
-        PathCodeOwnerStatus.create(Paths.get("/foo/bar.baz"), CodeOwnerStatus.APPROVED);
+        PathCodeOwnerStatus.create(Path.of("/foo/bar.baz"), CodeOwnerStatus.APPROVED);
     FileCodeOwnerStatus fileCodeOwnerStatus =
         FileCodeOwnerStatus.create(changedFile, Optional.of(pathCodeOwnerStatus), Optional.empty());
     FileCodeOwnerStatusInfo fileCodeOwnerStatusInfo =
@@ -155,7 +155,7 @@
     ChangedFile changedFile = mock(ChangedFile.class);
     when(changedFile.changeType()).thenReturn(DiffEntry.ChangeType.DELETE);
     PathCodeOwnerStatus pathCodeOwnerStatus =
-        PathCodeOwnerStatus.create(Paths.get("/foo/bar.baz"), CodeOwnerStatus.APPROVED);
+        PathCodeOwnerStatus.create(Path.of("/foo/bar.baz"), CodeOwnerStatus.APPROVED);
     FileCodeOwnerStatus fileCodeOwnerStatus =
         FileCodeOwnerStatus.create(changedFile, Optional.empty(), Optional.of(pathCodeOwnerStatus));
     FileCodeOwnerStatusInfo fileCodeOwnerStatusInfo =
@@ -179,9 +179,9 @@
     ChangedFile changedFile = mock(ChangedFile.class);
     when(changedFile.changeType()).thenReturn(DiffEntry.ChangeType.RENAME);
     PathCodeOwnerStatus newPathCodeOwnerStatus =
-        PathCodeOwnerStatus.create(Paths.get("/foo/new.baz"), CodeOwnerStatus.PENDING);
+        PathCodeOwnerStatus.create(Path.of("/foo/new.baz"), CodeOwnerStatus.PENDING);
     PathCodeOwnerStatus oldPathCodeOwnerStatus =
-        PathCodeOwnerStatus.create(Paths.get("/foo/old.baz"), CodeOwnerStatus.APPROVED);
+        PathCodeOwnerStatus.create(Path.of("/foo/old.baz"), CodeOwnerStatus.APPROVED);
     FileCodeOwnerStatus fileCodeOwnerStatus =
         FileCodeOwnerStatus.create(
             changedFile, Optional.of(newPathCodeOwnerStatus), Optional.of(oldPathCodeOwnerStatus));
@@ -235,7 +235,7 @@
     ChangedFile changedFile = mock(ChangedFile.class);
     when(changedFile.changeType()).thenReturn(DiffEntry.ChangeType.ADD);
     PathCodeOwnerStatus pathCodeOwnerStatus =
-        PathCodeOwnerStatus.create(Paths.get("/foo/bar.baz"), CodeOwnerStatus.APPROVED);
+        PathCodeOwnerStatus.create(Path.of("/foo/bar.baz"), CodeOwnerStatus.APPROVED);
     FileCodeOwnerStatus fileCodeOwnerStatus =
         FileCodeOwnerStatus.create(changedFile, Optional.of(pathCodeOwnerStatus), Optional.empty());
     CodeOwnerStatusInfo codeOwnerStatusInfo =
@@ -265,7 +265,7 @@
     ChangedFile changedFile = mock(ChangedFile.class);
     when(changedFile.changeType()).thenReturn(DiffEntry.ChangeType.ADD);
     PathCodeOwnerStatus pathCodeOwnerStatus =
-        PathCodeOwnerStatus.builder(Paths.get("/foo/bar.baz"), CodeOwnerStatus.APPROVED)
+        PathCodeOwnerStatus.builder(Path.of("/foo/bar.baz"), CodeOwnerStatus.APPROVED)
             .addReason("one reason")
             .addReason("another reason")
             .build();
@@ -312,7 +312,7 @@
     ChangedFile changedFile = mock(ChangedFile.class);
     when(changedFile.changeType()).thenReturn(DiffEntry.ChangeType.ADD);
     PathCodeOwnerStatus pathCodeOwnerStatus =
-        PathCodeOwnerStatus.builder(Paths.get("/foo/bar.baz"), CodeOwnerStatus.APPROVED)
+        PathCodeOwnerStatus.builder(Path.of("/foo/bar.baz"), CodeOwnerStatus.APPROVED)
             .addReason(reason1)
             .addReason(reason2)
             .build();
@@ -349,7 +349,7 @@
     ChangedFile changedFile1 = mock(ChangedFile.class);
     when(changedFile1.changeType()).thenReturn(DiffEntry.ChangeType.ADD);
     PathCodeOwnerStatus pathCodeOwnerStatus1 =
-        PathCodeOwnerStatus.create(Paths.get("/foo/a/bar.baz"), CodeOwnerStatus.APPROVED);
+        PathCodeOwnerStatus.create(Path.of("/foo/a/bar.baz"), CodeOwnerStatus.APPROVED);
     FileCodeOwnerStatus fileCodeOwnerStatus1 =
         FileCodeOwnerStatus.create(
             changedFile1, Optional.of(pathCodeOwnerStatus1), Optional.empty());
@@ -357,7 +357,7 @@
     ChangedFile changedFile2 = mock(ChangedFile.class);
     when(changedFile2.changeType()).thenReturn(DiffEntry.ChangeType.DELETE);
     PathCodeOwnerStatus pathCodeOwnerStatus2 =
-        PathCodeOwnerStatus.create(Paths.get("/foo/b/bar.baz"), CodeOwnerStatus.APPROVED);
+        PathCodeOwnerStatus.create(Path.of("/foo/b/bar.baz"), CodeOwnerStatus.APPROVED);
     FileCodeOwnerStatus fileCodeOwnerStatus2 =
         FileCodeOwnerStatus.create(
             changedFile2, Optional.empty(), Optional.of(pathCodeOwnerStatus2));
@@ -365,9 +365,9 @@
     ChangedFile changedFile3 = mock(ChangedFile.class);
     when(changedFile3.changeType()).thenReturn(DiffEntry.ChangeType.DELETE);
     PathCodeOwnerStatus newPathCodeOwnerStatus3 =
-        PathCodeOwnerStatus.create(Paths.get("/foo/c/new.baz"), CodeOwnerStatus.APPROVED);
+        PathCodeOwnerStatus.create(Path.of("/foo/c/new.baz"), CodeOwnerStatus.APPROVED);
     PathCodeOwnerStatus oldPathCodeOwnerStatus3 =
-        PathCodeOwnerStatus.create(Paths.get("/foo/c/old.baz"), CodeOwnerStatus.APPROVED);
+        PathCodeOwnerStatus.create(Path.of("/foo/c/old.baz"), CodeOwnerStatus.APPROVED);
     FileCodeOwnerStatus fileCodeOwnerStatus3 =
         FileCodeOwnerStatus.create(
             changedFile3,
diff --git a/javatests/com/google/gerrit/plugins/codeowners/util/JgitPathTest.java b/javatests/com/google/gerrit/plugins/codeowners/util/JgitPathTest.java
index 4b73459..9571146 100644
--- a/javatests/com/google/gerrit/plugins/codeowners/util/JgitPathTest.java
+++ b/javatests/com/google/gerrit/plugins/codeowners/util/JgitPathTest.java
@@ -15,12 +15,11 @@
 package com.google.gerrit.plugins.codeowners.util;
 
 import static com.google.common.truth.Truth.assertThat;
-import static com.google.common.truth.Truth8.assertThat;
 import static com.google.gerrit.testing.GerritJUnit.assertThrows;
 
+import com.google.common.truth.Truth8;
 import com.google.gerrit.plugins.codeowners.acceptance.AbstractCodeOwnersTest;
 import java.nio.file.Path;
-import java.nio.file.Paths;
 import org.junit.Test;
 
 /** Tests for {@link com.google.gerrit.plugins.codeowners.util.JgitPath}. */
@@ -40,8 +39,8 @@
 
   @Test
   public void getJgitPathOfPath() throws Exception {
-    assertThat(JgitPath.of(Paths.get("foo/bar/OWNERS")).get()).isEqualTo("foo/bar/OWNERS");
-    assertThat(JgitPath.of(Paths.get("/foo/bar/OWNERS")).get()).isEqualTo("foo/bar/OWNERS");
+    assertThat(JgitPath.of(Path.of("foo/bar/OWNERS")).get()).isEqualTo("foo/bar/OWNERS");
+    assertThat(JgitPath.of(Path.of("/foo/bar/OWNERS")).get()).isEqualTo("foo/bar/OWNERS");
   }
 
   @Test
@@ -53,8 +52,8 @@
 
   @Test
   public void getPathAsAbsolutePath() throws Exception {
-    assertThat(JgitPath.of("foo/bar/OWNERS").getAsAbsolutePath())
-        .isEqualTo(Paths.get("/foo/bar/OWNERS"));
+    Truth8.assertThat(JgitPath.of("foo/bar/OWNERS").getAsAbsolutePath())
+        .isEqualTo(Path.of("/foo/bar/OWNERS"));
   }
 
   @Test
diff --git a/web/suggest-owners.ts b/web/suggest-owners.ts
index 4fe2a7d..7f07906 100644
--- a/web/suggest-owners.ts
+++ b/web/suggest-owners.ts
@@ -770,12 +770,12 @@
 
   private getOwnedByAllUsersContent() {
     if (this.selectedSuggestionsState === SuggestionsState.Loading) {
-      return 'Any user can approve';
+      return 'All users are considered owners';
     }
     // If all users own all the files in the change suggestedOwners.length === 1
     // (suggestedOwners - collection of owners groupbed by owners)
     return this.suggestedOwners && this.suggestedOwners.length === 1
-      ? 'Any user can approve. Please select a user manually'
+      ? 'All users are considered owners. Please select a user manually'
       : 'Any user from the other files can approve';
   }