JEP 330 class loader getResourceAsStream
Jonathan Gibbons
jonathan.gibbons at oracle.com
Mon Aug 27 18:18:26 UTC 2018
On 8/27/18 10:51 AM, Peter Levart wrote:
>
>
> On 08/27/2018 04:47 PM, David Lloyd wrote:
>> On Mon, Aug 27, 2018 at 9:41 AM Alan Bateman
>> <Alan.Bateman at oracle.com> wrote:
>>> On 24/08/2018 18:27, 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.
>>> Right, it wouldn't be too hard but it would require a bit of
>>> plumbing to
>>> have it backed by the Memory* classes in the source file launcher. That
>>> said, a newbie starting out with "java HelloWorld.java" is unlikely to
>>> be writing code that needs the class bytes so it's more likely the more
>>> advanced cases where the code is using a library that needs the bytes.
>> AFAIK any code would expect that resources available as streams would
>> generally also be available as URLs. I'm not sure that distinguishing
>> between basic and advanced code really clarifies anything in terms of
>> the question.
>>
>
> Maybe there's a middle ground where URLStreamHandlerProvider is not
> provided. In other words, one would not be able to "parse" URL(s) from
> String(s) such that those URL(s) would be usable in providing the
> content via openConnection().getInputStream(). Such a thing would be
> very hard to achieve anyway as one can think of situations where
> there's more than one MemoryClassLoader instance present in a single
> JVM (for example, some java source launched via java launcher uses
> tools API to instruct "java" tool to launch another java source file).
> In such situation one would have to distinguish URL(s) resolving
> resources of one MemoryClassLoader from URL(s) resolving resources of
> another MemoryClassLoader. In other words, URL scheme would have to
> contain some identification of MemoryClassLoader instance and
> MemoryClassLoader instances would have to be registered in a JVM
> global Map<UUID, WeakReference<MemoryClassLoader>> for example, etc,
> etc... Just imagine the complexity of a full-blown solution.
>
> There's a middle ground where MemoryClassLoader.getResource() returns
> a URL which is usable in providing the content such that
> url.openConnection() returns an URLConnection and such
> urlConnection.getInputStream() returns an InputStream providing the
> class bytes. One can even construct URL(s) by providing some URL
> obtained by getResource() and resolving against it, effectively
> targeting the choosen MemoryClassLoader instance. Here's such
> prototype for illustration:
>
> http://cr.openjdk.java.net/~plevart/jdk-dev/MemoryClassLoader_getResource/webrev.01/
>
>
> Running: java Test.java with the following source:
>
>
> import java.io.InputStream;
> import java.net.URL;
> import java.net.URLConnection;
>
> public class Test {
> public static void main(String[] args) throws Exception {
> String name = Test.class.getName().replace('.', '/') + ".class";
> URL url = Test.class.getClassLoader().getResource(name);
> System.out.println("URL: " + url);
> URLConnection conn = url.openConnection();
> System.out.println("Content-Length: " + conn.getContentLength());
> System.out.println("Content-Type: " + conn.getContentType());
> InputStream in = conn.getInputStream();
> byte[] bytes = in.readAllBytes();
> System.out.println("bytes.length: " + bytes.length);
> }
> }
>
>
> Prints the following:
>
>
> URL: classbytes:/Test.class
> Content-Length: 1763
> Content-Type: application/octet-stream
> bytes.length: 1763
>
>
> Would that be enough for bytecode instrumentation tools?
>
> Regards, Peter
>
Peter,
I like this form of solution; I like that we can fairly easily return a
URL, from which the user can get a stream that is equivalent to using
getResourceAsStream, without having to provide the "full-blown" solution.
-- Jon
More information about the core-libs-dev
mailing list