JEP 330 and MemoryClassLoader.getResourceAsStream
Peter Levart
peter.levart at gmail.com
Tue Sep 4 12:17:12 UTC 2018
Hello,
On 08/27/2018 04:11 AM, seth lytle wrote:
> to add to what Jon said, recompiling doesn't necessarily provide the
> correct info as it may have been manipulated by another agent or
> classloader (there is a similar weakness in my current workaround)
>
> getResourceAsStream (getRAS) is:
> - robust: you know it's the same bytecode your parent CL used
> - flexible: you can run woven and unwoven code concurrently
> - chainable: downstream CLs will see your modifications
>
>
> i haven't been able to think of anything that getResource adds, though
> some people may use that instead
>
> on the core-libs-dev list david lloyd wrote:
> > Why not go ahead and implement getResource as well? It's not *that*
> > big of a deal to add a URL handler, and it would be a fairly trivial one.
>
>
> @jon - would you like to reply to that or should i ?
>
> my feeling is that we're better off without getResource (getR)
> - the javadocs appear to allow differences between getR and getRAS
> - getR adds complexity, startup cost and increases footprint
Not that much. Most code can be in separate classes which are loaded
only if .getResourceXXX is actually used.
> - we're not aware of a consumer of the getR api
Which does not mean there is none.
> - the only resource is bytecode, and that's naturally accessed as a stream
> - many things are changing with java 11 so any bytecode-modifying
> library is likely to need to make source code changes anyway
>
> the only problem i see with not implementing getR is that there's no
> way to convey to a hypothetical consumer of the API that the bytecode
> that they're looking for is available via getRAS
The correct way, I think, is to implement findResource() and
findResources(). getResource(), getResources() and getResourceAsStream()
are just front-end methods to be called by users. They implement
ClassLoader delegation model and call findResource(s) at appropriate
time. Making getResourceAsStream() available, but getResource() always
return null (or even throw exception?) would be a precedent, I think.
Here's a prototype that works and is not that complicated:
http://cr.openjdk.java.net/~plevart/jdk-dev/MemoryClassLoader_getResource/webrev.01/
Someone might say that the URL protocol in this implementation does not
allow parsing such URL(s) from String(s). That's true, but if one wanted
to do that, one would have to identify (in the URL) the target
MemoryClassLoader instance. There may be more than one MemoryClassLoader
instance in the JVM. Comparing it to other protocols: in
http://host:port/path/resource, the host:port part of the URL uniquely
identifies the http server, where the resources are located; in
file:///path/resource, the protocol refers to the single local file
system on the host machine where the JVM is running, etc. How would one
identify multiple instances of MemoryClassLoader such that their unique
"names" would be known in advance? No way.
I think that the presented prototype strikes the balance where the full
resource resolving API of ClassLoader is implemented, while the URL
protocol is not supported in a way that would allow parsing such URL(s)
from String(s).
If this is acceptable compromise, I suggest moving in this direction.
Regards, Peter
More information about the compiler-dev
mailing list