RFR: 8353487: JShell LocalExecutionControl should allow decorating the execution task [v2]

xxDark duke at openjdk.org
Mon May 19 12:32:53 UTC 2025


On Fri, 4 Apr 2025 16:55:11 GMT, Archie Cobbs <acobbs at openjdk.org> wrote:

>> This PR adds the ability for subclasses of JShell's `LocalExecutionControl` to configure thread-local context in the execution thread that snippets execute in. Please see [JDK-8353487](https://bugs.openjdk.org/browse/JDK-8353487) for more details & rationale.
>
> Archie Cobbs has updated the pull request incrementally with one additional commit since the last revision:
> 
>   Replace decorateExecution() with doInvoke() per review suggestion.

import jdk.jshell.execution.LocalExecutionControl;

import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class LocalExecutionControlTest {

    public static void main(String[] args) throws Throwable {
        var control = new LocalExecutionControl((ClassLoader) null) {
            Object result;

            @Override
            protected Object doInvoke(Method method) throws IllegalAccessException, InvocationTargetException {
                return result = super.doInvoke(method);
            }
        };
        control.doInvoke(MethodHandles.class.getDeclaredMethod("lookup"));
        var lookup = (MethodHandles.Lookup) control.result;
        var unsafeClass = Class.forName("jdk.internal.misc.Unsafe");
        var unsafe = lookup.findStatic(unsafeClass, "getUnsafe", MethodType.methodType(unsafeClass)).invoke();
        var field = MethodHandles.Lookup.class.getDeclaredField("IMPL_LOOKUP");
        lookup = (MethodHandles.Lookup) lookup.findVirtual(unsafeClass, "getReference", MethodType.methodType(Object.class, Object.class, long.class))
                .invoke(
                        unsafe,
                        lookup.findVirtual(unsafeClass, "staticFieldBase", MethodType.methodType(Object.class, Field.class)).invoke(unsafe, field),
                        (long) lookup.findVirtual(unsafeClass, "staticFieldOffset", MethodType.methodType(long.class, Field.class)).invoke(unsafe, field)
                );
        System.out.println(lookup);
    }
}

https://github.com/openjdk/jdk/blob/3acfa9e4e7be2f37ac55f97348aad4f74ba802a0/src/java.base/share/classes/module-info.java#L204-L222
Please reconsider use of reflection (or method handles)
I was looking into jshell before to achieve something like this using https://github.com/openjdk/jdk/blob/3acfa9e4e7be2f37ac55f97348aad4f74ba802a0/src/jdk.jshell/share/classes/jdk/jshell/execution/DirectExecutionControl.java#L125 that exposes accessible `java.lang.reflect.Method` to user code, but it was not possible to get back the invocation result. With this PR, it is now possible.

-------------

PR Comment: https://git.openjdk.org/jdk/pull/24398#issuecomment-2890837027


More information about the kulla-dev mailing list