IJava icon indicating copy to clipboard operation
IJava copied to clipboard

Executing Java code using the Java Kernel

Open colathurv opened this issue 4 years ago • 2 comments

Thanks for an awesome contribution to the Jupyter Notebook community. This is a great idea.

I need your help on the following. While using the Java Kernel with java 14.0.2 2020-07-14), the following statement in a Jupyter cell runs and provides an output of 0.

int x = 2; int x = 3; System.out.println(x);

The correct behavior which is to flag this as an error i.e., "error: variable x is already defined in method main(String[])" works when using the Python Kernel and then using a combination of %%file, %%cmd , javac, java and then having this code in a simple main.

Question : Is it possible to have the same behavior in the Java Kernel ? Should something be added to the kernel.json used by the Java kernel to induce correct behavior ?

I found a cheap way to work around it by defining a superficial method like the following: void test() { int x = 2; int x = 3; System.out.println(x); } test();

However, I wish there was an option where this can be invoked naturally. My larger point is that, as much as the Java Kernel helps in executing Java statements, without all the bells and whistles of an IDE, it becomes challenging to teach Java to beginners, unless these nuances are vetted out, one way or the other. This is very similar to jshell.

One more update. This also works, but the error that is returned is "variable z1 is already defined in method do_it$()" { int z1 = 2; int z1 = 3; };

colathurv avatar Sep 11 '20 03:09 colathurv

Hi. This is because of how JShell, the Java REPL works. It has nothing to do with the notebook. Short story is that jshell splits the code in block instructions an it executes them as separate programs which shares the same memory and the same fabricated session class in order to give the user continuity between statements. The example within the block respects semantic because is a block in itself and compiled together. For example if you change the type of x for separate instructions it will not work. The reason being that at each declaration instruction will create a static variable and you would end up with same static var with different types. You can take a look here for other similar problems: https://arbitrary-but-fixed.net/teaching/java/jshell/2017/12/14/jshell-peculiarities.html

padreati avatar Sep 11 '20 11:09 padreati

Jshell is a managed REPL and as @padreati said, it works different than the java compiler, in Jshell java kernel the cell code is spited in statements and every statement is evaluated as a snippet, a snippet gets many things managed automatically like syntax errors and exceptions, in the case you brought snippets are overwritten in the jshell sate so, the int x = 3; snippet will replace the int x = 2; snippet, you need to add logic to the evaluation loop in the java kernel to track snippets and check their status to find whether or not a snippet has been overwritten by another and reject that changes and throw an exception and show it on client side

Source : jdk.jshell Source : jdk.jshell snippet usage

3xau1o avatar Sep 15 '20 16:09 3xau1o