SpencerPark / IJava

A Jupyter kernel for executing Java code.
MIT License
1.1k stars 215 forks source link

Impossible to use JShell commands like /list #128

Open nicolalandro opened 2 years ago

nicolalandro commented 2 years ago

I try to do this instructions:

import io.github.spencerpark.ijava.IJava;
IJava.getKernelInstance().evalRaw("/list")

But the result is:

---------------------------------------------------------------------------
io.github.spencerpark.ijava.execution.CompilationException: null
    at io.github.spencerpark.ijava.execution.CodeEvaluator.evalSingle(CodeEvaluator.java:127)
    at io.github.spencerpark.ijava.execution.CodeEvaluator.eval(CodeEvaluator.java:147)
    at io.github.spencerpark.ijava.JavaKernel.evalRaw(JavaKernel.java:276)
    at .(#76:1)

How to get the lines of the cels? In jupyter python I only run _ih[line_number], I need it for Printing the line near the Jacoco Coverage you can see the full code here.

To quickly replicate:

santiagobasulto commented 3 months ago

Having the same issue, were you able to find a solution?

andrus commented 3 months ago

@santiagobasulto : iJava kernel is using jdk.jshell.JShell, but all the commands like /list are defined downstream from that inside jdk.internal.jshell.tool.JShellTool, and hence are not known in the Jupyter environment, and you have to use JShell API directly to achieve a similar effect.

On top of that, you can't directly access JShell in IJava. I just opened a task in JJava (a supported descendant of IJava) to expose JShell, so hopefully we'll have it soon - https://github.com/dflib/jjava/issues/27

In the meantime, you can use reflection. Here is an example from JJava that can be easily converted to IJava:

import org.dflib.jjava.*;
import org.dflib.jjava.execution.*;
import jdk.jshell.*;

// access JShell via reflection
var kernel = JJava.getKernelInstance();
var f = kernel.getClass().getDeclaredField("evaluator");
f.setAccessible(true);
JShell sh = ((CodeEvaluator) f.get(kernel)).getShell();

// use JShell API to emulate JShell commands
sh.snippets().forEach(s -> System.out.println(s))