diff --git a/spring-core/src/main/java/org/springframework/core/io/ClassPathResource.java b/spring-core/src/main/java/org/springframework/core/io/ClassPathResource.java index 10a379700e6..5a71b2bf1d0 100644 --- a/spring-core/src/main/java/org/springframework/core/io/ClassPathResource.java +++ b/spring-core/src/main/java/org/springframework/core/io/ClassPathResource.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2015 the original author or authors. + * Copyright 2002-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -197,7 +197,8 @@ public class ClassPathResource extends AbstractFileResolvingResource { @Override public Resource createRelative(String relativePath) { String pathToUse = StringUtils.applyRelativePath(this.path, relativePath); - return new ClassPathResource(pathToUse, this.classLoader, this.clazz); + return (this.clazz != null ? new ClassPathResource(pathToUse, this.clazz) : + new ClassPathResource(pathToUse, this.classLoader)); } /** diff --git a/spring-core/src/test/java/org/springframework/core/io/ClassPathResourceTests.java b/spring-core/src/test/java/org/springframework/core/io/ClassPathResourceTests.java index 67e1c49d9d9..6319742edb7 100644 --- a/spring-core/src/test/java/org/springframework/core/io/ClassPathResourceTests.java +++ b/spring-core/src/test/java/org/springframework/core/io/ClassPathResourceTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -47,26 +47,6 @@ public class ClassPathResourceTests { private static final Pattern DESCRIPTION_PATTERN = Pattern.compile("^class path resource \\[(.+?)\\]$"); - private void assertDescriptionContainsExpectedPath(ClassPathResource resource, String expectedPath) { - Matcher matcher = DESCRIPTION_PATTERN.matcher(resource.getDescription()); - assertTrue(matcher.matches()); - assertEquals(1, matcher.groupCount()); - String match = matcher.group(1); - - assertEquals(expectedPath, match); - } - - private void assertExceptionContainsFullyQualifiedPath(ClassPathResource resource) { - try { - resource.getInputStream(); - fail("FileNotFoundException expected for resource: " + resource); - } - catch (IOException ex) { - assertThat(ex, instanceOf(FileNotFoundException.class)); - assertThat(ex.getMessage(), containsString(FQ_RESOURCE_PATH)); - } - } - @Test public void stringConstructorRaisesExceptionWithFullyQualifiedPath() { assertExceptionContainsFullyQualifiedPath(new ClassPathResource(FQ_RESOURCE_PATH)); @@ -74,13 +54,12 @@ public class ClassPathResourceTests { @Test public void classLiteralConstructorRaisesExceptionWithFullyQualifiedPath() { - assertExceptionContainsFullyQualifiedPath(new ClassPathResource(NONEXISTENT_RESOURCE_NAME, this.getClass())); + assertExceptionContainsFullyQualifiedPath(new ClassPathResource(NONEXISTENT_RESOURCE_NAME, getClass())); } @Test public void classLoaderConstructorRaisesExceptionWithFullyQualifiedPath() { - assertExceptionContainsFullyQualifiedPath(new ClassPathResource(FQ_RESOURCE_PATH, - this.getClass().getClassLoader())); + assertExceptionContainsFullyQualifiedPath(new ClassPathResource(FQ_RESOURCE_PATH, getClass().getClassLoader())); } @Test @@ -91,31 +70,64 @@ public class ClassPathResourceTests { @Test public void getDescriptionWithStringConstructorAndLeadingSlash() { assertDescriptionContainsExpectedPath(new ClassPathResource(FQ_RESOURCE_PATH_WITH_LEADING_SLASH), - FQ_RESOURCE_PATH); + FQ_RESOURCE_PATH); } @Test public void getDescriptionWithClassLiteralConstructor() { - assertDescriptionContainsExpectedPath(new ClassPathResource(NONEXISTENT_RESOURCE_NAME, this.getClass()), - FQ_RESOURCE_PATH); + assertDescriptionContainsExpectedPath(new ClassPathResource(NONEXISTENT_RESOURCE_NAME, getClass()), + FQ_RESOURCE_PATH); } @Test public void getDescriptionWithClassLiteralConstructorAndLeadingSlash() { assertDescriptionContainsExpectedPath( - new ClassPathResource(FQ_RESOURCE_PATH_WITH_LEADING_SLASH, this.getClass()), FQ_RESOURCE_PATH); + new ClassPathResource(FQ_RESOURCE_PATH_WITH_LEADING_SLASH, getClass()), FQ_RESOURCE_PATH); } @Test public void getDescriptionWithClassLoaderConstructor() { assertDescriptionContainsExpectedPath( - new ClassPathResource(FQ_RESOURCE_PATH, this.getClass().getClassLoader()), FQ_RESOURCE_PATH); + new ClassPathResource(FQ_RESOURCE_PATH, getClass().getClassLoader()), FQ_RESOURCE_PATH); } @Test public void getDescriptionWithClassLoaderConstructorAndLeadingSlash() { - assertDescriptionContainsExpectedPath(new ClassPathResource(FQ_RESOURCE_PATH_WITH_LEADING_SLASH, - this.getClass().getClassLoader()), FQ_RESOURCE_PATH); + assertDescriptionContainsExpectedPath( + new ClassPathResource(FQ_RESOURCE_PATH_WITH_LEADING_SLASH, getClass().getClassLoader()), FQ_RESOURCE_PATH); + } + + @Test + public void dropLeadingSlashForClassLoaderAccess() { + assertEquals("test.html", new ClassPathResource("/test.html").getPath()); + assertEquals("test.html", ((ClassPathResource) new ClassPathResource("").createRelative("/test.html")).getPath()); + } + + @Test + public void preserveLeadingSlashForClassRelativeAccess() { + assertEquals("/test.html", new ClassPathResource("/test.html", getClass()).getPath()); + assertEquals("/test.html", ((ClassPathResource) new ClassPathResource("", getClass()).createRelative("/test.html")).getPath()); + } + + + private void assertDescriptionContainsExpectedPath(ClassPathResource resource, String expectedPath) { + Matcher matcher = DESCRIPTION_PATTERN.matcher(resource.getDescription()); + assertTrue(matcher.matches()); + assertEquals(1, matcher.groupCount()); + String match = matcher.group(1); + + assertEquals(expectedPath, match); + } + + private void assertExceptionContainsFullyQualifiedPath(ClassPathResource resource) { + try { + resource.getInputStream(); + fail("FileNotFoundException expected for resource: " + resource); + } + catch (IOException ex) { + assertThat(ex, instanceOf(FileNotFoundException.class)); + assertThat(ex.getMessage(), containsString(FQ_RESOURCE_PATH)); + } } }