tho*_*ers 5 python java jupyter jupyter-notebook google-colaboratory
在初始 IJava 安装和浏览器页面刷新后,我的所有笔记本都停止连接。
以前做什么工作
!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
Run Code Online (Sandbox Code Playgroud)
等待Installed java kernel消息
刷新浏览器页面。
使用 Java 代码执行任何单元。
现在发生的是
我可以执行第一个单元格并获取消息Installed java kernel,看到笔记本状态为“已连接”。
但刷新页面后,笔记本的状态永远停留在“正在连接”,
因此没有单元格可以被执行。
--
我免费使用 Google Colab,但由于初始安装仍然有效,并且刷新页面之前笔记本状态为“已连接”,因此这应该不是问题。
知道发生了什么变化,以及如何让我的 Java 笔记本再次连接吗?
--
更新1
页面重新加载后,当我尝试运行包含 Java 代码的单元格时,这是我在一段时间后收到的错误消息:
await connected: disconnected
@https://ssl.gstatic.com/colaboratory-static/common/5f9fa09db4e185842380071022f6c9a6/external_polymer_binary_l10n__en_gb.js:6249:377
promiseReactionJob@[native code]
Run Code Online (Sandbox Code Playgroud)
另外,笔记本设置是
运行时类型:java
硬件加速器:None
这些单元包含非常简单的 Java 代码,没有外部库,没有 CPU 或 GPU 密集型内容。
出于调试目的,我尝试运行其他单元(例如安装 Java 或 Python 代码的单元),但当然,它们在没有连接的情况下也不会执行。
--
更新2
安装 IJava 后和页面重新加载之前,我注意到 Java 内核的路径与“预安装”ir 和 python3 内核的路径不同:
!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
Run Code Online (Sandbox Code Playgroud)
这可能是问题所在吗?
(我以前从未检查过这一点,所以我不知道最近默认路径是否已更改。)
这是 ipynb 文件的元数据内容:
{
"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": [{
...
]}
}
Run Code Online (Sandbox Code Playgroud)
在某些时候,colab 将默认传输更改为ipc(从默认tcp),这是 IJava 不支持的。
/usr/bin/python3 /usr/local/bin/jupyter-notebook --ip=... --transport=ipc --port=...
内核启动但从未正确连接,并且不发送 jupyter 正在等待的初始内核信息消息。
当/如果到了某个时刻我们可以要求开始使用tcp传输时,那会更好(请参阅https://github.com/googlecolab/colabtools/issues/3267),但目前我们可以解决这个问题。
解决方法是在 java 内核前面放置一个小的本地代理,该代理连接所有 ipc 通道并将它们转发到另一组连接到 java 内核的 tcp 通道。
第一个单元仍然是通常的安装/设置,但也包括代理的安装:
%%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 Code Online (Sandbox Code Playgroud)
运行该单元格。你可能有Unrecognized runtime "java"; defaulting to "python3",这没关系。单元运行后输出类似于:
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(
Run Code Online (Sandbox Code Playgroud)
请按照打印的说明进行操作:Go to 'Runtime > Change runtime type' and select 'java'. 运行时现在应该显示“Connected to java...”并且您应该能够编写和执行 java 代码。
尝试https://colab.research.google.com/gist/SpencerPark/447de114fcd3e6a272dc140809462e30作为示例基本笔记本。
该设置单元应该是您运行所需的一切,但这里对代理内核中的内容进行了一些解释。它作为要点发布(https://gist.github.com/SpencerPark/e2732061ad19c1afa4a33a58cb8f18a9)。总体思路是:
_tcp使用后缀 ( )重命名真实内核java_tcp,并使用预期名称 ( ) 在其位置安装代理java。
启动代理内核并绑定所有内容,就像代理本身就是内核一样。
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(
Run Code Online (Sandbox Code Playgroud)
"tcp"使用支持的参数(传输)和相同的会话信息启动真正的内核。这很重要,因此我们可以将消息直接转发到真正的内核,而无需在中间对它们进行解码。
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)
Run Code Online (Sandbox Code Playgroud)
为每对通道启动一个 zmq 代理(这就是所有的ProxyKernelClient作用)。
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()
Run Code Online (Sandbox Code Playgroud)
然后我们就完成了!只需等待托管内核进程退出,然后我们自己也退出。
Thread(target=zmq.proxy, args=(proxy_server_socket, self.kernel_client_socket)).start()
Run Code Online (Sandbox Code Playgroud)