[External] : Re: Local execution - class loader & class path issues

Jan Lahoda jan.lahoda at oracle.com
Tue Aug 15 15:09:48 UTC 2023


On 15. 08. 23 16:41, Archie Cobbs wrote:

> Hi Jan,
>
> Thanks for taking a look.
>
> On Tue, Aug 15, 2023 at 8:12 AM Jan Lahoda <jan.lahoda at oracle.com> wrote:
>
>
>>     *Question*: Shouldn't LoaderDelegate.addToClasspath() have been
>>     passed the --class-path flag at some point in the example above?
>>     JShell's LocalExecutionControl uses DefaultLoaderDelegate, which
>>     uses a class loader of type
>>     DefaultLoaderDelegate.RemoteClassLoader. This would have added
>>     classes to RemoteClassLoader's class path.
>
>     Possibly.
>
> Thanks for the mild endorsement :) If you don't object I may file a 
> bug for this.


Sure, please do!


>
>>     *Question*: Shouldn't DefaultLoaderDelegate$RemoteClassLoaderuse
>>     the current thread's context loader as its parent loader instead
>>     of defaulting to the system class loader?
>
>     If that was done from the beginning, maybe. Now, probably not, as
>     that would be an incompatible change. Should be possible to have a
>     custom ExecutionControl (an instance of or subtype of
>     LocalExecutionControl), with custom LoaderDelegate (where,
>     possibly, there could be a factory for DefaultLoaderDelegate
>     taking a custom ClassLoader). Does not seem this should be very
>     too difficult?
>
> Yes, it's not too difficult and I've already done it (link 
> <https://urldefense.com/v3/__https://github.com/archiecobbs/java-console-toolkit/blob/main/jshell/src/main/java/org/dellroad/jct/jshell/LocalContextExecutionControlProvider.java__;!!ACWV5N9M2RV99hQ!NLf38Yz7eZhnS-RW-sdl_Rq5zTa9_4oYqZrKGZEtJm0olgVuLNX3UGDo22Xtt2e0Fdi3pvudhaBLhh6m8YjX7jY$>) 
> but it's still an annoying hassle...
>
> But I think we can get the best of both worlds, by adding a new 
> parameter that LocalExecutionControlProvider would accept, e.g. 
> contextLoaderParent=true. This would obviate the need for writing 
> custom a ExecutionControl but also not change the current behavior. Do 
> you see any issue with this idea?


If a new constructor for LocalExecutionControlProvider taking (probably) 
the ClassLoader would work, that would be a very good solution, I think.


>
>     (I am a bit confused about the command line example - at least the
>     "agent" (i.e. the DirectExecutionControl/LocalExecutionControl)
>     must run inside your target VM.)
>
> I was probably unclear. My point is that, if we're just looking at the 
> available JShell flags and parameters, you have zero control over the 
> execution class path when using local execution. The only control 
> available at all is the JVM classpath setting, which is what that 
> example shows.
>
> This is just a restatement of problem #1, i.e., the --class-path flag 
> is effectively broken when using local execution, because it affects 
> only the compilation class path, and not the execution class path.
>
>
>>     *Question*: Should JShell provide a way to "best effort" extract
>>     a compilation class path from a given ClassLoader (and its
>>     parents)? It could work for any URLClassLoader instances, but
>>     being part of the JDK it could also take advantage of
>>     inter-module access to the system and other built-in class
>>     loaders, which are all of type
>>     jdk.internal.loader.BuiltinClassLoader, which has an internal
>>     URLClassPath field.
>
>     Sorry, I don't think so. There has been some thinking some time
>     ago on supporting compilation based on ClassLoaders, but it is
>     fairly tricky, and very easy.
>
> I assume you meant "not very easy" there...


Yes, sorry.


>
> I'm curious to learn more.  Do you recall the upshot of that thinking? 
> Does it "work"? If not, what are the limitations?


Generally, as far as I know, ClassLoaders can load a resource/class 
given a name, but cannot provide a list of things under a 
directory/package. This causes two problems, IIRC:

- given a file containing only:

import does.not.exist.*;

I believe the specification says there should be an error for this 
import - but for that, we would need to know if there's a class (or 
possibly source) file under 'does.not.exist' or not. (There are some 
similar constrains on exports and esp. opens, but those are not relevant 
to JShell.)

- when the code contains something like "java.util.List", javac won't 
try to load "java.util.List". It will rather list the content of the 
whole "java.util" package, and look if there's a "List.class" (or alike) 
inside. If I remember correctly from the time I was experimenting with 
this, it is probably not impossible to change, but not easy, and 
consequences are not completely clear.


Jan


>     Having heuristics inside JShell to read some data from some
>     ClassLoaders does not sounds like a very good idea to me, sorry.
>
> I have to agree. This would be gross/hacky and I don't really like it 
> either (even though this is the workaround I'm currently being forced 
> to use).
>
> For the sake of argument, suppose we found a reliable way to make a 
> ClassLoader look like a JavaFileManager. Then all that would be 
> missing is a way to configure it in the JavaShellToolBuilder.
>
> Is there any particular reason why JavaShellToolBuilder couldn't have 
> a fileManager() method like JShell.Builder does?
>
> Thanks,
> -Archie
>
> -- 
> Archie L. Cobbs
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/kulla-dev/attachments/20230815/34425b0b/attachment.htm>


More information about the kulla-dev mailing list