This is an automated email from the ASF dual-hosted git repository.

mdrob pushed a commit to branch branch_9_0
in repository https://gitbox.apache.org/repos/asf/solr.git


The following commit(s) were added to refs/heads/branch_9_0 by this push:
     new 2dd1e74  SOLR-15919 Another pass as moving File to Path (#544)
2dd1e74 is described below

commit 2dd1e74434ffdd7ed41eb0128f1fd89742b038bb
Author: Mike Drob <[email protected]>
AuthorDate: Tue Jan 25 10:20:22 2022 -0600

    SOLR-15919 Another pass as moving File to Path (#544)
    
    (cherry picked from commit 86bf5e847bffb0b59514b0bf87236f5d10ae8389)
---
 .../org/apache/solr/bench/MiniClusterState.java    |   4 +-
 .../client/solrj/embedded/JettySolrRunner.java     |   4 +-
 .../java/org/apache/solr/cloud/SolrZkServer.java   |   2 +-
 .../org/apache/solr/core/ConfigSetService.java     |  70 +++++++-------
 .../java/org/apache/solr/handler/IndexFetcher.java |   2 +-
 .../apache/solr/handler/ReplicationHandler.java    |  90 +++++++++---------
 .../solr/handler/admin/ShowFileRequestHandler.java |  48 +++++-----
 .../handler/component/QueryElevationComponent.java |   6 +-
 .../solr/handler/component/SuggestComponent.java   |   9 +-
 .../designer/SchemaDesignerConfigSetHelper.java    |  74 +++++++--------
 .../apache/solr/rest/ManagedResourceStorage.java   |  15 +--
 .../org/apache/solr/schema/ManagedIndexSchema.java |  32 ++-----
 .../solr/schema/ManagedIndexSchemaFactory.java     |   2 +-
 .../solr/spelling/AbstractLuceneSpellChecker.java  |   3 +-
 .../solr/spelling/IndexBasedSpellChecker.java      |   4 +-
 .../solr/spelling/suggest/SolrSuggester.java       |  58 +++++-------
 .../apache/solr/spelling/suggest/Suggester.java    |  44 ++++-----
 .../org/apache/solr/update/TransactionLog.java     |  72 ++++++++-------
 .../src/java/org/apache/solr/update/UpdateLog.java | 102 +++++++++++----------
 .../src/java/org/apache/solr/util/PackageTool.java |   8 +-
 .../src/java/org/apache/solr/util/SolrCLI.java     |   4 +-
 .../java/org/apache/solr/util/SolrLogPostTool.java |  54 ++++-------
 .../apache/solr/cloud/BasicDistributedZkTest.java  |   2 +-
 .../apache/solr/cloud/SolrCloudExampleTest.java    |  42 +++++----
 .../org/apache/solr/cloud/TestConfigSetsAPI.java   |  12 ++-
 .../TestSchemaDesignerConfigSetHelper.java         |  24 +++++
 .../org/apache/solr/update/TransactionLogTest.java |  12 +--
 .../solrj/request/StreamingUpdateRequest.java      |   8 +-
 .../apache/solr/client/solrj/SolrExampleTests.java |   2 +-
 .../apache/solr/EmbeddedSolrServerTestBase.java    |   7 +-
 .../apache/solr/cloud/MiniSolrCloudCluster.java    |   4 +-
 31 files changed, 398 insertions(+), 422 deletions(-)

diff --git 
a/solr/benchmark/src/java/org/apache/solr/bench/MiniClusterState.java 
b/solr/benchmark/src/java/org/apache/solr/bench/MiniClusterState.java
index 33c7a65..80590c8 100755
--- a/solr/benchmark/src/java/org/apache/solr/bench/MiniClusterState.java
+++ b/solr/benchmark/src/java/org/apache/solr/bench/MiniClusterState.java
@@ -130,9 +130,7 @@ public class MiniClusterState {
               benchmarkParams.id(),
               String.valueOf(runCnt++),
               benchmarkParams.getBenchmark() + ".txt");
-      if (!Files.exists(metricsResults.getParent())) {
-        Files.createDirectories(metricsResults.getParent());
-      }
+      Files.createDirectories(metricsResults.getParent());
 
       cluster.dumpMetrics(
           metricsResults.getParent().toFile(), 
metricsResults.getFileName().toString());
diff --git 
a/solr/core/src/java/org/apache/solr/client/solrj/embedded/JettySolrRunner.java 
b/solr/core/src/java/org/apache/solr/client/solrj/embedded/JettySolrRunner.java
index fcb12dc..b0b2e99 100644
--- 
a/solr/core/src/java/org/apache/solr/client/solrj/embedded/JettySolrRunner.java
+++ 
b/solr/core/src/java/org/apache/solr/client/solrj/embedded/JettySolrRunner.java
@@ -718,9 +718,7 @@ public class JettySolrRunner {
 
       if (outputDirectory != null) {
         Path outDir = outputDirectory.toPath();
-        if (!Files.exists(outDir)) {
-          Files.createDirectories(outDir);
-        }
+        Files.createDirectories(outDir);
       }
 
       SolrMetricManager metricsManager = getCoreContainer().getMetricManager();
diff --git a/solr/core/src/java/org/apache/solr/cloud/SolrZkServer.java 
b/solr/core/src/java/org/apache/solr/cloud/SolrZkServer.java
index 6349aa8..ccb4315 100644
--- a/solr/core/src/java/org/apache/solr/cloud/SolrZkServer.java
+++ b/solr/core/src/java/org/apache/solr/cloud/SolrZkServer.java
@@ -54,7 +54,7 @@ public class SolrZkServer {
 
   private Thread zkThread;  // the thread running a zookeeper server, only if 
zkRun is set
 
-  private File dataHome;
+  private File dataHome; // o.a.zookeeper.**.QuorumPeerConfig needs a File not 
a Path
   private String confHome;
 
   public SolrZkServer(String zkRun, String zkHost, File dataHome, String 
confHome, int solrPort) {
diff --git a/solr/core/src/java/org/apache/solr/core/ConfigSetService.java 
b/solr/core/src/java/org/apache/solr/core/ConfigSetService.java
index 73e3f20..aa3486d 100644
--- a/solr/core/src/java/org/apache/solr/core/ConfigSetService.java
+++ b/solr/core/src/java/org/apache/solr/core/ConfigSetService.java
@@ -16,13 +16,11 @@
  */
 package org.apache.solr.core;
 
-import java.io.File;
 import java.io.IOException;
 import java.lang.invoke.MethodHandles;
 import java.lang.reflect.Constructor;
 import java.nio.file.Files;
 import java.nio.file.Path;
-import java.nio.file.Paths;
 import java.util.List;
 import java.util.Locale;
 import java.util.Map;
@@ -109,20 +107,20 @@ public abstract class ConfigSetService {
 
   private void bootstrapDefaultConf() throws IOException {
     if (this.checkConfigExists("_default") == false) {
-      String configDirPath = getDefaultConfigDirPath();
+      Path configDirPath = getDefaultConfigDirPath();
       if (configDirPath == null) {
         log.warn(
             "The _default configset could not be uploaded. Please provide 
'solr.default.confdir' parameter that points to a configset {} {}",
             "intended to be the default. Current 'solr.default.confdir' 
value:",
             
System.getProperty(SolrDispatchFilter.SOLR_DEFAULT_CONFDIR_ATTRIBUTE));
       } else {
-        this.uploadConfig(ConfigSetsHandler.DEFAULT_CONFIGSET_NAME, 
Paths.get(configDirPath));
+        this.uploadConfig(ConfigSetsHandler.DEFAULT_CONFIGSET_NAME, 
configDirPath);
       }
     }
   }
 
   private void bootstrapConfDir(String confDir) throws IOException {
-    Path configPath = Paths.get(confDir);
+    Path configPath = Path.of(confDir);
     if (!Files.isDirectory(configPath)) {
       throw new IllegalArgumentException ("bootstrap_confdir must be a 
directory of configuration files, configPath: " + configPath);
     }
@@ -139,62 +137,56 @@ public abstract class ConfigSetService {
    * @lucene.internal
    * @see SolrDispatchFilter#SOLR_DEFAULT_CONFDIR_ATTRIBUTE
    */
-  public static String getDefaultConfigDirPath() {
-    String configDirPath = null;
-    String serverSubPath =
-        "solr"
-            + File.separator
-            + "configsets"
-            + File.separator
-            + "_default"
-            + File.separator
-            + "conf";
-    String subPath = File.separator + "server" + File.separator + 
serverSubPath;
-    if (System.getProperty(SolrDispatchFilter.SOLR_DEFAULT_CONFDIR_ATTRIBUTE) 
!= null
-        && new 
File(System.getProperty(SolrDispatchFilter.SOLR_DEFAULT_CONFDIR_ATTRIBUTE))
-            .exists()) {
-      configDirPath =
-          new 
File(System.getProperty(SolrDispatchFilter.SOLR_DEFAULT_CONFDIR_ATTRIBUTE))
-              .getAbsolutePath();
-    } else if 
(System.getProperty(SolrDispatchFilter.SOLR_INSTALL_DIR_ATTRIBUTE) != null
-        && new 
File(System.getProperty(SolrDispatchFilter.SOLR_INSTALL_DIR_ATTRIBUTE) + 
subPath)
-            .exists()) {
-      configDirPath =
-          new 
File(System.getProperty(SolrDispatchFilter.SOLR_INSTALL_DIR_ATTRIBUTE) + 
subPath)
-              .getAbsolutePath();
+  public static Path getDefaultConfigDirPath() {
+    String confDir = 
System.getProperty(SolrDispatchFilter.SOLR_DEFAULT_CONFDIR_ATTRIBUTE);
+    if (confDir != null) {
+      Path path = Path.of(confDir);
+      if (Files.exists(path)) {
+        return path;
+      }
+    }
+
+    String installDir = 
System.getProperty(SolrDispatchFilter.SOLR_INSTALL_DIR_ATTRIBUTE);
+    if (installDir != null) {
+      Path subPath = Path.of("server", "solr", "configsets", "_default", 
"conf");
+      Path path = Path.of(installDir).resolve(subPath);
+      if (Files.exists(path)) {
+        return path;
+      }
     }
-    return configDirPath;
+
+    return null;
   }
 
   // Order is important here since "confDir" may be
   // 1> a full path to the parent of a solrconfig.xml or parent of 
/conf/solrconfig.xml
   // 2> one of the canned config sets only, e.g. _default
   // and trying to assemble a path for configsetDir/confDir is A Bad Idea. if 
confDir is a full path.
-  public static Path getConfigsetPath(String confDir, String configSetDir) 
throws IOException {
+  public static Path getConfigsetPath(String confDir, String configSetDir) {
 
     // A local path to the source, probably already includes "conf".
-    Path ret = Paths.get(confDir, "solrconfig.xml").normalize();
+    Path ret = Path.of(confDir, "solrconfig.xml").normalize();
     if (Files.exists(ret)) {
-      return Paths.get(confDir).normalize();
+      return Path.of(confDir).normalize();
     }
 
     // a local path to the parent of a "conf" directory
-    ret = Paths.get(confDir, "conf", "solrconfig.xml").normalize();
+    ret = Path.of(confDir, "conf", "solrconfig.xml").normalize();
     if (Files.exists(ret)) {
-      return Paths.get(confDir, "conf").normalize();
+      return Path.of(confDir, "conf").normalize();
     }
 
     // one of the canned configsets.
-    ret = Paths.get(configSetDir, confDir, "conf", 
"solrconfig.xml").normalize();
+    ret = Path.of(configSetDir, confDir, "conf", "solrconfig.xml").normalize();
     if (Files.exists(ret)) {
-      return Paths.get(configSetDir, confDir, "conf").normalize();
+      return Path.of(configSetDir, confDir, "conf").normalize();
     }
 
     throw new IllegalArgumentException(String.format(Locale.ROOT,
             "Could not find solrconfig.xml at %s, %s or %s",
-            Paths.get(configSetDir, 
"solrconfig.xml").normalize().toAbsolutePath().toString(),
-            Paths.get(configSetDir, "conf", 
"solrconfig.xml").normalize().toAbsolutePath().toString(),
-            Paths.get(configSetDir, confDir, "conf", 
"solrconfig.xml").normalize().toAbsolutePath().toString()
+            Path.of(configSetDir, 
"solrconfig.xml").normalize().toAbsolutePath().toString(),
+            Path.of(configSetDir, "conf", 
"solrconfig.xml").normalize().toAbsolutePath().toString(),
+            Path.of(configSetDir, confDir, "conf", 
"solrconfig.xml").normalize().toAbsolutePath().toString()
     ));
   }
 
diff --git a/solr/core/src/java/org/apache/solr/handler/IndexFetcher.java 
b/solr/core/src/java/org/apache/solr/handler/IndexFetcher.java
index 2b210ad..5aaf86a 100644
--- a/solr/core/src/java/org/apache/solr/handler/IndexFetcher.java
+++ b/solr/core/src/java/org/apache/solr/handler/IndexFetcher.java
@@ -1030,7 +1030,7 @@ public class IndexFetcher {
           }
           // A hard link here should survive the eventual directory move, and 
should be more space efficient as
           // compared to a file copy. TODO: Maybe we could do a move safely 
here?
-          Files.createLink(new File(tmpIndexDirPath, filename).toPath(), 
localFile.toPath());
+          Files.createLink(Path.of(tmpIndexDirPath, filename), 
localFile.toPath());
           bytesSkippedCopying += localFile.length();
         } else {
           dirFileFetcher = new DirectoryFileFetcher(tmpIndexDir, file,
diff --git a/solr/core/src/java/org/apache/solr/handler/ReplicationHandler.java 
b/solr/core/src/java/org/apache/solr/handler/ReplicationHandler.java
index 28fb05a..74d4548 100644
--- a/solr/core/src/java/org/apache/solr/handler/ReplicationHandler.java
+++ b/solr/core/src/java/org/apache/solr/handler/ReplicationHandler.java
@@ -16,7 +16,6 @@
  */
 package org.apache.solr.handler;
 
-import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileNotFoundException;
 import java.io.IOException;
@@ -26,8 +25,9 @@ import java.io.OutputStream;
 import java.lang.invoke.MethodHandles;
 import java.net.URI;
 import java.nio.ByteBuffer;
-import java.nio.channels.FileChannel;
+import java.nio.channels.SeekableByteChannel;
 import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
 import java.nio.file.NoSuchFileException;
 import java.nio.file.Path;
 import java.nio.file.Paths;
@@ -424,20 +424,16 @@ public class ReplicationHandler extends 
RequestHandlerBase implements SolrCoreAw
     return l;
   }
 
-  static Long getCheckSum(Checksum checksum, File f) {
-    FileInputStream fis = null;
+  static Long getCheckSum(Checksum checksum, Path f) {
     checksum.reset();
     byte[] buffer = new byte[1024 * 1024];
-    int bytesRead;
-    try {
-      fis = new FileInputStream(f);
-      while ((bytesRead = fis.read(buffer)) >= 0)
+    try (InputStream in = Files.newInputStream(f)) {
+      int bytesRead;
+      while ((bytesRead = in.read(buffer)) >= 0)
         checksum.update(buffer, 0, bytesRead);
       return checksum.getValue();
     } catch (Exception e) {
       log.warn("Exception in finding checksum of {}", f, e);
-    } finally {
-      IOUtils.closeQuietly(fis);
     }
     return null;
   }
@@ -784,12 +780,20 @@ public class ReplicationHandler extends 
RequestHandlerBase implements SolrCoreAw
       Checksum checksum = null;
       for (int i = 0; i < nameAndAlias.size(); i++) {
         String cf = nameAndAlias.getName(i);
-        File f = new File(core.getResourceLoader().getConfigDir(), cf);
-        if (!f.exists() || f.isDirectory()) continue; //must not happen
+        Path f = core.getResourceLoader().getConfigPath().resolve(cf);
+        if (!Files.exists(f) || Files.isDirectory(f)) continue; //must not 
happen
         FileInfo info = confFileInfoCache.get(cf);
-        if (info == null || info.lastmodified != f.lastModified() || info.size 
!= f.length()) {
+        long lastModified = 0;
+        long size = 0;
+        try {
+          lastModified = Files.getLastModifiedTime(f).toMillis();
+          size = Files.size(f);
+        } catch (IOException e) {
+          // proceed with zeroes for now, will probably error on checksum 
anyway
+        }
+        if (info == null || info.lastmodified != lastModified || info.size != 
size) {
           if (checksum == null) checksum = new Adler32();
-          info = new FileInfo(f.lastModified(), cf, f.length(), 
getCheckSum(checksum, f));
+          info = new FileInfo(lastModified, cf, size, getCheckSum(checksum, 
f));
           confFileInfoCache.put(cf, info);
         }
         Map<String, Object> m = info.getAsMap();
@@ -1651,14 +1655,14 @@ public class ReplicationHandler extends 
RequestHandlerBase implements SolrCoreAw
    */
   private abstract class LocalFsFileStream extends DirectoryFileStream {
 
-    private File file;
+    private Path file;
 
     public LocalFsFileStream(SolrParams solrParams) {
       super(solrParams);
       this.file = this.initFile();
     }
 
-    protected abstract File initFile();
+    protected abstract Path initFile();
 
     @Override
     public void write(OutputStream out) throws IOException {
@@ -1667,30 +1671,30 @@ public class ReplicationHandler extends 
RequestHandlerBase implements SolrCoreAw
       try {
         initWrite();
 
-        if (file.exists() && file.canRead()) {
-          inputStream = new FileInputStream(file);
-          FileChannel channel = inputStream.getChannel();
-          //if offset is mentioned move the pointer to that point
-          if (offset != -1)
-            channel.position(offset);
-          ByteBuffer bb = ByteBuffer.wrap(buf);
-
-          while (true) {
-            bb.clear();
-            long bytesRead = channel.read(bb);
-            if (bytesRead <= 0) {
-              writeNothingAndFlush();
-              fos.close(); // we close because DeflaterOutputStream requires a 
close call, but but the request outputstream is protected
-              break;
-            }
-            fos.writeInt((int) bytesRead);
-            if (useChecksum) {
-              checksum.reset();
-              checksum.update(buf, 0, (int) bytesRead);
-              fos.writeLong(checksum.getValue());
+        if (Files.isReadable(file)) {
+          try (SeekableByteChannel channel = Files.newByteChannel(file)) {
+            //if offset is mentioned move the pointer to that point
+            if (offset != -1)
+              channel.position(offset);
+            ByteBuffer bb = ByteBuffer.wrap(buf);
+
+            while (true) {
+              bb.clear();
+              long bytesRead = channel.read(bb);
+              if (bytesRead <= 0) {
+                writeNothingAndFlush();
+                fos.close(); // we close because DeflaterOutputStream requires 
a close call, but the request outputstream is protected
+                break;
+              }
+              fos.writeInt((int) bytesRead);
+              if (useChecksum) {
+                checksum.reset();
+                checksum.update(buf, 0, (int) bytesRead);
+                fos.writeLong(checksum.getValue());
+              }
+              fos.write(buf, 0, (int) bytesRead);
+              fos.flush();
             }
-            fos.write(buf, 0, (int) bytesRead);
-            fos.flush();
           }
         } else {
           writeNothingAndFlush();
@@ -1710,9 +1714,9 @@ public class ReplicationHandler extends 
RequestHandlerBase implements SolrCoreAw
       super(solrParams);
     }
 
-    protected File initFile() {
+    protected Path initFile() {
       //if it is a tlog file read from tlog directory
-      return new File(core.getUpdateHandler().getUpdateLog().getLogDir(), 
tlogFileName);
+      return Path.of(core.getUpdateHandler().getUpdateLog().getLogDir(), 
tlogFileName);
     }
 
   }
@@ -1723,9 +1727,9 @@ public class ReplicationHandler extends 
RequestHandlerBase implements SolrCoreAw
       super(solrParams);
     }
 
-    protected File initFile() {
+    protected Path initFile() {
       //if it is a conf file read from config directory
-      return 
core.getResourceLoader().getConfigPath().resolve(cfileName).toFile();
+      return core.getResourceLoader().getConfigPath().resolve(cfileName);
     }
 
   }
diff --git 
a/solr/core/src/java/org/apache/solr/handler/admin/ShowFileRequestHandler.java 
b/solr/core/src/java/org/apache/solr/handler/admin/ShowFileRequestHandler.java
index 0fd998d..e944fb5 100644
--- 
a/solr/core/src/java/org/apache/solr/handler/admin/ShowFileRequestHandler.java
+++ 
b/solr/core/src/java/org/apache/solr/handler/admin/ShowFileRequestHandler.java
@@ -46,6 +46,7 @@ import java.io.IOException;
 import java.io.UnsupportedEncodingException;
 import java.lang.invoke.MethodHandles;
 import java.net.URISyntaxException;
+import java.nio.file.Files;
 import java.nio.file.Path;
 import java.util.Date;
 import java.util.HashSet;
@@ -198,28 +199,29 @@ public class ShowFileRequestHandler extends 
RequestHandlerBase implements Permis
 
   // Return the file indicated (or the directory listing) from the local file 
system.
   private void showFromFileSystem(SolrQueryRequest req, SolrQueryResponse rsp) 
{
-    File adminFile = getAdminFileFromFileSystem(req, rsp, hiddenFiles);
+    Path admin = getAdminFileFromFileSystem(req, rsp, hiddenFiles);
 
-    if (adminFile == null) { // exception already recorded
+    if (admin == null) { // exception already recorded
       return;
     }
 
+    File adminFile = admin.toFile();
     // Make sure the file exists, is readable and is not a hidden file
     if( !adminFile.exists() ) {
       log.error("Can not find: {} [{}]", adminFile.getName(), 
adminFile.getAbsolutePath());
       rsp.setException(new SolrException
-                       ( ErrorCode.NOT_FOUND, "Can not find: 
"+adminFile.getName() 
+                       ( ErrorCode.NOT_FOUND, "Can not find: 
"+adminFile.getName()
                          + " ["+adminFile.getAbsolutePath()+"]" ));
       return;
     }
     if( !adminFile.canRead() || adminFile.isHidden() ) {
       log.error("Can not show: {} [{}]", adminFile.getName(), 
adminFile.getAbsolutePath());
       rsp.setException(new SolrException
-                       ( ErrorCode.NOT_FOUND, "Can not show: 
"+adminFile.getName() 
+                       ( ErrorCode.NOT_FOUND, "Can not show: 
"+adminFile.getName()
                          + " ["+adminFile.getAbsolutePath()+"]" ));
       return;
     }
-    
+
     // Show a directory listing
     if( adminFile.isDirectory() ) {
       // it's really a directory, just go for it.
@@ -236,7 +238,7 @@ public class ShowFileRequestHandler extends 
RequestHandlerBase implements Permis
         SimpleOrderedMap<Object> fileInfo = new SimpleOrderedMap<>();
         files.add( path, fileInfo );
         if( f.isDirectory() ) {
-          fileInfo.add( "directory", true ); 
+          fileInfo.add( "directory", true );
         }
         else {
           // TODO? content type
@@ -350,15 +352,14 @@ public class ShowFileRequestHandler extends 
RequestHandlerBase implements Permis
 
   // Find the file indicated by the "file=XXX" parameter or the root of the 
conf directory on the local
   // file system. Respects all the "interesting" stuff around what the 
resource loader does to find files.
-  public static File getAdminFileFromFileSystem(SolrQueryRequest req, 
SolrQueryResponse rsp,
+  public static Path getAdminFileFromFileSystem(SolrQueryRequest req, 
SolrQueryResponse rsp,
                                                 Set<String> hiddenFiles) {
-    File adminFile = null;
     final SolrResourceLoader loader = req.getCore().getResourceLoader();
-    File configdir = new File( loader.getConfigDir() );
-    if (!configdir.exists()) {
+    Path configDir = loader.getConfigPath();
+    if (!Files.exists(configDir)) {
       // TODO: maybe we should just open it this way to start with?
       try {
-        configdir = new File( 
loader.getClassLoader().getResource(loader.getConfigDir()).toURI() );
+        configDir = 
Path.of(loader.getClassLoader().getResource(loader.getConfigDir()).toURI());
       } catch (URISyntaxException e) {
         log.error("Can not access configuration directory!");
         rsp.setException(new SolrException( SolrException.ErrorCode.FORBIDDEN, 
"Can not access configuration directory!", e));
@@ -367,20 +368,19 @@ public class ShowFileRequestHandler extends 
RequestHandlerBase implements Permis
     }
     String fname = req.getParams().get("file", null);
     if( fname == null ) {
-      adminFile = configdir;
-    } else {
-      fname = fname.replace( '\\', '/' ); // normalize slashes
-      if( hiddenFiles.contains( fname.toUpperCase(Locale.ROOT) ) ) {
-        log.error("Can not access: {}", fname);
-        rsp.setException(new SolrException( SolrException.ErrorCode.FORBIDDEN, 
"Can not access: "+fname ));
-        return null;
-      }
-      // A leading slash is unnecessary but supported and interpreted as start 
of config dir
-      Path filePath = configdir.toPath().resolve(fname.startsWith("/") ? 
fname.substring(1) : fname);
-      req.getCore().getCoreContainer().assertPathAllowed(filePath);
-      adminFile = filePath.toFile();
+      return configDir;
     }
-    return adminFile;
+
+    fname = fname.replace( '\\', '/' ); // normalize slashes
+    if( hiddenFiles.contains( fname.toUpperCase(Locale.ROOT) ) ) {
+      log.error("Can not access: {}", fname);
+      rsp.setException(new SolrException( SolrException.ErrorCode.FORBIDDEN, 
"Can not access: "+fname ));
+      return null;
+    }
+    // A leading slash is unnecessary but supported and interpreted as start 
of config dir
+    Path filePath = configDir.resolve(fname.startsWith("/") ? 
fname.substring(1) : fname);
+    req.getCore().getCoreContainer().assertPathAllowed(filePath);
+    return filePath;
   }
 
   public final Set<String> getHiddenFiles() {
diff --git 
a/solr/core/src/java/org/apache/solr/handler/component/QueryElevationComponent.java
 
b/solr/core/src/java/org/apache/solr/handler/component/QueryElevationComponent.java
index b63e44b..2106bf6 100644
--- 
a/solr/core/src/java/org/apache/solr/handler/component/QueryElevationComponent.java
+++ 
b/solr/core/src/java/org/apache/solr/handler/component/QueryElevationComponent.java
@@ -340,12 +340,12 @@ public class QueryElevationComponent extends 
SearchComponent implements SolrCore
   protected long getConfigVersion(SolrCore core) {
     // TODO move this mechanism to a SolrResourceLoader.getVersion / 
getLastModTime
     try {
-      String configDir = core.getResourceLoader().getConfigDir(); // 
unsupported in ZK
-      Path cfg = Path.of(configDir).resolve(configFileName);
+      // unsupported in ZK
+      Path cfg = 
core.getResourceLoader().getConfigPath().resolve(configFileName);
       return Files.getLastModifiedTime(cfg).toMillis();
     } catch (Exception ignore) {
+      return -1; // don't know  (e.g. Zookeeper as of this writing)
     }
-    return -1; // don't know  (e.g. Zookeeper as of this writing)
   }
 
   /**
diff --git 
a/solr/core/src/java/org/apache/solr/handler/component/SuggestComponent.java 
b/solr/core/src/java/org/apache/solr/handler/component/SuggestComponent.java
index 4402862..5f3b9b1 100644
--- a/solr/core/src/java/org/apache/solr/handler/component/SuggestComponent.java
+++ b/solr/core/src/java/org/apache/solr/handler/component/SuggestComponent.java
@@ -43,9 +43,10 @@ import org.apache.solr.util.plugin.SolrCoreAware;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.io.File;
 import java.io.IOException;
 import java.lang.invoke.MethodHandles;
+import java.nio.file.Files;
+import java.nio.file.Path;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
@@ -138,8 +139,8 @@ public class SuggestComponent extends SearchComponent 
implements SolrCoreAware,
           boolean buildOnStartup;
           Object buildOnStartupObj = 
suggesterParams.get(BUILD_ON_STARTUP_LABEL);
           if (buildOnStartupObj == null) {
-            File storeFile = suggester.getStoreFile();
-            buildOnStartup = storeFile == null || !storeFile.exists();
+            Path storeFile = suggester.getStoreFile();
+            buildOnStartup = storeFile == null || !Files.exists(storeFile);
           } else {
             buildOnStartup = Boolean.parseBoolean((String) buildOnStartupObj);
           }
@@ -185,7 +186,7 @@ public class SuggestComponent extends SearchComponent 
implements SolrCoreAware,
       rb.rsp.add("command", (!buildAll) ? "build" : "buildAll");
     } else if (params.getBool(SUGGEST_RELOAD, false) || reloadAll) {
       for (SolrSuggester suggester : querysuggesters) {
-        suggester.reload(rb.req.getCore(), rb.req.getSearcher());
+        suggester.reload();
       }
       rb.rsp.add("command", (!reloadAll) ? "reload" : "reloadAll");
     }
diff --git 
a/solr/core/src/java/org/apache/solr/handler/designer/SchemaDesignerConfigSetHelper.java
 
b/solr/core/src/java/org/apache/solr/handler/designer/SchemaDesignerConfigSetHelper.java
index a6a3365..8fd476d 100644
--- 
a/solr/core/src/java/org/apache/solr/handler/designer/SchemaDesignerConfigSetHelper.java
+++ 
b/solr/core/src/java/org/apache/solr/handler/designer/SchemaDesignerConfigSetHelper.java
@@ -18,15 +18,17 @@
 package org.apache.solr.handler.designer;
 
 import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.FileInputStream;
 import java.io.IOException;
+import java.io.InputStream;
 import java.lang.invoke.MethodHandles;
 import java.net.URI;
 import java.net.URISyntaxException;
 import java.nio.charset.StandardCharsets;
+import java.nio.file.FileVisitResult;
 import java.nio.file.Files;
 import java.nio.file.Path;
+import java.nio.file.SimpleFileVisitor;
+import java.nio.file.attribute.BasicFileAttributes;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
@@ -1012,51 +1014,41 @@ class SchemaDesignerConfigSetHelper implements 
SchemaDesignerConstants {
   byte[] downloadAndZipConfigSet(String configId) throws IOException {
     ByteArrayOutputStream baos = new ByteArrayOutputStream();
     Path tmpDirectory = Files.createTempDirectory("schema-designer-" + 
FilenameUtils.getName(configId));
-    File tmpDir = tmpDirectory.toFile();
     try {
       cc.getConfigSetService().downloadConfig(configId, tmpDirectory);
       try (ZipOutputStream zipOut = new ZipOutputStream(baos)) {
-        zipIt(tmpDir, "", zipOut);
-      }
-    } finally {
-      FileUtils.deleteDirectory(tmpDir);
-    }
-    return baos.toByteArray();
-  }
-
-  protected void zipIt(File f, String fileName, ZipOutputStream zipOut) throws 
IOException {
-    if (f.isHidden()) {
-      return;
-    }
+        Files.walkFileTree(tmpDirectory, new SimpleFileVisitor<>() {
+          @Override
+          public FileVisitResult preVisitDirectory(Path dir, 
BasicFileAttributes attrs) throws IOException {
+            if (Files.isHidden(dir)) {
+              return FileVisitResult.SKIP_SUBTREE;
+            }
 
-    if (f.isDirectory()) {
-      String dirPrefix = "";
-      if (fileName.endsWith("/")) {
-        zipOut.putNextEntry(new ZipEntry(fileName));
-        zipOut.closeEntry();
-        dirPrefix = fileName;
-      } else if (!fileName.isEmpty()) {
-        dirPrefix = fileName + "/";
-        zipOut.putNextEntry(new ZipEntry(dirPrefix));
-        zipOut.closeEntry();
-      }
-      File[] files = f.listFiles();
-      if (files != null) {
-        for (File child : files) {
-          zipIt(child, dirPrefix + child.getName(), zipOut);
-        }
-      }
-      return;
-    }
+            String dirName = tmpDirectory.relativize(dir).toString();
+            if (!dirName.endsWith("/")) {
+              dirName += "/";
+            }
+            zipOut.putNextEntry(new ZipEntry(dirName));
+            zipOut.closeEntry();
+            return FileVisitResult.CONTINUE;
+          }
 
-    byte[] bytes = new byte[1024];
-    int r;
-    try (FileInputStream fis = new FileInputStream(f)) {
-      ZipEntry zipEntry = new ZipEntry(fileName);
-      zipOut.putNextEntry(zipEntry);
-      while ((r = fis.read(bytes)) >= 0) {
-        zipOut.write(bytes, 0, r);
+          @Override
+          public FileVisitResult visitFile(Path file, BasicFileAttributes 
attrs) throws IOException {
+            if (! Files.isHidden(file)) {
+              try (InputStream fis = Files.newInputStream(file)) {
+                ZipEntry zipEntry = new 
ZipEntry(tmpDirectory.relativize(file).toString());
+                zipOut.putNextEntry(zipEntry);
+                fis.transferTo(zipOut);
+              }
+            }
+            return FileVisitResult.CONTINUE;
+          }
+        });
       }
+    } finally {
+      FileUtils.deleteDirectory(tmpDirectory.toFile());
     }
+    return baos.toByteArray();
   }
 }
diff --git 
a/solr/core/src/java/org/apache/solr/rest/ManagedResourceStorage.java 
b/solr/core/src/java/org/apache/solr/rest/ManagedResourceStorage.java
index 382c49a..1bd1e8e 100644
--- a/solr/core/src/java/org/apache/solr/rest/ManagedResourceStorage.java
+++ b/solr/core/src/java/org/apache/solr/rest/ManagedResourceStorage.java
@@ -32,6 +32,7 @@ import java.lang.invoke.MethodHandles;
 import java.nio.charset.Charset;
 import java.nio.charset.StandardCharsets;
 import java.nio.file.Files;
+import java.nio.file.Path;
 import java.util.HashMap;
 import java.util.Locale;
 import java.util.Map;
@@ -119,20 +120,22 @@ public abstract class ManagedResourceStorage {
     if (storageIO instanceof FileStorageIO) {
       // using local fs, if storageDir is not set in the solrconfig.xml, 
assume the configDir for the core
       if (initArgs.get(STORAGE_DIR_INIT_ARG) == null) {
-        File configDir = new File(resourceLoader.getConfigDir());
-        boolean hasAccess = false;
+        Path configDir = resourceLoader.getConfigPath();
+        boolean hasAccess;
         try {
-          hasAccess = configDir.isDirectory() && configDir.canWrite();
-        } catch (java.security.AccessControlException ace) {}
+          hasAccess = Files.isDirectory(configDir) && 
Files.isWritable(configDir);
+        } catch (SecurityException noAccess) {
+          hasAccess = false;
+        }
         
         if (hasAccess) {
-          initArgs.add(STORAGE_DIR_INIT_ARG, configDir.getAbsolutePath());
+          initArgs.add(STORAGE_DIR_INIT_ARG, 
configDir.toAbsolutePath().toString());
         } else {
           // most likely this is because of a unit test 
           // that doesn't have write-access to the config dir
           // while this failover approach is not ideal, it's better
           // than causing the core to fail esp. if managed resources aren't 
being used
-          log.warn("Cannot write to config directory {} ; switching to use 
InMemory storage instead.", configDir.getAbsolutePath());
+          log.warn("Cannot write to config directory {} ; switching to use 
InMemory storage instead.", configDir.toAbsolutePath());
           storageIO = new ManagedResourceStorage.InMemoryStorageIO();
         }
       }       
diff --git a/solr/core/src/java/org/apache/solr/schema/ManagedIndexSchema.java 
b/solr/core/src/java/org/apache/solr/schema/ManagedIndexSchema.java
index 7ebc540..2b57294 100644
--- a/solr/core/src/java/org/apache/solr/schema/ManagedIndexSchema.java
+++ b/solr/core/src/java/org/apache/solr/schema/ManagedIndexSchema.java
@@ -16,13 +16,13 @@
  */
 package org.apache.solr.schema;
 
-import java.io.File;
-import java.io.FileOutputStream;
 import java.io.IOException;
-import java.io.OutputStreamWriter;
 import java.io.StringWriter;
+import java.io.Writer;
 import java.lang.invoke.MethodHandles;
 import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
@@ -39,9 +39,9 @@ import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Future;
 import java.util.concurrent.TimeUnit;
 
-import org.apache.commons.io.IOUtils;
 import org.apache.lucene.analysis.Analyzer;
 import org.apache.lucene.analysis.CharFilterFactory;
+import org.apache.lucene.util.IOUtils;
 import org.apache.lucene.util.ResourceLoaderAware;
 import org.apache.lucene.analysis.TokenFilterFactory;
 import org.apache.lucene.analysis.TokenizerFactory;
@@ -72,7 +72,6 @@ import org.apache.solr.core.SolrConfig;
 import org.apache.solr.core.SolrResourceLoader;
 import org.apache.solr.rest.schema.FieldTypeXmlAdapter;
 import org.apache.solr.util.DOMConfigNode;
-import org.apache.solr.util.FileUtils;
 import org.apache.solr.util.RTimer;
 import org.apache.zookeeper.CreateMode;
 import org.apache.zookeeper.KeeperException;
@@ -122,31 +121,20 @@ public final class ManagedIndexSchema extends IndexSchema 
{
       return persistManagedSchemaToZooKeeper(createOnly);
     }
     // Persist locally
-    File managedSchemaFile = new File(loader.getConfigDir(), 
managedSchemaResourceName);
-    OutputStreamWriter writer = null;
+    Path managedSchemaFile = 
loader.getConfigPath().resolve(managedSchemaResourceName);
     try {
-      File parentDir = managedSchemaFile.getParentFile();
-      if ( ! parentDir.isDirectory()) {
-        if ( ! parentDir.mkdirs()) {
-          final String msg = "Can't create managed schema directory " + 
parentDir.getAbsolutePath();
-          log.error(msg);
-          throw new SolrException(ErrorCode.SERVER_ERROR, msg);
-        }
-      }
-      final FileOutputStream out = new FileOutputStream(managedSchemaFile);
-      writer = new OutputStreamWriter(out, StandardCharsets.UTF_8);
-      persist(writer);
-      if (log.isInfoEnabled()) {
-        log.info("Upgraded to managed schema at {}", 
managedSchemaFile.getPath());
+      Files.createDirectories(managedSchemaFile.getParent());
+      try (Writer out = Files.newBufferedWriter(managedSchemaFile, 
StandardCharsets.UTF_8)) {
+        persist(out);
       }
+      log.info("Upgraded to managed schema at {}", managedSchemaFile);
     } catch (IOException e) {
       final String msg = "Error persisting managed schema " + 
managedSchemaFile;
       log.error(msg, e);
       throw new SolrException(ErrorCode.SERVER_ERROR, msg, e);
     } finally {
-      IOUtils.closeQuietly(writer);
       try {
-        FileUtils.sync(managedSchemaFile);
+        IOUtils.fsync(managedSchemaFile, false);
       } catch (IOException e) {
         final String msg = "Error syncing the managed schema file " + 
managedSchemaFile;
         log.error(msg, e);
diff --git 
a/solr/core/src/java/org/apache/solr/schema/ManagedIndexSchemaFactory.java 
b/solr/core/src/java/org/apache/solr/schema/ManagedIndexSchemaFactory.java
index f027486..a71d705 100644
--- a/solr/core/src/java/org/apache/solr/schema/ManagedIndexSchemaFactory.java
+++ b/solr/core/src/java/org/apache/solr/schema/ManagedIndexSchemaFactory.java
@@ -166,7 +166,7 @@ public class ManagedIndexSchemaFactory extends 
IndexSchemaFactory implements Sol
    * Once the IndexSchema is instantiated, if the managed schema file does not 
exist,
    * the instantiated IndexSchema is persisted to the managed schema file 
named in the
    * managedSchemaResourceName param, in the directory given by
-   * {@link org.apache.solr.core.SolrResourceLoader#getConfigDir()}, or if 
configs are
+   * {@link SolrResourceLoader#getConfigPath()}, or if configs are
    * in ZooKeeper, under {@link 
org.apache.solr.cloud.ZkSolrResourceLoader#getConfigSetZkPath()}.
    *
    * After the managed schema file is persisted, the original schema file is
diff --git 
a/solr/core/src/java/org/apache/solr/spelling/AbstractLuceneSpellChecker.java 
b/solr/core/src/java/org/apache/solr/spelling/AbstractLuceneSpellChecker.java
index c068c64..4e6dd02 100644
--- 
a/solr/core/src/java/org/apache/solr/spelling/AbstractLuceneSpellChecker.java
+++ 
b/solr/core/src/java/org/apache/solr/spelling/AbstractLuceneSpellChecker.java
@@ -18,6 +18,7 @@ package org.apache.solr.spelling;
 
 import java.io.File;
 import java.io.IOException;
+import java.nio.file.Path;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.Comparator;
@@ -223,7 +224,7 @@ public abstract class AbstractLuceneSpellChecker extends 
SolrSpellChecker {
       // Windows causes problems because deleted files can't be opened.  It 
would be better for SpellChecker to hold a single IW instance,
       // and close it on close, but Solr never seems to close its spell 
checkers.  Wrapping as FilterDirectory prevents IndexWriter from
       // catching the pending deletions:
-      index = new FilterDirectory(FSDirectory.open(new 
File(indexDir).toPath())) {
+      index = new FilterDirectory(FSDirectory.open(Path.of(indexDir))) {
       };
     } else {
       index = new ByteBuffersDirectory();
diff --git 
a/solr/core/src/java/org/apache/solr/spelling/IndexBasedSpellChecker.java 
b/solr/core/src/java/org/apache/solr/spelling/IndexBasedSpellChecker.java
index 416cfad..97155db 100644
--- a/solr/core/src/java/org/apache/solr/spelling/IndexBasedSpellChecker.java
+++ b/solr/core/src/java/org/apache/solr/spelling/IndexBasedSpellChecker.java
@@ -25,8 +25,8 @@ import org.apache.solr.common.util.NamedList;
 import org.apache.solr.core.SolrCore;
 import org.apache.solr.search.SolrIndexSearcher;
 
-import java.io.File;
 import java.io.IOException;
+import java.nio.file.Path;
 
 /**
  * <p>
@@ -59,7 +59,7 @@ public class IndexBasedSpellChecker extends 
AbstractLuceneSpellChecker {
   private void initSourceReader() {
     if (sourceLocation != null) {
       try {
-        FSDirectory luceneIndexDir = FSDirectory.open(new 
File(sourceLocation).toPath());
+        FSDirectory luceneIndexDir = FSDirectory.open(Path.of(sourceLocation));
         this.reader = DirectoryReader.open(luceneIndexDir);
       } catch (IOException e) {
         throw new RuntimeException(e);
diff --git 
a/solr/core/src/java/org/apache/solr/spelling/suggest/SolrSuggester.java 
b/solr/core/src/java/org/apache/solr/spelling/suggest/SolrSuggester.java
index aa35e42..68be03e 100644
--- a/solr/core/src/java/org/apache/solr/spelling/suggest/SolrSuggester.java
+++ b/solr/core/src/java/org/apache/solr/spelling/suggest/SolrSuggester.java
@@ -17,11 +17,10 @@
 package org.apache.solr.spelling.suggest;
 
 import java.io.Closeable;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
 import java.io.IOException;
 import java.lang.invoke.MethodHandles;
+import java.nio.file.Files;
+import java.nio.file.Path;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
@@ -38,7 +37,6 @@ import org.apache.lucene.search.suggest.Lookup;
 import org.apache.lucene.search.suggest.Lookup.LookupResult;
 import org.apache.lucene.store.AlreadyClosedException;
 import org.apache.lucene.util.Accountable;
-import org.apache.lucene.util.IOUtils;
 import org.apache.solr.analysis.TokenizerChain;
 import org.apache.solr.common.util.NamedList;
 import org.apache.solr.core.CloseHook;
@@ -84,7 +82,7 @@ public class SolrSuggester implements Accountable {
   static SuggesterResult EMPTY_RESULT = new SuggesterResult();
   
   private String sourceLocation;
-  private File storeDir;
+  private Path storeDir;
   private Dictionary dictionary;
   private Lookup lookup;
   private String lookupImpl;
@@ -121,7 +119,7 @@ public class SolrSuggester implements Accountable {
     factory = core.getResourceLoader().newInstance(lookupImpl, 
LookupFactory.class);
     lookup = factory.create(config, core);
     
-    if (lookup != null && lookup instanceof Closeable) {
+    if (lookup instanceof Closeable) {
       core.addCloseHook(new CloseHook() {
         @Override
         public void preClose(SolrCore core) {
@@ -136,18 +134,18 @@ public class SolrSuggester implements Accountable {
 
     // if store directory is provided make it or load up the lookup with its 
content
     if (store != null && !store.isEmpty()) {
-      storeDir = new File(store);
-      if (!storeDir.isAbsolute()) {
-        storeDir = new File(core.getDataDir() + File.separator + storeDir);
+      storeDir = Path.of(store);
+      storeDir = Path.of(core.getDataDir()).resolve(storeDir); // if store dir 
is absolute this won't change it
+      try {
+        Files.createDirectories(storeDir);
+      } catch (IOException e) {
+        log.warn("Could not create directory {}", storeDir);
       }
-      if (!storeDir.exists()) {
-        storeDir.mkdirs();
-      } else if (getStoreFile().exists()) {
-        if (log.isDebugEnabled()) {
-          log.debug("attempt reload of the stored lookup from file {}", 
getStoreFile());
-        }
+      Path storeFile = getStoreFile();
+      if (Files.exists(storeFile)) {
+        log.debug("attempt reload of the stored lookup from file {}", 
storeFile);
         try {
-          lookup.load(new FileInputStream(getStoreFile()));
+          lookup.load(Files.newInputStream(storeFile));
         } catch (IOException e) {
           log.warn("Loading stored lookup data failed, possibly not cached 
yet");
         }
@@ -182,32 +180,25 @@ public class SolrSuggester implements Accountable {
       throw e2;
     }
     if (storeDir != null) {
-      File target = getStoreFile();
-      if(!lookup.store(new FileOutputStream(target))) {
+      Path target = getStoreFile();
+      if(!lookup.store(Files.newOutputStream(target))) {
         log.error("Store Lookup build failed");
       } else {
         if (log.isInfoEnabled()) {
-          log.info("Stored suggest data to: {}", target.getAbsolutePath());
+          log.info("Stored suggest data to: {}", target.toAbsolutePath());
         }
       }
     }
   }
 
   /** Reloads the underlying Lucene Suggester */
-  public void reload(SolrCore core, SolrIndexSearcher searcher) throws 
IOException {
+  public void reload() throws IOException {
     log.info("SolrSuggester.reload({})", name);
     if (dictionary == null && storeDir != null) {
-      File lookupFile = getStoreFile();
-      if (lookupFile.exists()) {
+      Path lookupFile = getStoreFile();
+      if (Files.exists(lookupFile)) {
         // this may be a firstSearcher event, try loading it
-        FileInputStream is = new FileInputStream(lookupFile);
-        try {
-          if (lookup.load(is)) {
-            return;  // loaded ok
-          }
-        } finally {
-          IOUtils.closeWhileHandlingException(is);
-        }
+        lookup.load(Files.newInputStream(lookupFile));
       } else {
         log.info("lookup file doesn't exist");
       }
@@ -215,15 +206,14 @@ public class SolrSuggester implements Accountable {
   }
 
   /**
-   * 
    * @return the file where this suggester is stored.
    *         null if no storeDir was configured
    */
-  public File getStoreFile() {
+  public Path getStoreFile() {
     if (storeDir == null) {
       return null;
     }
-    return new File(storeDir, factory.storeFileName());
+    return storeDir.resolve(factory.storeFileName());
   }
 
   /** Returns suggestions based on the {@link SuggesterOptions} passed */
@@ -293,7 +283,7 @@ public class SolrSuggester implements Accountable {
   public String toString() {
     return "SolrSuggester [ name=" + name + ", "
         + "sourceLocation=" + sourceLocation + ", "
-        + "storeDir=" + ((storeDir == null) ? "" : storeDir.getAbsoluteFile()) 
+ ", "
+        + "storeDir=" + ((storeDir == null) ? "" : storeDir.toAbsolutePath()) 
+ ", "
         + "lookupImpl=" + lookupImpl + ", "
         + "dictionaryImpl=" + dictionaryImpl + ", "
         + "sizeInBytes=" + ((lookup!=null) ? String.valueOf(ramBytesUsed()) : 
"0") + " ]";
diff --git a/solr/core/src/java/org/apache/solr/spelling/suggest/Suggester.java 
b/solr/core/src/java/org/apache/solr/spelling/suggest/Suggester.java
index c7771fe..5f2dd80 100644
--- a/solr/core/src/java/org/apache/solr/spelling/suggest/Suggester.java
+++ b/solr/core/src/java/org/apache/solr/spelling/suggest/Suggester.java
@@ -17,14 +17,13 @@
 package org.apache.solr.spelling.suggest;
 
 import java.io.Closeable;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStreamReader;
 import java.io.UnsupportedEncodingException;
 import java.lang.invoke.MethodHandles;
 import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
 import java.util.Collections;
 import java.util.List;
 
@@ -38,7 +37,6 @@ import org.apache.lucene.search.suggest.Lookup.LookupResult;
 import org.apache.lucene.search.suggest.analyzing.AnalyzingSuggester;
 import org.apache.lucene.search.suggest.fst.WFSTCompletionLookup;
 import org.apache.lucene.util.CharsRef;
-import org.apache.lucene.util.IOUtils;
 import org.apache.solr.common.util.NamedList;
 import org.apache.solr.core.CloseHook;
 import org.apache.solr.core.SolrCore;
@@ -74,7 +72,7 @@ public class Suggester extends SolrSpellChecker {
   public static final String STORE_DIR = "storeDir";
   
   protected String sourceLocation;
-  protected File storeDir;
+  protected Path storeDir;
   protected float threshold;
   protected Dictionary dictionary;
   protected IndexReader reader;
@@ -108,7 +106,7 @@ public class Suggester extends SolrSpellChecker {
     core.addCloseHook(new CloseHook() {
       @Override
       public void preClose(SolrCore core) {
-        if (lookup != null && lookup instanceof Closeable) {
+        if (lookup instanceof Closeable) {
           try {
             ((Closeable) lookup).close();
           } catch (IOException e) {
@@ -117,19 +115,22 @@ public class Suggester extends SolrSpellChecker {
         }
       }
     });
-    
+
+    // TODO: Duplicated with SolrSuggester
     String store = (String)config.get(STORE_DIR);
     if (store != null) {
-      storeDir = new File(store);
-      if (!storeDir.isAbsolute()) {
-        storeDir = new File(core.getDataDir() + File.separator + storeDir);
+      storeDir = Path.of(store);
+      storeDir = Path.of(core.getDataDir()).resolve(storeDir); // if store dir 
is absolute this won't change it
+      try {
+        Files.createDirectories(storeDir);
+      } catch (IOException e) {
+        log.warn("Could not create directory {}", storeDir);
       }
-      if (!storeDir.exists()) {
-        storeDir.mkdirs();
-      } else {
+      Path storeFile = storeDir.resolve(factory.storeFileName());
+      if (Files.exists(storeFile)) {
         // attempt reload of the stored lookup
         try {
-          lookup.load(new FileInputStream(new File(storeDir, 
factory.storeFileName())));
+          lookup.load(Files.newInputStream(storeFile));
         } catch (IOException e) {
           log.warn("Loading stored lookup data failed", e);
         }
@@ -157,8 +158,8 @@ public class Suggester extends SolrSpellChecker {
 
     lookup.build(dictionary);
     if (storeDir != null) {
-      File target = new File(storeDir, factory.storeFileName());
-      if(!lookup.store(new FileOutputStream(target))) {
+      Path target = storeDir.resolve(factory.storeFileName());
+      if(!lookup.store(Files.newOutputStream(target))) {
         if (sourceLocation == null) {
           assert reader != null && field != null;
           log.error("Store Lookup build from index on field: {} failed reader 
has: {} docs", field, reader.maxDoc());
@@ -167,7 +168,7 @@ public class Suggester extends SolrSpellChecker {
         }
       } else {
         if (log.isInfoEnabled()) {
-          log.info("Stored suggest data to: {}", target.getAbsolutePath());
+          log.info("Stored suggest data to: {}", target.toAbsolutePath());
         }
       }
     }
@@ -178,13 +179,8 @@ public class Suggester extends SolrSpellChecker {
     log.info("reload()");
     if (dictionary == null && storeDir != null) {
       // this may be a firstSearcher event, try loading it
-      FileInputStream is = new FileInputStream(new File(storeDir, 
factory.storeFileName()));
-      try {
-        if (lookup.load(is)) {
-          return;  // loaded ok
-        }
-      } finally {
-        IOUtils.closeWhileHandlingException(is);
+      if 
(lookup.load(Files.newInputStream(storeDir.resolve(factory.storeFileName())))) {
+        return;  // loaded ok
       }
       log.debug("load failed, need to build Lookup again");
     }
diff --git a/solr/core/src/java/org/apache/solr/update/TransactionLog.java 
b/solr/core/src/java/org/apache/solr/update/TransactionLog.java
index 651a0fb..353bfe0 100644
--- a/solr/core/src/java/org/apache/solr/update/TransactionLog.java
+++ b/solr/core/src/java/org/apache/solr/update/TransactionLog.java
@@ -17,15 +17,15 @@
 package org.apache.solr.update;
 
 import java.io.Closeable;
-import java.io.File;
 import java.io.IOException;
 import java.io.OutputStream;
-import java.io.RandomAccessFile;
 import java.lang.invoke.MethodHandles;
 import java.nio.ByteBuffer;
 import java.nio.channels.Channels;
 import java.nio.channels.FileChannel;
 import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.StandardOpenOption;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashMap;
@@ -69,11 +69,10 @@ public class TransactionLog implements Closeable {
   private boolean debug = log.isDebugEnabled();
   private boolean trace = log.isTraceEnabled();
 
-  public final static String END_MESSAGE = "SOLR_TLOG_END";
+  public static final String END_MESSAGE = "SOLR_TLOG_END";
 
   long id;
-  File tlogFile;
-  RandomAccessFile raf;
+  Path tlog;
   FileChannel channel;
   OutputStream os;
   FastOutputStream fos;    // all accesses to this stream should be 
synchronized on "this" (The TransactionLog)
@@ -158,49 +157,50 @@ public class TransactionLog implements Closeable {
     }
   }
 
-  TransactionLog(File tlogFile, Collection<String> globalStrings) {
+  TransactionLog(Path tlogFile, Collection<String> globalStrings) {
     this(tlogFile, globalStrings, false);
   }
 
-  TransactionLog(File tlogFile, Collection<String> globalStrings, boolean 
openExisting) {
+  TransactionLog(Path tlogFile, Collection<String> globalStrings, boolean 
openExisting) {
     boolean success = false;
     try {
+      this.tlog = tlogFile;
+
       if (debug) {
-        log.debug("New TransactionLog file= {}, exists={}, size={} 
openExisting={}"
-                , tlogFile, tlogFile.exists(), tlogFile.length(), 
openExisting);
+        log.debug("New TransactionLog file={}, exists={}, size={} 
openExisting={}",
+            tlogFile, Files.exists(tlogFile), getLogSize(), openExisting);
       }
 
       // Parse tlog id from the filename
-      String filename = tlogFile.getName();
+      String filename = tlog.getFileName().toString();
       id = Long.parseLong(filename.substring(filename.lastIndexOf('.') + 1));
 
-      this.tlogFile = tlogFile;
-      raf = new RandomAccessFile(this.tlogFile, "rw");
-      long start = raf.length();
-      channel = raf.getChannel();
-      os = Channels.newOutputStream(channel);
-      fos = new FastOutputStream(os, new byte[65536], 0);
-      // fos = FastOutputStream.wrap(os);
-
       if (openExisting) {
+        assert Files.exists(tlog) : tlog + " did not exist";
+
+        long start = Files.size(tlog);
+        channel = FileChannel.open(tlog, StandardOpenOption.READ, 
StandardOpenOption.WRITE);
+        os = Channels.newOutputStream(channel);
+        fos = new FastOutputStream(os, new byte[65536], 0);
+
         if (start > 0) {
           readHeader(null);
-          raf.seek(start);
-          assert channel.position() == start;
+          channel.position(start);
           fos.setWritten(start);    // reflect that we aren't starting at the 
beginning
           assert fos.size() == channel.size();
         } else {
           addGlobalStrings(globalStrings);
         }
       } else {
-        if (start > 0) {
-          log.warn("New transaction log already exists:{} size={}", tlogFile, 
raf.length());
+        if (Files.exists(tlog)) {
+          log.warn("New transaction log already exists:{} size={}", tlog, 
Files.size(tlog));
           return;
         }
 
-        if (start > 0) {
-          raf.setLength(0);
-        }
+        channel = FileChannel.open(tlog, StandardOpenOption.READ, 
StandardOpenOption.WRITE, StandardOpenOption.CREATE_NEW);
+        os = Channels.newOutputStream(channel);
+        fos = new FastOutputStream(os, new byte[65536], 0);
+
         addGlobalStrings(globalStrings);
       }
 
@@ -211,9 +211,9 @@ public class TransactionLog implements Closeable {
     } catch (IOException e) {
       throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, e);
     } finally {
-      if (!success && raf != null) {
+      if (!success && channel != null) {
         try {
-          raf.close();
+          channel.close();
         } catch (Exception e) {
           log.error("Error closing tlog file (after error opening)", e);
         }
@@ -572,7 +572,7 @@ public class TransactionLog implements Closeable {
         // Since fsync is outside of synchronized block, we can end up with a 
partial
         // last record on power failure (which is OK, and does not represent 
an error...
         // we just need to be aware of it when reading).
-        raf.getFD().sync();
+        channel.force(true);
       }
 
     } catch (IOException e) {
@@ -593,7 +593,7 @@ public class TransactionLog implements Closeable {
 
       if (deleteOnClose) {
         try {
-          Files.deleteIfExists(tlogFile.toPath());
+          Files.deleteIfExists(tlog);
         } catch (IOException e) {
           // TODO: should this class care if a file couldnt be deleted?
           // this just emulates previous behavior, where only 
SecurityException would be handled.
@@ -616,12 +616,16 @@ public class TransactionLog implements Closeable {
 
   @Override
   public String toString() {
-    return "tlog{file=" + tlogFile.toString() + " refcount=" + refcount.get() 
+ "}";
+    return "tlog{file=" + tlog + " refcount=" + refcount.get() + "}";
   }
 
   public long getLogSize() {
-    if (tlogFile != null) {
-      return tlogFile.length();
+    if (tlog != null) {
+      try {
+        return Files.size(tlog);
+      } catch (IOException e) {
+        log.warn("Could not read tlog length file={}", tlog);
+      }
     }
     return 0;
   }
@@ -710,7 +714,7 @@ public class TransactionLog implements Closeable {
     @Override
     public String toString() {
       synchronized (TransactionLog.this) {
-        return "LogReader{" + "file=" + tlogFile + ", position=" + 
fis.position() + ", end=" + fos.size() + "}";
+        return "LogReader{" + "file=" + tlog + ", position=" + fis.position() 
+ ", end=" + fos.size() + "}";
       }
     }
 
@@ -877,7 +881,7 @@ public class TransactionLog implements Closeable {
     @Override
     public String toString() {
       synchronized (TransactionLog.this) {
-        return "LogReader{" + "file=" + tlogFile + ", position=" + 
fis.position() + ", end=" + fos.size() + "}";
+        return "LogReader{" + "file=" + tlog + ", position=" + fis.position() 
+ ", end=" + fos.size() + "}";
       }
     }
 
diff --git a/solr/core/src/java/org/apache/solr/update/UpdateLog.java 
b/solr/core/src/java/org/apache/solr/update/UpdateLog.java
index ecdf23e..87be666 100644
--- a/solr/core/src/java/org/apache/solr/update/UpdateLog.java
+++ b/solr/core/src/java/org/apache/solr/update/UpdateLog.java
@@ -19,11 +19,11 @@ package org.apache.solr.update;
 import java.io.Closeable;
 import java.io.File;
 import java.io.FileNotFoundException;
-import java.io.FilenameFilter;
 import java.io.IOException;
 import java.lang.invoke.MethodHandles;
 import java.nio.charset.Charset;
 import java.nio.file.Files;
+import java.nio.file.Path;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
@@ -46,6 +46,7 @@ import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.concurrent.atomic.AtomicReference;
+import java.util.stream.Stream;
 
 import com.codahale.metrics.Gauge;
 import com.codahale.metrics.Meter;
@@ -233,8 +234,8 @@ public class UpdateLog implements PluginInfoInitialized, 
SolrMetricProducer {
 
   protected LinkedList<DBQ> deleteByQueries = new LinkedList<>();
 
-  protected String[] tlogFiles;
-  protected File tlogDir;
+  protected String[] tlogFiles; // Needs to be String because hdfs.Path is 
incompatible with nio.Path
+  protected Path tlogDir;
   protected Collection<String> globalStrings;
 
   protected String dataDir;
@@ -372,28 +373,38 @@ public class UpdateLog implements PluginInfoInitialized, 
SolrMetricProducer {
       return;
     }
     lastDataDir = dataDir;
-    tlogDir = new File(dataDir, TLOG_NAME);
-    tlogDir.mkdirs();
-    tlogFiles = getLogList(tlogDir);
+    tlogDir = Path.of(dataDir, TLOG_NAME);
+    try {
+      Files.createDirectories(tlogDir);
+    } catch (IOException e) {
+      throw new SolrException(ErrorCode.SERVER_ERROR, "Could not set up 
tlogs", e);
+    }
+    tlogFiles = getLogList(tlogDir.toFile());
     id = getLastLogId() + 1;   // add 1 since we will create a new log for the 
next update
 
     if (debug) {
       log.debug("UpdateHandler init: tlogDir={}, existing tlogs={}, next 
id={}", tlogDir, Arrays.asList(tlogFiles), id);
     }
 
-    String[] oldBufferTlog = getBufferLogList(tlogDir);
-    if (oldBufferTlog != null && oldBufferTlog.length != 0) {
-      existOldBufferLog = true;
+    final String prefix = BUFFER_TLOG_NAME + '.';
+    try (Stream<Path> bufferedTLogs = Files.walk(tlogDir, 1)) {
+      existOldBufferLog = bufferedTLogs.anyMatch(path -> 
path.getFileName().toString().startsWith(prefix));
+    } catch (IOException e) {
+      // Existance of buffered t-logs indicates previous recovery failed and 
lets us skip peer sync as an optimization
+      // Failing to read them is non-fatal and almost not even worth logging 
about
+      log.debug("Could not read {} directory searching for buffered 
transaction log files.", tlogDir, e);
+      existOldBufferLog = false;
     }
     TransactionLog oldLog = null;
     for (String oldLogName : tlogFiles) {
-      File f = new File(tlogDir, oldLogName);
+      Path path = tlogDir.resolve(oldLogName);
       try {
-        oldLog = newTransactionLog(f, null, true);
+        oldLog = newTransactionLog(path, null, true);
         addOldLog(oldLog, false);  // don't remove old logs on startup since 
more than one may be uncapped.
-      } catch (Exception e) {
-        SolrException.log(log, "Failure to open existing log file (non fatal) 
" + f, e);
-        deleteFile(f);
+      } catch (RuntimeException e) {
+        // This could be a SolrException, why is it non-fatal?
+        log.error("Failure to open existing log file (non fatal) {} ", path, 
e);
+        deleteFile(path);
       }
     }
 
@@ -473,12 +484,12 @@ public class UpdateLog implements PluginInfoInitialized, 
SolrMetricProducer {
    * Returns a new {@link org.apache.solr.update.TransactionLog}. Sub-classes 
can override this method to
    * change the implementation of the transaction log.
    */
-  public TransactionLog newTransactionLog(File tlogFile, Collection<String> 
globalStrings, boolean openExisting) {
+  public TransactionLog newTransactionLog(Path tlogFile, Collection<String> 
globalStrings, boolean openExisting) {
     return new TransactionLog(tlogFile, globalStrings, openExisting);
   }
 
   public String getLogDir() {
-    return tlogDir.getAbsolutePath();
+    return tlogDir.toAbsolutePath().toString();
   }
 
   public List<Long> getStartingVersions() {
@@ -522,11 +533,6 @@ public class UpdateLog implements PluginInfoInitialized, 
SolrMetricProducer {
     logs.addFirst(oldLog);
   }
 
-  public String[] getBufferLogList(File directory) {
-    final String prefix = BUFFER_TLOG_NAME+'.';
-    return directory.list((dir, name) -> name.startsWith(prefix));
-  }
-
   /**
    * Does update from old tlogs (not from buffer tlog)?
    * If yes we must skip writing {@code cmd} to current tlog
@@ -537,12 +543,7 @@ public class UpdateLog implements PluginInfoInitialized, 
SolrMetricProducer {
 
   public String[] getLogList(File directory) {
     final String prefix = TLOG_NAME+'.';
-    String[] names = directory.list(new FilenameFilter() {
-      @Override
-      public boolean accept(File dir, String name) {
-        return name.startsWith(prefix);
-      }
-    });
+    String[] names = directory.list((dir, name) -> name.startsWith(prefix));
     if (names == null) {
       throw new RuntimeException(new 
FileNotFoundException(directory.getAbsolutePath()));
     }
@@ -1328,17 +1329,19 @@ public class UpdateLog implements 
PluginInfoInitialized, SolrMetricProducer {
   protected void ensureBufferTlog() {
     if (bufferTlog != null) return;
     String newLogName = String.format(Locale.ROOT, LOG_FILENAME_PATTERN, 
BUFFER_TLOG_NAME, System.nanoTime());
-    bufferTlog = newTransactionLog(new File(tlogDir, newLogName), 
globalStrings, false);
+    bufferTlog = newTransactionLog(tlogDir.resolve(newLogName), globalStrings, 
false);
     bufferTlog.isBuffer = true;
   }
 
   // Cleanup old buffer tlogs
   protected void deleteBufferLogs() {
-    String[] oldBufferTlog = getBufferLogList(tlogDir);
-    if (oldBufferTlog != null && oldBufferTlog.length != 0) {
-      for (String oldBufferLogName : oldBufferTlog) {
-        deleteFile(new File(tlogDir, oldBufferLogName));
-      }
+    try (Stream<Path> tlogs = Files.walk(tlogDir, 1)) {
+      final String prefix = BUFFER_TLOG_NAME + '.';
+      tlogs.filter(Files::isRegularFile)
+          .filter(path -> path.getFileName().toString().startsWith(prefix))
+          .forEach(UpdateLog::deleteFile);
+    } catch (IOException e) {
+      log.warn("Could not clean up buffered transaction logs in {}", tlogDir, 
e);
     }
   }
 
@@ -1346,7 +1349,7 @@ public class UpdateLog implements PluginInfoInitialized, 
SolrMetricProducer {
   protected void ensureLog() {
     if (tlog == null) {
       String newLogName = String.format(Locale.ROOT, LOG_FILENAME_PATTERN, 
TLOG_NAME, id);
-      tlog = newTransactionLog(new File(tlogDir, newLogName), globalStrings, 
false);
+      tlog = newTransactionLog(tlogDir.resolve(newLogName), globalStrings, 
false);
     }
   }
 
@@ -2133,10 +2136,10 @@ public class UpdateLog implements 
PluginInfoInitialized, SolrMetricProducer {
       new SolrNamedThreadFactory("recoveryExecutor"));
 
 
-  public static void deleteFile(File file) {
+  public static void deleteFile(Path file) {
     boolean success = false;
     try {
-      Files.deleteIfExists(file.toPath());
+      Files.deleteIfExists(file);
       success = true;
     } catch (Exception e) {
       log.error("Error deleting file: {}", file, e);
@@ -2144,7 +2147,7 @@ public class UpdateLog implements PluginInfoInitialized, 
SolrMetricProducer {
 
     if (!success) {
       try {
-        file.deleteOnExit();
+        file.toFile().deleteOnExit();
       } catch (Exception e) {
         log.error("Error deleting file on exit: {}", file, e);
       }
@@ -2174,17 +2177,20 @@ public class UpdateLog implements 
PluginInfoInitialized, SolrMetricProducer {
    */
   public void clearLog(SolrCore core, PluginInfo ulogPluginInfo) {
     if (ulogPluginInfo == null) return;
-    File tlogDir = new File(getTlogDir(core, ulogPluginInfo));
-    if (tlogDir.exists()) {
-      String[] files = getLogList(tlogDir);
-      for (String file : files) {
-        File f = new File(tlogDir, file);
-        try {
-          Files.delete(f.toPath());
-        } catch (IOException cause) {
-          // NOTE: still throws SecurityException as before.
-          log.error("Could not remove tlog file:{}", f, cause);
-        }
+    Path tlogPath = Path.of(getTlogDir(core, ulogPluginInfo));
+    if (Files.exists(tlogPath)) {
+      try (Stream<Path> paths = Files.walk(tlogPath)) {
+        paths.filter(Files::isRegularFile)
+            .forEach(path -> {
+              try {
+                Files.delete(path);
+              } catch (IOException cause) {
+                // NOTE: still throws SecurityException as before.
+                log.error("Could not remove tlog file: {}", path, cause);
+              }
+            });
+      } catch (IOException e) {
+        log.error("Could not clear old tlogs in {}", tlogPath);
       }
     }
   }
diff --git a/solr/core/src/java/org/apache/solr/util/PackageTool.java 
b/solr/core/src/java/org/apache/solr/util/PackageTool.java
index 89aa244..75a9bdb 100644
--- a/solr/core/src/java/org/apache/solr/util/PackageTool.java
+++ b/solr/core/src/java/org/apache/solr/util/PackageTool.java
@@ -16,14 +16,13 @@
  */
 package org.apache.solr.util;
 
-import java.io.File;
 import java.lang.invoke.MethodHandles;
-import java.nio.file.Paths;
+import java.nio.file.Files;
+import java.nio.file.Path;
 import java.util.Map;
 
 import org.apache.commons.cli.CommandLine;
 import org.apache.commons.cli.Option;
-import org.apache.commons.io.FileUtils;
 import org.apache.http.impl.client.CloseableHttpClient;
 import org.apache.logging.log4j.Level;
 import org.apache.logging.log4j.core.config.Configurator;
@@ -95,7 +94,8 @@ public class PackageTool extends SolrCLI.ToolBase {
                 break;
               case "add-key":
                 String keyFilename = cli.getArgs()[1];
-                repositoryManager.addKey(FileUtils.readFileToByteArray(new 
File(keyFilename)), Paths.get(keyFilename).getFileName().toString());
+                Path path = Path.of(keyFilename);
+                repositoryManager.addKey(Files.readAllBytes(path), 
path.getFileName().toString());
                 break;
               case "list-installed":
                 PackageUtils.printGreen("Installed packages:\n-----");
diff --git a/solr/core/src/java/org/apache/solr/util/SolrCLI.java 
b/solr/core/src/java/org/apache/solr/util/SolrCLI.java
index 93112d4..068f5bd 100755
--- a/solr/core/src/java/org/apache/solr/util/SolrCLI.java
+++ b/solr/core/src/java/org/apache/solr/util/SolrCLI.java
@@ -1924,9 +1924,7 @@ public class SolrCLI implements CLIO {
         if (configSetPath.endsWith("/conf") == false) {
           configSetPath = Paths.get(configSetPath.toString(), "conf");
         }
-        if (Files.exists(configSetPath) == false) {
-          Files.createDirectories(configSetPath);
-        }
+        Files.createDirectories(configSetPath);
         echo("Downloading configset " + confName + " from ZooKeeper at " + 
zkHost +
             " to directory " + configSetPath.toAbsolutePath());
 
diff --git a/solr/core/src/java/org/apache/solr/util/SolrLogPostTool.java 
b/solr/core/src/java/org/apache/solr/util/SolrLogPostTool.java
index bf5f753..eae5d23 100644
--- a/solr/core/src/java/org/apache/solr/util/SolrLogPostTool.java
+++ b/solr/core/src/java/org/apache/solr/util/SolrLogPostTool.java
@@ -16,17 +16,22 @@
  */
 package org.apache.solr.util;
 
-import java.io.*;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.LineNumberReader;
 import java.nio.charset.Charset;
+import java.nio.file.Files;
+import java.nio.file.Path;
 import java.util.Collections;
 import java.util.List;
-import java.util.ArrayList;
 import java.net.URLDecoder;
 import java.util.Map;
 import java.util.TreeMap;
 import java.util.UUID;
 import java.util.regex.Pattern;
 import java.util.regex.Matcher;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 import org.apache.solr.client.solrj.SolrServerException;
 import org.apache.solr.client.solrj.impl.HttpSolrClient;
@@ -65,29 +70,26 @@ public class SolrLogPostTool {
     String root = args[1];
 
     HttpSolrClient.Builder builder = new HttpSolrClient.Builder();
-    SolrClient client = null;
-    try {
-      client = builder.withBaseSolrUrl(baseUrl).build();
-      File rf = new File(root);
-      List<File> files = new ArrayList<>();
-      gatherFiles(rf, files);
+    try (SolrClient client = builder.withBaseSolrUrl(baseUrl).build()) {
       int rec = 0;
       UpdateRequest request = new UpdateRequest();
 
-      for (File file : files) {
-
-        LineNumberReader bufferedReader = null;
+      List<Path> files;
+      try (Stream<Path> stream = Files.walk(Path.of(root), Integer.MAX_VALUE)) 
{
+          files = stream.filter(Files::isRegularFile)
+              .collect(Collectors.toList());
+      }
 
-        try {
-          bufferedReader = new LineNumberReader(new InputStreamReader(new 
FileInputStream(file), Charset.defaultCharset()));
-          LogRecordReader recordReader = new LogRecordReader(bufferedReader);
+      for (Path file : files) {
+        try (LineNumberReader reader = new 
LineNumberReader(Files.newBufferedReader(file, Charset.defaultCharset()))) {
+          LogRecordReader recordReader = new LogRecordReader(reader);
           SolrInputDocument doc = null;
-          String fileName = file.getName();
+          String fileName = file.getFileName().toString();
           while (true) {
             try {
               doc = recordReader.readRecord();
             } catch (Throwable t) {
-              CLIO.err("Error reading log record:"+ 
bufferedReader.getLineNumber() +" from file:"+ fileName);
+              CLIO.err("Error reading log record:"+ reader.getLineNumber() +" 
from file:"+ fileName);
               CLIO.err(t.getMessage());
               continue;
             }
@@ -107,16 +109,12 @@ public class SolrLogPostTool {
               rec = 0;
             }
           }
-        } finally {
-          bufferedReader.close();
         }
       }
 
       if (rec > 0) {
         sendBatch(client, request, true /* last batch */);
       }
-    } finally {
-      client.close();
     }
   }
 
@@ -142,22 +140,6 @@ public class SolrLogPostTool {
     }
   }
 
-  static void gatherFiles(File rootFile, List<File> files) {
-
-    if(rootFile.isFile()) {
-      files.add(rootFile);
-    } else {
-      File[] subFiles = rootFile.listFiles();
-      for(File f : subFiles) {
-        if(f.isFile()) {
-          files.add(f);
-        } else {
-          gatherFiles(f, files);
-        }
-      }
-    }
-  }
-
   public static class LogRecordReader {
 
     private BufferedReader bufferedReader;
diff --git 
a/solr/core/src/test/org/apache/solr/cloud/BasicDistributedZkTest.java 
b/solr/core/src/test/org/apache/solr/cloud/BasicDistributedZkTest.java
index 718610b..6a14e1d 100644
--- a/solr/core/src/test/org/apache/solr/cloud/BasicDistributedZkTest.java
+++ b/solr/core/src/test/org/apache/solr/cloud/BasicDistributedZkTest.java
@@ -914,7 +914,7 @@ public class BasicDistributedZkTest extends 
AbstractFullDistribZkTestBase {
 
     NamedList<Object> result = clients.get(0).request(
         new StreamingUpdateRequest("/update",
-            getFile("books_numeric_ids.csv"), "application/csv")
+            getFile("books_numeric_ids.csv").toPath(), "application/csv")
             .setCommitWithin(900000)
             .setAction(AbstractUpdateRequest.ACTION.COMMIT, true, true));
     
diff --git a/solr/core/src/test/org/apache/solr/cloud/SolrCloudExampleTest.java 
b/solr/core/src/test/org/apache/solr/cloud/SolrCloudExampleTest.java
index ac6eb19..09d0eac 100644
--- a/solr/core/src/test/org/apache/solr/cloud/SolrCloudExampleTest.java
+++ b/solr/core/src/test/org/apache/solr/cloud/SolrCloudExampleTest.java
@@ -17,17 +17,21 @@
 package org.apache.solr.cloud;
 
 import java.io.File;
-import java.io.FilenameFilter;
 import java.lang.invoke.MethodHandles;
 import java.nio.charset.StandardCharsets;
-import java.util.Arrays;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.ArrayList;
 import java.util.Collections;
+import java.util.Comparator;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Random;
 import java.util.Set;
 import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 import org.apache.commons.cli.CommandLine;
 import org.apache.http.HttpEntity;
@@ -115,35 +119,33 @@ public class SolrCloudExampleTest extends 
AbstractFullDistribZkTestBase {
     // now index docs like bin/post would do but we can't use SimplePostTool 
because it uses System.exit when
     // it encounters an error, which JUnit doesn't like ...
     log.info("Created collection, now posting example docs!");
-    File exampleDocsDir = new File(ExternalPaths.SOURCE_HOME, 
"example/exampledocs");
-    assertTrue(exampleDocsDir.getAbsolutePath()+" not found!", 
exampleDocsDir.isDirectory());
-
-    List<File> xmlFiles = Arrays.asList(exampleDocsDir.listFiles(new 
FilenameFilter() {
-      @Override
-      public boolean accept(File dir, String name) {
-        return name.endsWith(".xml");
-      }
-    }));
+    Path exampleDocsDir = Path.of(ExternalPaths.SOURCE_HOME, "example", 
"exampledocs");
+    assertTrue(exampleDocsDir.toAbsolutePath() + " not found!", 
Files.isDirectory(exampleDocsDir));
+
+    List<Path> xmlFiles;
+    try (Stream<Path> stream = Files.walk(exampleDocsDir, 1)) {
+        xmlFiles = stream.filter(path -> 
path.getFileName().toString().endsWith(".xml"))
+            // don't rely on File.compareTo, it's behavior varies by OS
+            .sorted(Comparator.comparing(path -> 
path.getFileName().toString()))
+            // be explicit about the collection type because we will shuffle 
it later
+            .collect(Collectors.toCollection(ArrayList::new));
+    }
 
     // force a deterministic random ordering of the files so seeds reproduce 
regardless of platform/filesystem
-    Collections.sort(xmlFiles, (o1, o2) -> {
-      // don't rely on File.compareTo, it's behavior varies by OS
-      return o1.getName().compareTo(o2.getName());
-    });
     Collections.shuffle(xmlFiles, new Random(random().nextLong()));
 
     // if you add/remove example XML docs, you'll have to fix these expected 
values
     int expectedXmlFileCount = 14;
     int expectedXmlDocCount = 32;
 
-    assertEquals("Unexpected # of example XML files in 
"+exampleDocsDir.getAbsolutePath(),
-                 expectedXmlFileCount, xmlFiles.size());
+    assertEquals("Unexpected # of example XML files in " + 
exampleDocsDir.toAbsolutePath(),
+        expectedXmlFileCount, xmlFiles.size());
     
-    for (File xml : xmlFiles) {
+    for (Path xml : xmlFiles) {
       if (log.isInfoEnabled()) {
-        log.info("POSTing {}", xml.getAbsolutePath());
+        log.info("POSTing {}", xml.toAbsolutePath());
       }
-      cloudClient.request(new 
StreamingUpdateRequest("/update",xml,"application/xml"));
+      cloudClient.request(new StreamingUpdateRequest("/update", xml, 
"application/xml"));
     }
     cloudClient.commit();
 
diff --git a/solr/core/src/test/org/apache/solr/cloud/TestConfigSetsAPI.java 
b/solr/core/src/test/org/apache/solr/cloud/TestConfigSetsAPI.java
index aa4f2bd..8d375b6 100644
--- a/solr/core/src/test/org/apache/solr/cloud/TestConfigSetsAPI.java
+++ b/solr/core/src/test/org/apache/solr/cloud/TestConfigSetsAPI.java
@@ -33,6 +33,8 @@ import java.lang.invoke.MethodHandles;
 import java.net.URI;
 import java.nio.ByteBuffer;
 import java.nio.charset.Charset;
+import java.nio.file.Files;
+import java.nio.file.Path;
 import java.security.Principal;
 import java.util.Arrays;
 import java.util.Collection;
@@ -1272,13 +1274,13 @@ public class TestConfigSetsAPI extends 
SolrCloudTestCase {
    */
   @Test
   public void testUserAndTestDefaultConfigsetsAreSame() throws IOException {
-    final File extPath = new File(ExternalPaths.DEFAULT_CONFIGSET);
-    assertTrue("_default dir doesn't exist: " + 
ExternalPaths.DEFAULT_CONFIGSET, extPath.exists());
-    assertTrue("_default dir isn't a dir: " + ExternalPaths.DEFAULT_CONFIGSET, 
extPath.isDirectory());
+    final Path extPath = Path.of(ExternalPaths.DEFAULT_CONFIGSET);
+    assertTrue("_default dir doesn't exist: " + 
ExternalPaths.DEFAULT_CONFIGSET, Files.exists(extPath));
+    assertTrue("_default dir isn't a dir: " + ExternalPaths.DEFAULT_CONFIGSET, 
Files.isDirectory(extPath));
 
-    final String zkBootStrap = ConfigSetService.getDefaultConfigDirPath();
+    final Path zkBootStrap = ConfigSetService.getDefaultConfigDirPath();
     assertEquals("extPath _default configset dir vs zk bootstrap path",
-                 ExternalPaths.DEFAULT_CONFIGSET, zkBootStrap);
+                 extPath, zkBootStrap);
   }
 
   private StringBuilder getConfigSetProps(Map<String, String> map) {
diff --git 
a/solr/core/src/test/org/apache/solr/handler/designer/TestSchemaDesignerConfigSetHelper.java
 
b/solr/core/src/test/org/apache/solr/handler/designer/TestSchemaDesignerConfigSetHelper.java
index dcbdfd6..d25d055 100644
--- 
a/solr/core/src/test/org/apache/solr/handler/designer/TestSchemaDesignerConfigSetHelper.java
+++ 
b/solr/core/src/test/org/apache/solr/handler/designer/TestSchemaDesignerConfigSetHelper.java
@@ -17,11 +17,15 @@
 
 package org.apache.solr.handler.designer;
 
+import java.io.ByteArrayInputStream;
 import java.io.File;
+import java.io.IOException;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
 import java.util.Map;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipInputStream;
 
 import org.apache.solr.client.solrj.request.CollectionAdminRequest;
 import org.apache.solr.cloud.SolrCloudTestCase;
@@ -113,6 +117,26 @@ public class TestSchemaDesignerConfigSetHelper extends 
SolrCloudTestCase impleme
   }
 
   @Test
+  public void testDownloadAndZip() throws IOException {
+    byte[] zipped = helper.downloadAndZipConfigSet(DEFAULT_CONFIGSET_NAME);
+    ZipInputStream stream = new ZipInputStream(new 
ByteArrayInputStream(zipped));
+
+    boolean foundSolrConfig = false;
+    boolean foundStopWords = false;
+
+    ZipEntry entry;
+    while ((entry = stream.getNextEntry()) != null) {
+      if ("solrconfig.xml".equals(entry.getName())) {
+        foundSolrConfig = true;
+      } else if ("lang/stopwords_en.txt".equals(entry.getName())) {
+        foundStopWords = true;
+      }
+    }
+    assertTrue("Did not find solrconfig.xml in downloaded configset", 
foundSolrConfig);
+    assertTrue("Did not find stopwords_en.txt in downloaded configset", 
foundStopWords);
+  }
+
+  @Test
   public void testEnableDisableOptions() throws Exception {
     String configSet = "testEnableDisableOptions";
     String mutableId = getMutableId(configSet);
diff --git a/solr/core/src/test/org/apache/solr/update/TransactionLogTest.java 
b/solr/core/src/test/org/apache/solr/update/TransactionLogTest.java
index 594bc89..dfe741d 100644
--- a/solr/core/src/test/org/apache/solr/update/TransactionLogTest.java
+++ b/solr/core/src/test/org/apache/solr/update/TransactionLogTest.java
@@ -17,10 +17,8 @@
 
 package org.apache.solr.update;
 
-import java.io.File;
 import java.io.IOException;
 import java.nio.file.Path;
-import java.util.ArrayList;
 import java.util.List;
 import java.util.Locale;
 import java.util.UUID;
@@ -37,8 +35,8 @@ public class TransactionLogTest extends SolrTestCase {
     String tlogFileName = String.format(Locale.ROOT, 
UpdateLog.LOG_FILENAME_PATTERN, UpdateLog.TLOG_NAME,
         Long.MAX_VALUE);
     Path path = createTempDir();
-    File logFile = new File(path.toFile(), tlogFileName);
-    try (TransactionLog transactionLog = new TransactionLog(logFile, new 
ArrayList<>())) {
+    Path logFile = path.resolve(tlogFileName);
+    try (TransactionLog transactionLog = new TransactionLog(logFile, null)) {
       transactionLog.lastAddSize = 2000000000;
       AddUpdateCommand updateCommand = new AddUpdateCommand(null);
       updateCommand.solrDoc = new SolrInputDocument();
@@ -51,9 +49,9 @@ public class TransactionLogTest extends SolrTestCase {
     String tlogFileName = String.format(Locale.ROOT, 
UpdateLog.LOG_FILENAME_PATTERN, UpdateLog.TLOG_NAME,
         Long.MAX_VALUE);
     Path path = createTempDir();
-    File logFile = new File(path.toFile(), tlogFileName);
+    Path logFile = path.resolve(tlogFileName);
     UUID uuid = UUID.randomUUID();
-    try (TransactionLog tlog = new TransactionLog(logFile, new ArrayList<>())) 
{
+    try (TransactionLog tlog = new TransactionLog(logFile, null)) {
       tlog.deleteOnClose = false;
       AddUpdateCommand updateCommand = new AddUpdateCommand(null);
 
@@ -64,7 +62,7 @@ public class TransactionLogTest extends SolrTestCase {
       tlog.write(updateCommand);
     }
 
-    try (TransactionLog tlog = new TransactionLog(logFile, new ArrayList<>(), 
true)) {
+    try (TransactionLog tlog = new TransactionLog(logFile, null, true)) {
       LogReader reader = tlog.getReader(0);
       Object entry = reader.next();
       assertNotNull(entry);
diff --git 
a/solr/solrj/src/java/org/apache/solr/client/solrj/request/StreamingUpdateRequest.java
 
b/solr/solrj/src/java/org/apache/solr/client/solrj/request/StreamingUpdateRequest.java
index 3b2ed5e..e58be80 100644
--- 
a/solr/solrj/src/java/org/apache/solr/client/solrj/request/StreamingUpdateRequest.java
+++ 
b/solr/solrj/src/java/org/apache/solr/client/solrj/request/StreamingUpdateRequest.java
@@ -17,12 +17,12 @@
 
 package org.apache.solr.client.solrj.request;
 
-import java.io.File;
-import java.io.FileInputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
 
 /** A simple update request which streams content to the server
  */
@@ -50,11 +50,11 @@ public class StreamingUpdateRequest extends 
AbstractUpdateRequest {
     });
   }
 
-  public StreamingUpdateRequest(String path, File f, String contentType) {
+  public StreamingUpdateRequest(String path, Path data, String contentType) {
     this(path, new RequestWriter.ContentWriter() {
       @Override
       public void write(OutputStream os) throws IOException {
-        try (InputStream is = new FileInputStream(f)) {
+        try (InputStream is = Files.newInputStream(data)) {
           is.transferTo(os);
         }
       }
diff --git 
a/solr/solrj/src/test/org/apache/solr/client/solrj/SolrExampleTests.java 
b/solr/solrj/src/test/org/apache/solr/client/solrj/SolrExampleTests.java
index 1eadc36..3e0cc21 100644
--- a/solr/solrj/src/test/org/apache/solr/client/solrj/SolrExampleTests.java
+++ b/solr/solrj/src/test/org/apache/solr/client/solrj/SolrExampleTests.java
@@ -780,7 +780,7 @@ abstract public class SolrExampleTests extends 
SolrExampleTestsBase
     QueryResponse rsp = client.query( new SolrQuery( "*:*") );
     Assert.assertEquals(0, rsp.getResults().getNumFound());
     NamedList<Object> result = client.request(new 
StreamingUpdateRequest("/update",
-        getFile("solrj/books.csv"), "application/csv")
+        getFile("solrj/books.csv").toPath(), "application/csv")
         .setAction(AbstractUpdateRequest.ACTION.COMMIT, true, true));
     assertNotNull("Couldn't upload books.csv", result);
     rsp = client.query( new SolrQuery( "*:*") );
diff --git 
a/solr/test-framework/src/java/org/apache/solr/EmbeddedSolrServerTestBase.java 
b/solr/test-framework/src/java/org/apache/solr/EmbeddedSolrServerTestBase.java
index 96ecfe3..4c547d6 100644
--- 
a/solr/test-framework/src/java/org/apache/solr/EmbeddedSolrServerTestBase.java
+++ 
b/solr/test-framework/src/java/org/apache/solr/EmbeddedSolrServerTestBase.java
@@ -22,6 +22,7 @@ import java.io.FileInputStream;
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.OutputStream;
+import java.io.UncheckedIOException;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.Paths;
@@ -76,9 +77,7 @@ abstract public class EmbeddedSolrServerTestBase extends 
SolrTestCaseJ4 {
 
   private void writeTo(final Path base, final ContentStream... contents) {
     try {
-      if (!Files.exists(base)) {
-        Files.createDirectories(base);
-      }
+      Files.createDirectories(base);
 
       for (final ContentStream content : contents) {
         final File file = new File(base.toFile(), content.getName());
@@ -89,7 +88,7 @@ abstract public class EmbeddedSolrServerTestBase extends 
SolrTestCaseJ4 {
         }
       }
     } catch (final IOException e) {
-      throw new RuntimeException(e);
+      throw new UncheckedIOException(e);
     }
   }
 
diff --git 
a/solr/test-framework/src/java/org/apache/solr/cloud/MiniSolrCloudCluster.java 
b/solr/test-framework/src/java/org/apache/solr/cloud/MiniSolrCloudCluster.java
index 677bf0a..aa9e533 100644
--- 
a/solr/test-framework/src/java/org/apache/solr/cloud/MiniSolrCloudCluster.java
+++ 
b/solr/test-framework/src/java/org/apache/solr/cloud/MiniSolrCloudCluster.java
@@ -385,9 +385,7 @@ public class MiniSolrCloudCluster {
 
   private Path createInstancePath(String name) throws IOException {
     Path instancePath = baseDir.resolve(name);
-    if (!Files.exists(instancePath)) {
-      Files.createDirectory(instancePath);
-    }
+    Files.createDirectory(instancePath);
     return instancePath;
   }
 

Reply via email to