Skip to content

Commit

Permalink
[FLINK-37183][clients] Fix symbolic links not being followed in "usrlib"
Browse files Browse the repository at this point in the history
Closes #26052

Co-authored-by: Joery van den Hoff <[email protected]>
  • Loading branch information
2 people authored and ferenc-csaky committed Jan 22, 2025
1 parent 2dfac96 commit 95450ed
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.file.FileVisitOption;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
Expand Down Expand Up @@ -237,7 +238,7 @@ private static List<URL> getClasspathsFromUserLibDir(
return Collections.emptyList();
}

try (Stream<Path> files = Files.walk(userLibDir.toPath())) {
try (Stream<Path> files = Files.walk(userLibDir.toPath(), FileVisitOption.FOLLOW_LINKS)) {
return getClasspathsFromArtifacts(files, jarFile);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,10 @@ class DefaultPackagedProgramRetrieverITCase {
ClasspathProviderExtension singleEntryClassClasspathProvider =
ClasspathProviderExtension.createWithSingleEntryClass();

@RegisterExtension
ClasspathProviderExtension symlinkClasspathProvider =
ClasspathProviderExtension.createWithSymlink();

@RegisterExtension
ClasspathProviderExtension multipleEntryClassesClasspathProvider =
ClasspathProviderExtension.createWithMultipleEntryClasses();
Expand Down Expand Up @@ -522,6 +526,34 @@ void testRetrieveFromJarFileWithNonRootUserLib()
assertThat(actualClasspath).isEqualTo(expectedClasspath);
}

@Test
void testRetrieveFromJarFileWithSymlinkUserLib()
throws IOException, FlinkException, ProgramInvocationException {
final File actualUsrLib = new File(symlinkClasspathProvider.getDirectory(), "usrlib");
final PackagedProgramRetriever retrieverUnderTest =
DefaultPackagedProgramRetriever.create(
actualUsrLib,
// the testJob jar is not on the user classpath
testJobEntryClassClasspathProvider.getJobJar(),
null,
null,
ClasspathProviderExtension.parametersForTestJob("suffix"),
new Configuration());
final JobGraph jobGraph = retrieveJobGraph(retrieverUnderTest, new Configuration());

assertThat(jobGraph.getUserJars())
.contains(
new org.apache.flink.core.fs.Path(
testJobEntryClassClasspathProvider.getJobJar().toURI()));
final List<String> actualClasspath =
jobGraph.getClasspaths().stream().map(URL::toString).collect(Collectors.toList());
final List<String> expectedClasspath =
extractRelativizedURLsForJarsFromDirectory(actualUsrLib);

assertThat(actualClasspath).hasSize(2);
assertThat(actualClasspath).isEqualTo(expectedClasspath);
}

@Test
void testRetrieveFromJarFileWithArtifacts()
throws IOException, FlinkException, ProgramInvocationException {
Expand Down Expand Up @@ -684,6 +716,11 @@ private static List<String> extractRelativizedURLsForJarsFromDirectory(File dire
final List<String> relativizedURLs = new ArrayList<>();
final Path workingDirectory = FileUtils.getCurrentWorkingDirectory();
for (File file : Preconditions.checkNotNull(directory.listFiles())) {
if (file.isDirectory()) {
relativizedURLs.addAll(extractRelativizedURLsForJarsFromDirectory(file));
continue;
}

if (!FileUtils.isJarFile(file.toPath())) {
// any non-JARs are filtered by PackagedProgramRetrieverImpl
continue;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;

import static org.assertj.core.api.Assertions.assertThat;

/**
* {@code ClasspathProviderExtension} offers utility methods for creating a classpath based on
* actual jars.
Expand Down Expand Up @@ -92,6 +94,24 @@ public static ClasspathProviderExtension createWithSingleEntryClass() {
JOB_JAR_PATH.toFile());
}

public static ClasspathProviderExtension createWithSymlink() {
return new ClasspathProviderExtension(
"_user_dir_with_symlink",
directory -> {
final File actualUsrLib = new File(directory, "usrlib");
final File symLinkDir = new File(directory, "symlink");
assertThat(actualUsrLib.mkdirs()).isTrue();
assertThat(symLinkDir.mkdirs()).isTrue();

copyJar(JOB_LIB_JAR_PATH, symLinkDir);
copyJar(JOB_JAR_PATH, actualUsrLib);

Files.createSymbolicLink(
actualUsrLib.toPath().resolve("symlink"), symLinkDir.toPath());
},
JOB_JAR_PATH.toFile());
}

public static ClasspathProviderExtension createWithMultipleEntryClasses() {
return new ClasspathProviderExtension(
"_user_dir_with_multiple_entry_classes",
Expand Down

0 comments on commit 95450ed

Please sign in to comment.