Ensure ClassPathResources with same path and ClassLoader are equal
Prior to this commit, if two ClassPathResource instances were constructed differently (one from an absolute path and one from a path relative to a Class) but had the same absolute path and the same ClassLoader, they were effectively equal, but ClassPathResource#equals returned false. This commit addresses this by revising the logic in ClassPathResource#equals accordingly. Closes gh-29263
This commit is contained in:
@@ -24,7 +24,6 @@ import java.net.URL;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
@@ -271,9 +270,14 @@ public class ClassPathResource extends AbstractFileResolvingResource {
|
||||
if (!(other instanceof ClassPathResource otherRes)) {
|
||||
return false;
|
||||
}
|
||||
return (this.path.equals(otherRes.path) &&
|
||||
ObjectUtils.nullSafeEquals(this.classLoader, otherRes.classLoader) &&
|
||||
ObjectUtils.nullSafeEquals(this.clazz, otherRes.clazz));
|
||||
if (!this.absolutePath.equals(otherRes.absolutePath)) {
|
||||
return false;
|
||||
}
|
||||
ClassLoader thisClassLoader =
|
||||
(this.classLoader != null ? this.classLoader : this.clazz.getClassLoader());
|
||||
ClassLoader otherClassLoader =
|
||||
(otherRes.classLoader != null ? otherRes.classLoader : otherRes.clazz.getClassLoader());
|
||||
return thisClassLoader.equals(otherClassLoader);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -30,6 +30,8 @@ import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.io.TempDir;
|
||||
|
||||
import org.springframework.core.OverridingClassLoader;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
import static org.junit.jupiter.api.io.CleanupMode.NEVER;
|
||||
@@ -79,6 +81,29 @@ class ClassPathResourceTests {
|
||||
assertThat(resource2).isEqualTo(resource1);
|
||||
}
|
||||
|
||||
@Test
|
||||
void resourcesWithEquivalentAbsolutePathsFromTheSameClassLoaderAreEqual() {
|
||||
Resource resource1 = new ClassPathResource("Resource.class", getClass());
|
||||
Resource resource2 = new ClassPathResource("org/springframework/core/io/Resource.class", getClass().getClassLoader());
|
||||
assertThat(resource1).isEqualTo(resource2);
|
||||
assertThat(resource2).isEqualTo(resource1);
|
||||
}
|
||||
|
||||
@Test
|
||||
void resourcesWithEquivalentAbsolutePathsFromDifferentClassLoadersAreNotEqual() {
|
||||
class SimpleThrowawayClassLoader extends OverridingClassLoader {
|
||||
SimpleThrowawayClassLoader(ClassLoader parent) {
|
||||
super(parent);
|
||||
}
|
||||
}
|
||||
|
||||
Resource resource1 = new ClassPathResource("Resource.class", getClass());
|
||||
Resource resource2 = new ClassPathResource("org/springframework/core/io/Resource.class",
|
||||
new SimpleThrowawayClassLoader(getClass().getClassLoader()));
|
||||
assertThat(resource1).isNotEqualTo(resource2);
|
||||
assertThat(resource2).isNotEqualTo(resource1);
|
||||
}
|
||||
|
||||
@Test
|
||||
void relativeResourcesAreEqual() throws Exception {
|
||||
Resource resource = new ClassPathResource("dir/");
|
||||
|
||||
Reference in New Issue
Block a user