Skip to content

Commit

Permalink
Make DefaultClassPathResourceLoader handle URLs with format `jar:fi…
Browse files Browse the repository at this point in the history
…le:/{JAR_PATH}!/{PREFIX}!/{RESOURCE}` gracefully (#10092)
  • Loading branch information
guillermocalvo authored Nov 10, 2023
1 parent 9e20f4f commit 105f81b
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,12 @@
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.ProviderNotFoundException;
import java.util.Arrays;
import java.util.Collections;
import java.util.Enumeration;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import org.slf4j.helpers.NOPLogger;
Expand Down Expand Up @@ -147,6 +149,15 @@ public Optional<InputStream> getResourceAsStream(String path) {
}
}
Path pathObject = fileSystem.getPath(path);
if (!Files.exists(pathObject) && uri.toString().contains("!/")) {
// Gracefully transform a URL: "jar:file:/{JAR_PATH}!/{PREFIX}!/{RESOURCE}" to path: "{PREFIX}/{RESOURCE}"
final String altPath = Arrays.stream(uri.toString().split("\\!\\/")).skip(1).collect(Collectors.joining("/"));
final Path altPathObject = fileSystem.getPath(altPath);
if (Files.exists(altPathObject) && !Files.isDirectory(pathObject)) {
// Use this path only if the resource exists at that location
pathObject = altPathObject;
}
}
if (Files.isDirectory(pathObject)) {
return Optional.empty();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package io.micronaut.core.io.scan

import spock.lang.Specification
import spock.lang.Subject
import spock.mock.MockFactory

class DefaultClassPathResourceLoaderSpec extends Specification {

ClassLoader parent = Mock() {
getResource(_) >> {
args -> new URL("jar:" + this.class.classLoader.getResource("test.war") + "!/WEB-INF/classes!/" + args[0])
}
}

@Subject
DefaultClassPathResourceLoader loader = new DefaultClassPathResourceLoader(parent)

def 'get file resource in war file'() {
when:
Optional<InputStream> input = loader.getResourceAsStream("application.yml")
then:
!input.empty
input.get().text.contains("application configuration")
}

def 'no such resource in war file'() {
when:
Optional<InputStream> input = loader.getResourceAsStream("no-such-file.yml")
then:
input.empty
}
}
Binary file added core/src/test/resources/test.war
Binary file not shown.

0 comments on commit 105f81b

Please sign in to comment.