Sharing dynamically loaded classes with JShell instance

后端 未结 3 679
不知归路
不知归路 2021-01-31 18:45

Please view the edits below

I\'m trying to create a JShell instance that gives me access to, and lets me interact with objects in the <

3条回答
  •  温柔的废话
    2021-01-31 19:07

    The solution is to create a custom LoaderDelegate implementation, that supplies instances of already loaded classes instead of loading them again. A simple example is to use the default implementation, DefaultLoaderDelegate (source) and override the findClass method of its internal RemoteClassLoader

    @Override
    protected Class findClass(String name) throws ClassNotFoundException {
        byte[] b = classObjects.get(name);
        if (b == null) {
            Class c = null;
            try {
                c = Class.forName(name);//Use a custom way to load the class
            } catch(ClassNotFoundException e) {
            }
            if(c == null) {
                return super.findClass(name);
            }
            return c;
        }
        return super.defineClass(name, b, 0, b.length, (CodeSource) null);
    }
    

    To create a working JShell instance, use the following code

    JShell shell = JShell.builder()
        .executionEngine(new ExecutionControlProvider() {
            @Override
            public String name() {
                return "name";
            }
    
            @Override
            public ExecutionControl generate(ExecutionEnv ee, Map map) throws Throwable {
                return new DirectExecutionControl(new CustomLoaderDelegate());
            }
        }, null)
        .build();
    shell.addToClasspath("Example.jar");//Add custom classes to Classpath, otherwise they can not be referenced in the JShell
    

提交回复
热议问题