This is an automated email from the git hooks/post-receive script. New commit to branch feature/jdk11 in repository nuiton-utils. See https://gitlab.nuiton.org/nuiton/nuiton-utils.git commit 0f0d32cbf3e1cebac4f9af899a3bfbe4bafa8bd4 Author: Arnaud Thimel <thimel@codelutin.com> Date: Mon Jan 6 17:30:29 2020 +0100 Rewrite org.nuiton.util.Resource#getURLs(java.lang.String, java.net.URLClassLoader) to be compatible with Java 9+ --- src/main/java/org/nuiton/util/Resource.java | 80 ++++++++++++++++++++++--- src/test/java/org/nuiton/util/ResourceTest.java | 32 +++++++++- 2 files changed, 103 insertions(+), 9 deletions(-) diff --git a/src/main/java/org/nuiton/util/Resource.java b/src/main/java/org/nuiton/util/Resource.java index 5c9c078..6df76ab 100644 --- a/src/main/java/org/nuiton/util/Resource.java +++ b/src/main/java/org/nuiton/util/Resource.java @@ -32,18 +32,26 @@ import java.io.FileInputStream; import java.io.IOException; import java.net.JarURLConnection; import java.net.MalformedURLException; +import java.net.URI; import java.net.URISyntaxException; import java.net.URL; import java.net.URLClassLoader; import java.net.URLConnection; +import java.nio.file.FileSystemNotFoundException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; import java.util.ArrayList; import java.util.Collections; import java.util.Enumeration; import java.util.List; +import java.util.Objects; +import java.util.Optional; import java.util.jar.Attributes; import java.util.jar.JarEntry; import java.util.jar.JarFile; import java.util.jar.Manifest; +import java.util.stream.Stream; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; import java.util.zip.ZipInputStream; @@ -158,23 +166,79 @@ public class Resource { // Resource * Retourner la liste des fichiers du classLoader. Ces fichiers doivent * correspondre au pattern donne. * - * @param classLoader classloader to use (if null, use {@link ClassLoader#getSystemClassLoader()} + * @param urlClassLoader classloader to use (if null, use {@link ClassLoader#getSystemClassLoader()} * @param pattern le nom du fichier a extraire du fichier compressé ou * du repertoire doit correspondre au pattern (repertoire + nom * compris). * @return la liste des urls correspondant au pattern */ - public static List<URL> getURLs(String pattern, URLClassLoader classLoader) { - if (classLoader == null) { + public static List<URL> getURLs(String pattern, URLClassLoader urlClassLoader) { + + Optional<URLClassLoader> notNullUrlClassLoader = Optional.ofNullable(urlClassLoader); + + // Si on a pas d'URLClassLoader on essaye de prendre celui du system + if (!notNullUrlClassLoader.isPresent()) { ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader(); if (systemClassLoader instanceof URLClassLoader) { - classLoader = (URLClassLoader) systemClassLoader; - } else { - throw new UnsupportedOperationException(Resource.class.getName() + " is not compatible with Java 9+ so far. See https://gitlab.nuiton.org/nuiton/nuiton-utils/issues/319"); + notNullUrlClassLoader = Optional.of((URLClassLoader) systemClassLoader); + } + } + + if (notNullUrlClassLoader.isPresent()) { + URL[] urls = ClassLoaderUtil.getURLs(notNullUrlClassLoader.get()); + List<URL> result = getURLs(pattern, urls); + return result; + } else { + // Malgré les tentatives impossible de trouver un URLClassLoader, donc on va parcourir les ressources accessibles + List<URL> urls = walkThroughClassLoaderAndGetURLs(pattern); + return urls; + } + } + + private static URL safeUriToUrlOrNull(URI uri) { + try { + return uri.toURL(); + } catch (MalformedURLException e) { + if (log.isWarnEnabled()) { + log.warn("An error occured while walking through classpath, it may not work as expected",e); } + return null; + } + } + + protected static List<URL> walkThroughClassLoaderAndGetURLs(String pattern) { + + try { + List<URL> classpathUrls = new ArrayList<>(); + + Enumeration<URL> urls = ClassLoader.getSystemResources(""); + while (urls.hasMoreElements()) { + try { + try (Stream<Path> walk = Files.walk(Paths.get(urls.nextElement().toURI()))) { + + walk.filter(Files::isRegularFile) + .map(Path::toUri) + .map(Resource::safeUriToUrlOrNull) + .filter(Objects::nonNull) + .filter(url -> url.getPath().matches(pattern)) + .forEach(classpathUrls::add); + + } catch (IOException | FileSystemNotFoundException e) { + if (log.isWarnEnabled()) { + log.warn("An error occurred while walking through classpath, it may not work as expected", e); + } + } + } catch (URISyntaxException urise) { + if (log.isWarnEnabled()) { + log.warn("An error occurred while walking through classpath, it may not work as expected", urise); + } + } + } + + return classpathUrls; + } catch (IOException e) { + return new ArrayList<>(); } - URL[] arrayURL = ClassLoaderUtil.getURLs(classLoader); - return getURLs(pattern, arrayURL); } /** diff --git a/src/test/java/org/nuiton/util/ResourceTest.java b/src/test/java/org/nuiton/util/ResourceTest.java index b9fd902..c61d25c 100644 --- a/src/test/java/org/nuiton/util/ResourceTest.java +++ b/src/test/java/org/nuiton/util/ResourceTest.java @@ -50,7 +50,12 @@ public class ResourceTest { // ResourceTest @Test public void testGetURL() { - Resource.getURL("/zip/not-a-zip.zip"); + + URL url = Resource.getURL("README.md"); + Assert.assertNotNull(url); + + url = Resource.getURL("/zip/not-a-zip.zip"); + Assert.assertNotNull(url); } @Test(expected = ResourceNotFoundException.class) @@ -58,6 +63,31 @@ public class ResourceTest { // ResourceTest Resource.getURL("/zip/non-existent-file.zip"); } + @Test + public void testGetURLs() { + List<URL> result; + + result = Resource.getURLs(".*zip"); + Assert.assertNotNull(result); + Assert.assertEquals(2, result.size()); + + result = Resource.getURLs(".*zap"); + Assert.assertNotNull(result); + Assert.assertEquals(1, result.size()); + + result = Resource.getURLs(".*zop"); + Assert.assertNotNull(result); + Assert.assertEquals(0, result.size()); + + result = Resource.getURLs(".*windows.properties"); + Assert.assertNotNull(result); + Assert.assertEquals(1, result.size()); + + result = Resource.getURLs(".*properties/windows.properties"); + Assert.assertNotNull(result); + Assert.assertEquals(1, result.size()); + } + @Test public void testGetURLsFromDirectory() throws Exception { -- To stop receiving notification emails like this one, please contact nuiton.org SCM administrator <admin+scm@nuiton.org>.