SpencerPark / IJava

A Jupyter kernel for executing Java code.
MIT License
1.07k stars 211 forks source link

how to use %classpath magic correctly? #154

Open david-romano opened 5 months ago

david-romano commented 5 months ago

For context, I use this code:

%%sh
# Install java kernel
wget -q https://github.com/SpencerPark/IJava/releases/download/v1.3.0/ijava-1.3.0.zip
unzip -q ijava-1.3.0.zip
python install.py

# Install proxy for the java kernel
wget -qO- https://gist.github.com/SpencerPark/e2732061ad19c1afa4a33a58cb8f18a9/archive/b6cff2bf09b6832344e576ea1e4731f0fb3df10c.tar.gz | tar xvz --strip-components=1
python install_ipc_proxy_kernel.py --kernel=java --implementation=ipc_proxy_kernel.py

(from this gist) to load IJava as the kernel in a Google Colab notebook, but no matter what I do, the classpath is always

/usr/local/share/jupyter/kernels/java_tcp/ijava-1.3.0.jar

Here's a Google Colab gist that shows how I'm using %classpath and how the classpath isn't updated afterwards.

Am I using the magic incorrectly? I was hoping to be able import my own classes to use in a Google Colab notebook, but I can't get IJava to recognize them.

Thanks for any help!

SpencerPark commented 5 months ago

You're using the magic correctly (%classpath <path>).

The system property (System.getProperty("java.class.path")) isn't updated because that is the app classpath for the kernel itself but the managed JShell's classpath is still updated. When you run code in a cell it is compiled and run with a different classpath set through the various magic commands.

If you are distributing class files (rather than a jar) then they should be in folders matching their package structure and the root path added with %classpath.

e.g. with a class called HelloWorld in package com.example; located at /content/sample_data/com/example/HelloWorld.class, then you can use it with the following:

%classpath /content/sample_data
import com.example.HelloWorld;
System.out.println(HelloWorld.class);
david-romano commented 5 months ago

The system property (System.getProperty("java.class.path")) isn't updated because that is the app classpath for the kernel itself but the managed JShell's classpath is still updated. When you run code in a cell it is compiled and run with a different classpath set through the various magic commands.

Thanks for clearing that up! I'm guessing a distinction similar to the kernel/JShell one is why the output of HelloWorld doesn't appear as cell output for a cell whose code is:

Runtime.getRuntime().exec("java /content/sample_data/com/example/HelloWorld");

but that's outside the subject of the current thread, so I'll try to raise the question separately. Thanks again for the help!