diff --git a/implementation/src/main/java/io/smallrye/config/AbstractLocationConfigSourceLoader.java b/implementation/src/main/java/io/smallrye/config/AbstractLocationConfigSourceLoader.java index d8ca4f82b..f2909d88e 100644 --- a/implementation/src/main/java/io/smallrye/config/AbstractLocationConfigSourceLoader.java +++ b/implementation/src/main/java/io/smallrye/config/AbstractLocationConfigSourceLoader.java @@ -158,26 +158,28 @@ protected List tryJar(final URI uri, final int ordinal) { } protected List fallbackToUnknownProtocol(final URI uri, final int ordinal, final ClassLoader classLoader) { - final List configSources = new ArrayList<>(); + List configSources = new ArrayList<>(); try { Enumeration resources = classLoader.getResources(uri.toString()); while (resources.hasMoreElements()) { - final URL resourceUrl = resources.nextElement(); + URL resourceUrl = resources.nextElement(); if (validExtension(resourceUrl.getFile())) { - final ConfigSource mainSource = addConfigSource(resourceUrl, ordinal, configSources); + ConfigSource mainSource = addConfigSource(resourceUrl, ordinal, configSources); configSources.add(new ConfigurableConfigSource((ProfileConfigSourceFactory) profiles -> { - final List profileSources = new ArrayList<>(); + List profileSources = new ArrayList<>(); for (int i = profiles.size() - 1; i >= 0; i--) { - final int mainOrdinal = mainSource.getOrdinal() + profiles.size() - i + 1; - final URI profileUri = addProfileName(uri, profiles.get(i)); - try { - final Enumeration profileResources = classLoader.getResources(profileUri.toString()); - while (profileResources.hasMoreElements()) { - final URL profileUrl = profileResources.nextElement(); - addProfileConfigSource(profileUrl, mainOrdinal, profileSources); + int mainOrdinal = mainSource.getOrdinal() + profiles.size() - i + 1; + for (String fileExtension : getFileExtensions()) { + URI profileUri = addProfileName(uri, profiles.get(i), fileExtension); + try { + Enumeration profileResources = classLoader.getResources(profileUri.toString()); + while (profileResources.hasMoreElements()) { + final URL profileUrl = profileResources.nextElement(); + addProfileConfigSource(profileUrl, mainOrdinal, profileSources); + } + } catch (IOException e) { + // It is ok to not find the resource here, because it is an optional profile resource. } - } catch (IOException e) { - // It is ok to not find the resource here, because it is an optional profile resource. } } return profileSources; @@ -200,15 +202,18 @@ protected List tryHttpResource(final URI uri, final int ordinal) { } protected List tryProfiles(final URI uri, final ConfigSource mainSource) { - final List configSources = new ArrayList<>(); + List configSources = new ArrayList<>(); configSources.add(new ConfigurableConfigSource(new ProfileConfigSourceFactory() { @Override public Iterable getProfileConfigSources(final List profiles) { - final List profileSources = new ArrayList<>(); + List profileSources = new ArrayList<>(); for (int i = profiles.size() - 1; i >= 0; i--) { - final int ordinal = mainSource.getOrdinal() + profiles.size() - i; - final URI profileUri = addProfileName(uri, profiles.get(i)); - AbstractLocationConfigSourceLoader.this.addProfileConfigSource(toURL(profileUri), ordinal, profileSources); + int ordinal = mainSource.getOrdinal() + profiles.size() - i; + for (String fileExtension : getFileExtensions()) { + URI profileUri = addProfileName(uri, profiles.get(i), fileExtension); + AbstractLocationConfigSourceLoader.this.addProfileConfigSource(toURL(profileUri), ordinal, + profileSources); + } } return profileSources; } @@ -273,9 +278,9 @@ private boolean validExtension(final String resourceName) { return false; } - private static URI addProfileName(final URI uri, final String profile) { + private static URI addProfileName(final URI uri, final String profile, final String fileExtension) { if ("jar".equals(uri.getScheme())) { - return URI.create("jar:" + addProfileName(URI.create(uri.getRawSchemeSpecificPart()), profile)); + return URI.create("jar:" + addProfileName(URI.create(uri.getRawSchemeSpecificPart()), profile, fileExtension)); } final String fileName = uri.getPath(); @@ -284,7 +289,7 @@ private static URI addProfileName(final URI uri, final String profile) { final int dot = fileName.lastIndexOf("."); final String fileNameProfile; if (dot != -1 && dot != 0 && fileName.charAt(dot - 1) != '/') { - fileNameProfile = fileName.substring(0, dot) + "-" + profile + fileName.substring(dot); + fileNameProfile = fileName.substring(0, dot) + "-" + profile + "." + fileExtension; } else { fileNameProfile = fileName + "-" + profile; } diff --git a/testsuite/extra/src/test/java/io/smallrye/config/test/location/PropertiesLocationTest.java b/testsuite/extra/src/test/java/io/smallrye/config/test/location/PropertiesLocationTest.java index aff6d3167..9c6b2fb18 100644 --- a/testsuite/extra/src/test/java/io/smallrye/config/test/location/PropertiesLocationTest.java +++ b/testsuite/extra/src/test/java/io/smallrye/config/test/location/PropertiesLocationTest.java @@ -429,6 +429,40 @@ void illegalChars(@TempDir Path tempDir) throws Exception { } } + @Test + void mixedExtensions(@TempDir Path tempDir) throws Exception { + JavaArchive jar = ShrinkWrap + .create(JavaArchive.class, "resources.jar") + .addAsResource(new StringAsset("my:\n" + + " prop:\n" + + " one: 1234\n"), "resources.yml") + .addAsResource(new StringAsset("my:\n" + + " prop:\n" + + " one: 5678\n"), "resources-prod.yaml"); + + Path filePath = tempDir.resolve("resources.jar"); + jar.as(ZipExporter.class).exportTo(filePath.toFile()); + + ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader(); + try (URLClassLoader urlClassLoader = new URLClassLoader(new URL[] { + new URL("jar:" + filePath.toUri() + "!/") + }, contextClassLoader)) { + Thread.currentThread().setContextClassLoader(urlClassLoader); + + SmallRyeConfig config = new SmallRyeConfigBuilder() + .addDiscoveredSources() + .addDefaultInterceptors() + .withProfile("prod") + .withDefaultValue(SMALLRYE_CONFIG_LOCATIONS, "jar:" + filePath.toUri() + "!/resources.yml") + .build(); + + assertEquals("5678", config.getRawValue("my.prop.one")); + assertEquals(2, countSources(config, YamlConfigSource.class)); + } finally { + Thread.currentThread().setContextClassLoader(contextClassLoader); + } + } + private static URLClassLoader urlClassLoader(ClassLoader parent, String... urls) { return new URLClassLoader(Stream.of(urls).map(spec -> { try {