Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SOLR-16903: Migrate off java.io.File to java.nio.file.Path from core files #2924

Merged
merged 10 commits into from
Feb 1, 2025
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import java.io.IOException;
import java.io.InputStream;
import java.lang.invoke.MethodHandles;
import java.nio.file.FileSystems;
import java.nio.file.Path;
import org.apache.solr.common.SolrException.ErrorCode;
import org.apache.solr.common.cloud.ZooKeeperException;
Expand Down Expand Up @@ -120,8 +121,9 @@ public InputStream openResource(String resource) throws IOException {

try {
// delegate to the class loader (looking into $INSTANCE_DIR/lib jars)
// Use Path to normalize path separator
is = classLoader.getResourceAsStream(Path.of(resource).toString());
is =
classLoader.getResourceAsStream(
resource.replace(FileSystems.getDefault().getSeparator(), "/"));
} catch (Exception e) {
throw new IOException("Error opening " + resource, e);
}
Expand Down
9 changes: 5 additions & 4 deletions solr/core/src/java/org/apache/solr/core/CoreDescriptor.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import java.io.Reader;
import java.lang.invoke.MethodHandles;
import java.nio.charset.StandardCharsets;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.HashMap;
Expand Down Expand Up @@ -62,7 +63,8 @@ public class CoreDescriptor {
public static final String CORE_CONFIGSET_PROPERTIES = "configSetProperties";
public static final String SOLR_CORE_PROP_PREFIX = "solr.core.";

public static final Path DEFAULT_EXTERNAL_PROPERTIES_FILE = Path.of("conf/solrcore.properties");
public static final String DEFAULT_EXTERNAL_PROPERTIES_FILE =
dsmiley marked this conversation as resolved.
Show resolved Hide resolved
"conf" + FileSystems.getDefault().getSeparator() + "solrcore.properties";

/**
* Whether this core was configured using a configSet that was trusted. This helps in avoiding the
Expand Down Expand Up @@ -94,7 +96,7 @@ public Properties getPersistableUserProperties() {
CORE_CONFIG, "solrconfig.xml",
CORE_SCHEMA, "schema.xml",
CORE_CONFIGSET_PROPERTIES, ConfigSetProperties.DEFAULT_FILENAME,
CORE_DATADIR, Path.of("data").toString(),
CORE_DATADIR, "data" + FileSystems.getDefault().getSeparator(),
CORE_TRANSIENT, "false",
CORE_LOADONSTARTUP, "true");

Expand Down Expand Up @@ -238,8 +240,7 @@ public CoreDescriptor(
* <p>File paths are taken as read from the core's instance directory if they are not absolute.
*/
protected void loadExtraProperties() {
String filename =
coreProperties.getProperty(CORE_PROPERTIES, DEFAULT_EXTERNAL_PROPERTIES_FILE.toString());
String filename = coreProperties.getProperty(CORE_PROPERTIES, DEFAULT_EXTERNAL_PROPERTIES_FILE);
Path propertiesFile = instanceDir.resolve(filename);
if (Files.exists(propertiesFile)) {
try (Reader r = Files.newBufferedReader(propertiesFile, StandardCharsets.UTF_8)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -372,12 +372,16 @@ public InputStream openResource(String resource) throws IOException {

// Delegate to the class loader (looking into $INSTANCE_DIR/lib jars).
// We need a ClassLoader-compatible (forward-slashes) path here!
InputStream is = classLoader.getResourceAsStream(resource);
InputStream is =
classLoader.getResourceAsStream(
resource.replace(FileSystems.getDefault().getSeparator(), "/"));

// This is a hack just for tests (it is not done in ZKResourceLoader)!
// TODO can we nuke this?
if (is == null && System.getProperty("jetty.testMode") != null) {
is = classLoader.getResourceAsStream(Path.of("conf").resolve(resource).toString());
is =
classLoader.getResourceAsStream(
("conf/" + resource).replace(FileSystems.getDefault().getSeparator(), "/"));
dsmiley marked this conversation as resolved.
Show resolved Hide resolved
}

if (is == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
import java.lang.invoke.MethodHandles;
import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.nio.file.FileSystems;
import java.time.Instant;
import java.util.Collections;
import java.util.List;
Expand Down Expand Up @@ -343,7 +343,8 @@ private void downloadConfigToRepo(ConfigSetService configSetService, String conf
// getAllConfigFiles always separates file paths with '/'
for (String filePath : filePaths) {
// Replace '/' to ensure that propre file is resolved for writing.
URI uri = repository.resolve(dir, Path.of(filePath).toString());
URI uri =
repository.resolve(dir, filePath.replace("/", FileSystems.getDefault().getSeparator()));
// checking for '/' is correct for a directory since ConfigSetService#getAllConfigFiles
// always separates file paths with '/'
if (!filePath.endsWith("/")) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,14 +84,15 @@ public Path getRealPath(String path) {
return _getRealPath(path, solrHome);
}

private static Path _getRealPath(String path, Path solrHome) {
Path dir = Path.of(path);
SolrPaths.assertNotUnc(dir);
private static Path _getRealPath(String dir, Path solrHome) {
Path path = Path.of(dir);
SolrPaths.assertNotUnc(path);

// Strip the path of from being absolute to become relative to resolve with SolrHome
while (path.startsWith("/")) {
path = path.substring(1);
if (path.isAbsolute()) {
// Strip the path of from being absolute to become relative to resolve with SolrHome
path = path.subpath(0, path.getNameCount());
}

var finalPath = getFileStoreDirPath(solrHome).resolve(path);

// Guard against path traversal by asserting final path is sub path of filestore
Expand Down Expand Up @@ -432,8 +433,7 @@ public void get(String path, Consumer<FileEntry> consumer, boolean fetchmissing)
Path file = getRealPath(path);
String simpleName = file.getFileName().toString();
if (isMetaDataFile(simpleName)) {
// TODO SOLR-8282 Move to Files.newInputStream
try (InputStream is = new FileInputStream(file.toString())) {
try (InputStream is = Files.newInputStream(file)) {
consumer.accept(
new FileEntry(null, null, path) {
// no metadata for metadata file
Expand Down
5 changes: 2 additions & 3 deletions solr/core/src/java/org/apache/solr/handler/IndexFetcher.java
Original file line number Diff line number Diff line change
Expand Up @@ -1494,11 +1494,10 @@ private void copyTmpConfFiles2Conf(Path tmpconfDir) {
if (Files.exists(oldPath)) {
try {
Path backupFile =
Path.of(
oldPath
oldPath.resolveSibling(
oldPath.getFileName()
+ "."
+ getDateAsStr(new Date(Files.getLastModifiedTime(oldPath).toMillis())));
Files.createDirectories(backupFile.getParent());
Files.move(oldPath, backupFile);
} catch (Exception e) {
throw new SolrException(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -410,7 +410,9 @@ private void upgradeToManagedSchema() {
"nor under SolrConfig.getConfigDir() or the current directory. ",
"PLEASE REMOVE THIS FILE.");
} else {
Path upgradedSchemaFile = Path.of(nonManagedSchemaFile + UPGRADED_SCHEMA_EXTENSION);
Path upgradedSchemaFile =
nonManagedSchemaFile.resolveSibling(
dsmiley marked this conversation as resolved.
Show resolved Hide resolved
nonManagedSchemaFile.getFileName() + UPGRADED_SCHEMA_EXTENSION);
try {
Files.move(nonManagedSchemaFile, upgradedSchemaFile);
// Set the resource name to the managed schema so that the CoreAdminHandler returns a
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,9 +84,7 @@ public String init(NamedList<?> config, SolrCore core) {

// If indexDir is relative then create index inside core.getDataDir()
if (indexDir != null) {
if (!indexDir.isAbsolute()) {
indexDir = Path.of(core.getDataDir(), indexDir.toString());
}
indexDir = Path.of(core.getDataDir()).resolve(indexDir);
}

sourceLocation = (String) config.get(LOCATION);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,9 +89,8 @@ public Lookup create(NamedList<?> params, SolrCore core) {
params.get(INDEX_PATH) != null
? Path.of(params.get(INDEX_PATH).toString())
: Path.of(DEFAULT_INDEX_PATH);
if (!indexPath.isAbsolute()) {
indexPath = Path.of(core.getDataDir(), indexPath.toString());
}

indexPath = Path.of(core.getDataDir()).resolve(indexPath);

int minPrefixChars =
params.get(MIN_PREFIX_CHARS) != null
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,11 +76,12 @@ public Lookup create(NamedList<?> params, SolrCore core) {

// optional parameters

String indexPath =
params.get(INDEX_PATH) != null ? params.get(INDEX_PATH).toString() : DEFAULT_INDEX_PATH;
if (!Path.of(indexPath).isAbsolute()) {
indexPath = Path.of(core.getDataDir(), indexPath).toString();
}
Path indexPath =
params.get(INDEX_PATH) != null
? Path.of(params.get(INDEX_PATH).toString())
: Path.of(DEFAULT_INDEX_PATH);

indexPath = Path.of(core.getDataDir()).resolve(indexPath);

int minPrefixChars =
params.get(MIN_PREFIX_CHARS) != null
Expand Down Expand Up @@ -109,7 +110,7 @@ public Lookup create(NamedList<?> params, SolrCore core) {

try {
return new BlendedInfixSuggester(
FSDirectory.open(Path.of(indexPath)),
FSDirectory.open(indexPath),
indexAnalyzer,
queryAnalyzer,
minPrefixChars,
Expand Down
6 changes: 3 additions & 3 deletions solr/core/src/java/org/apache/solr/util/SystemIdResolver.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.file.Path;
import java.nio.file.FileSystems;
import javax.xml.stream.XMLResolver;
import javax.xml.stream.XMLStreamException;
import javax.xml.transform.Source;
Expand Down Expand Up @@ -167,9 +167,9 @@ public InputSource resolveEntity(String publicId, String systemId) throws IOExce
}

public static String createSystemIdFromResourceName(String name) {
Path pathName = Path.of(name);
name = name.replace(FileSystems.getDefault().getSeparator(), "/");
final String authority;
if (pathName.startsWith("/")) {
if (name.startsWith("/")) {
// a hack to preserve absolute filenames and keep them absolute after resolving, we set the
// URI's authority to "@" on absolute filenames:
authority = RESOURCE_LOADER_AUTHORITY_ABSOLUTE;
Expand Down
15 changes: 6 additions & 9 deletions solr/core/src/java/org/apache/solr/util/VersionedFile.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@
*/
package org.apache.solr.util;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
Expand All @@ -38,9 +36,9 @@ public class VersionedFile {
* the last fileName.* after being sorted lexicographically.
* Older versions of the file are deleted (and queued for deletion if
* that fails).
* TODO SOLR-8282 dirName should be a Path instead of string
*/
public static InputStream getLatestFile(String dirName, String fileName)
throws FileNotFoundException {
public static InputStream getLatestFile(String dirName, String fileName) throws IOException {
Collection<Path> oldFiles = null;
final String prefix = fileName + '.';
Path f = Path.of(dirName, fileName);
Expand All @@ -66,23 +64,22 @@ public static InputStream getLatestFile(String dirName, String fileName)
SolrException.ErrorCode.SERVER_ERROR, "Unable to list files in " + dir, e);
}

f = Path.of(dir.toString(), fileList.getLast().getFileName().toString());
f = dir.resolve(fileList.getLast());
oldFiles = new ArrayList<>();
for (int i = 0; i < fileList.size() - 1; i++) {
oldFiles.add(Path.of(dir.toString(), fileList.get(i).toString()));
oldFiles.add(dir.resolve(fileList.get(i)));
}
}

// TODO SOLR-8282 Move to Files.newInputStream
is = new FileInputStream(f.toString());
is = Files.newInputStream(f);
} catch (Exception e) {
// swallow exception for now
}
}

// allow exception to be thrown from the final try.
if (is == null) {
is = new FileInputStream(f.toString());
is = Files.newInputStream(f);
}

// delete old files only after we have successfully opened the newest
Expand Down
Loading