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