Kotlin / kotlin-jupyter

Kotlin kernel for Jupyter/IPython
Apache License 2.0
1.1k stars 105 forks source link

Library Loading with %use only works when `homeDir` is not null, but invalid `homeDir` works fine #359

Closed fmagin closed 2 years ago

fmagin commented 2 years ago

All of the examples are on https://github.com/Kotlin/kotlin-jupyter/blob/stable-kotlin-2 but it doesn't look like this changed compared to current master

Problem

Usually I embed the kernel via

IkotlinKt.embedKernel(connectionFile, resolutionInfoProvider, Collections.singletonList(context))

but in the resulting kernel it is not possible to load a library definition, even if explicitly specifying a full path because in: https://github.com/Kotlin/kotlin-jupyter/blob/e5126191f53cb0a949d99d417fa60e8b8cbdb3ed/src/main/kotlin/org/jetbrains/kotlinx/jupyter/libraries/LibrariesProcessorImpl.kt#L66-L67

libraries is null, and the ReplException is thrown.

this happens because embedKernel passes null for a homeDir, https://github.com/Kotlin/kotlin-jupyter/blob/e5126191f53cb0a949d99d417fa60e8b8cbdb3ed/src/main/kotlin/org/jetbrains/kotlinx/jupyter/ikotlin.kt#L96

then the resolverConfig isn't created: https://github.com/Kotlin/kotlin-jupyter/blob/e5126191f53cb0a949d99d417fa60e8b8cbdb3ed/src/main/kotlin/org/jetbrains/kotlinx/jupyter/config.kt#L164 and then there are no libraries to pass when the LibrariesProcessor is constructed: https://github.com/Kotlin/kotlin-jupyter/blob/e5126191f53cb0a949d99d417fa60e8b8cbdb3ed/src/main/kotlin/org/jetbrains/kotlinx/jupyter/repl.kt#L242

If I instead use the following code to create the kernel it works, despite the homeDir being a completely invalid directory:

        var config = KernelConfig.Companion.fromConfig(
                KernelJupyterParams.Companion.fromFile(connectionFile),
                EmptyResolutionInfoProvider.INSTANCE,
                cp,
                new File("/NOTEXISTING/"),
                true);
        IkotlinKt.kernelServer(config, ConfigKt.getDefaultRuntimeProperties(), Collections.singletonList(context));

with this I can also run %use example in the kernel, and it will correctly load the file at /home/myusername/.jupyter_kotlin/libraries/example.json, so some other code knows the default homedir anyway.

Possible Fixes

Create resolverConfig with null homeDir

loadResolverConfig has a signature that requires the homeDir to be not null https://github.com/Kotlin/kotlin-jupyter/blob/e5126191f53cb0a949d99d417fa60e8b8cbdb3ed/src/main/kotlin/org/jetbrains/kotlinx/jupyter/config.kt#L172

but the called getStandardResolver is fine with a homeDir of null again.

https://github.com/Kotlin/kotlin-jupyter/blob/e5126191f53cb0a949d99d417fa60e8b8cbdb3ed/src/main/kotlin/org/jetbrains/kotlinx/jupyter/libraries/resolutionUtil.kt#L14-L21

Change the signature of embedKernel to allow passing a homeDir

I don't know what this homeDir value actually achieves, and it might be useful for code using embedKernel to correctly set this. But because a null homeDir doesn't raise an issues in my case it should probably be an optional parameter. And then it should IMO still be possible to load library definitions from a full path or from the .jupyter_kotlin/libraries/ directory even if no homeDir is passed.