Kotlin / kotlin-jupyter

Kotlin kernel for Jupyter/IPython

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

class loading behaviour

jbaron opened this issue · comments

commented

There is a difference in class loading behaviour using @file:DependsOn("...") or using dependencies(....) in the Integration class.

When using the dependencies(....) approach, the loaded classes cannot access other classes loaded using @file:DependsOn. Seems like @file:DependsOn and dependencies(....) use different class loaders?

What exactly do you mean? What series of snippets do you compare? I don't need exact libraries, just the way you're using @file:DependsOn and dependencies

commented

The use case is:

  1. I include a file in my notebook using: @file:DependsOn("locallib.jar")

  2. I run "%use roboquant" and in the JupyterIntegration subclass I call dependencies("x:y:z"). This "x:y:z" has a dependency on "locallib.jar". However this doesn't get resolved.

I guess difficult to pinpoint with this description. I have a workarounds, so not urgent. And if I have some time, will try to investigate a bit more.

I see. Actually calling dependencies("x:y:z") will generate code @file:DependsOn("x:y:z") and will execute it. So it's mostly the same. Classloaders are obviously different, but older classloader should be a parent to the latter one. It is not a native library, right? And another thing is what classloader is used for loading classes. In some libraries, system classloader is used explicitly which is wrong. The right one could be taken from Thread.currentClassLoader() or KotlinKernelHost.lastClassLoader

commented

Ahh, classloaders inherit based on their "age", explains the behaviour I noticed.

If I put the following two statements in a single notebook input cell, it causes the issue of the second statement not being able to resolve a dependency on the first one:

@file:DependsOn("TwsApi.jar")
%use roboquant(modules=ibkr) // triggers a call to dependencies("org.roboquant:roboquant-ibkr:1.2.0")

But if I put the same two statements in their own separate input cells (and thus forcing the first one to become the parent class loader of the second one), it works fine.

Seems a workable solution for me, so I will close this issue if ok.

Yes, you're right. And one unobvious thing here: %use roboquant(modules=ibkr) will be executed before @file:DependsOn("TwsApi.jar"), because magics are always processed first, regardless of the real order of the lines