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.bate...@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