In my experience (as I've written before), ClassLoader.getResources is
perhaps the biggest pain point I've experienced in trying to move
beyond Java 8. The method seems to have been very widely used, and IMO
was considered to be preferred over Class.getResourceXxx. And it is
very confusing to use once modules come into play.
There is no simple replacement for the ability to search for resources
across jar files. Module.getResourceXxx cannot be used as it only
returns one resource from the unamed module, when there could be many
(and the docs are no particularly clear on what they do). This is very
inconvenient. Returning a stream instead of a URL also typically
involves wider code change to adopt. In addition, many projects are
still on Java 8, so can't use java.lang.Module anyway.
ServiceLoader is completely the wrong solution for config files. Its
far too heavyweight.
My solution (which I think is pretty horrible) has been to move config
files to be under META-INF.
Old location:
org/joda/convert
New location:
META-INF/org/joda/convert
Its backwards incompatible to downstream users, but at least it works
with ClassLoader.getResources
Given there are no good solutions to normal coding problems, I can't
help feeling that Jigsaw didn't get resource access quite right.
Stephen
Post by MichaÅ ZeganHello.
When reading docs for jdk9 and jdk10 it seems that those methods work in
Module.getResourceAsStream will retrieve the resource without a problem
if a package is opened to the caller module, probably including the fact
that it will find a resource when the calling module is the same as one
represented by the module object.
But, ClassLoader.getResources and other resource methods seem to require
unconditional package open.
Why? I don't quite understand that distinction.
ClassLoaders, especially in a delegation chain, have no notion of "who" is
trying to locate the resource. The ClassLoader.getResourceXXX methods are
also not final. All told, the ClassLoader.getResourceXXX cannot reliably
support qualified opens so this is why they are specified to only locate
resources in modules when the package is open to all modules.
The general guideline is to use Class or Module getResourceXXX when you want
to locate a resource in your own module or another specific module. Use
ClassLoader.getResourceXXX when you want to search the class path. If you
follow that then it makes it a lot easier to migrate existing code to
modules.
-Alan