Fork me on GitHub
#clojure-dev
<
2019-01-20
>
cfleming22:01:52

Egor’s workaround works, but I still don’t understand why.

cfleming22:01:17

The good thing is that Clojure 1.10 seems to be off the hook.

cfleming22:01:44

I don’t know what he means by “Compiler.eval switches classloaders” - his fix basically forces the classloader used by the evaluation to be the classloader of the generated class. The way this works is that when the user evaluates an expression, I create an fn that looks like (fn [p1 p2 ...] <user's expression>) where the parameters are either locals from the current stack frame, or closed over values from higher stack frames. I then call RT.readString() on that, and Compiler.eval() on the result. Then I find the invoke method with the arity corresponding to the number of parameters and call that passing in the values from the local stack frames.

cfleming22:01:07

I guess the issue is that Compiler.eval() creates a new DCL which the anonymous fn class is defined in, but that’s not the one used by the subsequent evaluation of invoke.

cfleming22:01:29

I don’t know why that causes JDI to not see Object from the original classloader, though.

cfleming22:01:22

And only with Java 6+ bytecode.