Question: All of my notebooks stopped connecting, after the initial IJava installation and browser page refresh. What used to work  Execute this first cell  !wget https://github.com/SpencerPark/IJava/releases/download/v1.3.0/ijava-1.3.0.zip !unzip ijava-1.3.0.zip !python install.py --sys-prefix   Wait for the Installed java kernel message  Refresh the browser page.  Execute any cell with Java code.   Now what happens is I can execute the first cell and get the Installed java kernel message, seeing the notebook status as "Connected". But after refreshing the page, the status of the notebook is stuck at "Connecting" forever, and thus no cells can be executed. -- I'm using Google Colab for free, but since the initial installation still works, and the notebook status is "Connected" before the page is refreshed, this should not be the problem. Any idea what has been changed, and how I can get my Java notebooks to connect again? -- UPDATE 1 After the page reloads, when I try to run a cell containing Java code, this is the error message I'm getting after a while: await connected: disconnected @https://ssl.gstatic.com/colaboratory-static/common/5f9fa09db4e185842380071022f6c9a6/external_polymer_binary_l10n__en_gb.js:6249:377 promiseReactionJob@[native code]  Also, the notebook settings are Runtime type: java Hardware accelerator: None The cells contain really simple Java code, no external libraries, no CPU or GPU intensive stuff. For debugging purposes I tried running other cells (like the one with the Java installation, or Python code) - but of course, they also do not execute without connection. -- UPDATE 2 After installing IJava and before the page reload, I noticed that the path for the Java kernel is different than the path for the "preinstalled" ir and python3 kernels: !jupyter kernelspec list Available kernels: ir /usr/local/share/jupyter/kernels/ir python3 /usr/local/share/jupyter/kernels/python3 java /usr/share/jupyter/kernels/java  Could that be the problem? (I have never checked this before, so I don't know whether the default-path has been changed recently.) This is the metadata content of the ipynb file: { "nbformat": 4, "nbformat_minor": 0, "metadata": { "colab": { "provenance": [{ "file_id": "...", "timestamp": 1670411565504 }, { "file_id": "...", "timestamp": 1670311531999 }, { "file_id": "...", "timestamp": 1605675807586 }], "authorship_tag": "..." }, "kernelspec": { "name": "java", "display_name": "java" } }, "cells": [{ ... ]} } 

Answer: At some point colab changed the default transport to ipc (from the default tcp) which is not supported by IJava.  /usr/bin/python3 /usr/local/bin/jupyter-notebook --ip=... --transport=ipc --port=...  The kernel starts but never properly connects and doesn't send the initial kernel info message that jupyter is waiting for. When/if there comes a point where we can ask to start up with tcp transport instead, that will be preferable (see https://github.com/googlecolab/colabtools/issues/3267) but for the time being we can work around it. The workaround is to stick a little local proxy in front of the java kernel that connects all the ipc channels and forwards them to another set of tcp channels that are connected to the java kernel. The first cell is still the usual install/setup but also includes the install for the proxy as well: %%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  Run that cell. You may have Unrecognized runtime "java"; defaulting to "python3" which is ok. After the cell runs with output similar to: Installed java kernel into "/usr/local/share/jupyter/kernels/java" e2732061ad19c1afa4a33a58cb8f18a9-b6cff2bf09b6832344e576ea1e4731f0fb3df10c/install_ipc_proxy_kernel.py e2732061ad19c1afa4a33a58cb8f18a9-b6cff2bf09b6832344e576ea1e4731f0fb3df10c/ipc_proxy_kernel.py Moving java kernel from /usr/local/share/jupyter/kernels/java... Wrote modified kernel.json for java_tcp in /usr/local/share/jupyter/kernels/java_tcp/kernel.json Installing the proxy kernel in place of java in /usr/local/share/jupyter/kernels/java Installed proxy kernelspec: {"argv": ["/usr/bin/python3", "/usr/local/share/jupyter/kernels/java/ipc_proxy_kernel.py", "{connection_file}", "--kernel=java_tcp"], "env": {}, "display_name": "Java", "language": "java", "interrupt_mode": "message", "metadata": {}} Proxy kernel installed. Go to 'Runtime > Change runtime type' and select 'java' install.py:164: DeprecationWarning: replace is ignored. Installing a kernelspec always replaces an existing installation install_dest = KernelSpecManager().install_kernel_spec(  follow the printed instruction: Go to 'Runtime > Change runtime type' and select 'java'. The runtime should now show "Connected to java..." and you should be able to write and execute java code. Try https://colab.research.google.com/gist/SpencerPark/447de114fcd3e6a272dc140809462e30 for an example base notebook.  That setup cell should be everything you need to get running, but here is a bit of an explanation for what is in the proxy kernel. It is published as a gist (https://gist.github.com/SpencerPark/e2732061ad19c1afa4a33a58cb8f18a9). The general idea is:  rename the real kernel with the _tcp suffix (java_tcp) and install the proxy in it's place with the intended name (java).  start the proxy kernel and bind everything as if the proxy is a kernel itself. shell_socket = create_and_bind_socket(shell_port, zmq.ROUTER) stdin_socket = create_and_bind_socket(stdin_port, zmq.ROUTER) control_socket = create_and_bind_socket(control_port, zmq.ROUTER) iopub_socket = create_and_bind_socket(iopub_port, zmq.PUB) hb_socket = create_and_bind_socket(hb_port, zmq.REP)   start the real kernel with supported params (transport "tcp") and the same session information. This is important so we can forward messages directly to the real kernel without decoding them in between. kernel_manager = KernelManager() kernel_manager.kernel_name = args.kernel kernel_manager.transport = "tcp" kernel_manager.client_factory = ProxyKernelClient kernel_manager.autorestart = False kernel_manager.session.signature_scheme = signature_scheme kernel_manager.session.key = key kernel_manager.start_kernel()   start a zmq proxy for each pair of channels (this all the ProxyKernelClient does). Thread(target=zmq.proxy, args=(proxy_server_socket, self.kernel_client_socket)).start()   then we are done! Just wait for the managed kernel process to exit, and then exit ourselves as well. exit_code = kernel_manager.kernel.wait() kernel_client.stop_channels() zmq_context.destroy(0) exit(exit_code)