On Thu, 2 Sep 2021 11:43:46 GMT, Alan Bateman <al...@openjdk.org> wrote:

>> Using jarIndex for Hibench, there is an unexpected behavior with the 
>> exception "Exception in thread "main" 
>> org.apache.hadoop.fs.UnsupportedFileSystemException: No FileSystem for 
>> scheme "hdfs"".
>> 
>> After investigating it, it is related to the usage of ServiceLoader with 
>> JarIndex.
>> The below stack shows the issue with JDK11:
>> 
>> getResource:1016, URLClassPath$JarLoader (jdk.internal.loader)
>> getResource:937, URLClassPath$JarLoader (jdk.internal.loader)
>> findResource:912, URLClassPath$JarLoader (jdk.internal.loader)
>> next:341, URLClassPath$1 (jdk.internal.loader)
>> hasMoreElements:351, URLClassPath$1 (jdk.internal.loader)
>> hasNext:355, BuiltinClassLoader$1 (jdk.internal.loader)
>> hasMoreElements:363, BuiltinClassLoader$1 (jdk.internal.loader)
>> next:3032, CompoundEnumeration (java.lang)
>> hasMoreElements:3041, CompoundEnumeration (java.lang)
>> nextProviderClass:1203, ServiceLoader$LazyClassPathLookupIterator (java.util)
>> hasNextService:1221, ServiceLoader$LazyClassPathLookupIterator (java.util)
>> hasNext:1265, ServiceLoader$LazyClassPathLookupIterator (java.util)
>> hasNext:1300, ServiceLoader$2 (java.util)
>> hasNext:1385, ServiceLoader$3 (java.util)
>> 
>> The below API tries to get all the resources with the same name.
>> 
>> public Enumeration<URL> findResources(final String name,
>>                                      final boolean check) 
>>  ```
>> After using JarIndex, URLClassPath.findResources only returns 1 URL.
>> It is the same as the description in JDK-6957241.
>> 
>> The issue still exists in JDK18.
>> 
>> Root cause:
>> 
>> public Enumeration<URL> findResources(final String name,
>>                                      final boolean check) {
>>         return new Enumeration<>() {
>>             private int index = 0;
>>             private URL url = null;
>> 
>>             private boolean next() {
>>                 if (url != null) {
>>                     return true;
>>                 } else {
>>                     Loader loader;
>>                     while ((loader = getLoader(index++)) != null) {
>>                         url = loader.findResource(name, check);
>>                         if (url != null) {
>>                             return true;
>>                         }
>>                     }
>>                     return false;
>>                 }
>>             }
>> ...
>>         };
>>     }
>> 
>> With the JarIndex, there is only one loader which is corresponding to the 
>> jar with the index due to the implementation in JarLoader.getResource(final 
>> String name, boolean check, Set<String> visited).
>> 
>> Loaders corresponding to other jar packages will not appear in this while.
>> So it only returns 1 instance.
>> 
>> To solve the issue, I change the implementation "private boolean next()".
>> If the loader has index, traverse the index and get all the resource from 
>> the loader.
>
> @wxiang I think there is at least some support for removing the JAR indexing 
> support rather than trying to fix findResources. The issue of what to do with 
> the legacy JAR index mechanism came up during JDK 9 in the context of modular 
> JARs and also Multi-Release JARs but it was too much to take on at the time. 
> Would you be interested in working out the changes to remove it?

@AlanBateman Sure, I am interested in it.

-------------

PR: https://git.openjdk.java.net/jdk/pull/5316

Reply via email to