0.背景
继基于插件做到代码部分语义可视化、以及反向控制IDE浏览代码跳转之后,我想尝试进一步获得IDE的控制权,来完成其他想法中的数据收集和增强自动化办公的程度,小小的推进一下IaC的进程,顺带着给AI自动化控制IDE开启一个新的道路,给AI“看”和“动”的基础能力。
这个想法启发于黄老师在Archguard中使用的createRepl方法,可以在自己的应用程序中内嵌一个jupyter的后端来完成自定义DSL的REPL(参考 https://github.com/archguard/archguard/blob/master/architecture-as-code/repl-api/src/main/kotlin/org/archguard/aaac/repl/compiler/KotlinReplWrapper.kt )。要是模仿他的方法在插件中启动一个embedded-jupyter-repl后端,能否通过repl来越过jupyter来执行插件中的方法呢?
1.需求分析
实际上IDEA本身也是一个java进程,有着自己的JVM和类加载器,其实相同的功能还在官方的IDE Scripting Console中有所体现、还有名为liveplugin的IDEAplugin,都可以做到动态在已经运行了的IDE的JVM进程中执行额外的代码
众所周知Java的运行是需要先编译成字节码再加载到JVM中的,那么也就意味着如果没有字节码增强和动态类加载技术,仅凭借正常的Java反射是很难做到的。理论上大部分程序在启动之后其行为就已经固化,不太可能轻易的通过外部进行干预。因此jupyter-repl在正常情况下是没法控制它的父进程的才对。但createRepl方法中的embed参数又让我起了怀疑,特此继续调研之前设想的IDE中REPL的可行性。
实现这个功能的思路上大致可以分为暴力穷举方案、RPC方案、字节码增强&动态类加载方案、移花接木方案
暴力穷举:人工或通过某种形式提取IDEA目前已知所有公开的API,生成delegate代码写入一个插件中,通过RPC等形式暴露给外部使用,这个方法难度最低但工作量最大,并且随着IDEA自身的升级需要持续维护
RPC方案:相比暴力穷举做一层抽象,使用反射进行动态调用再暴露结果给外部,这个方案难度比前一个高,工作量少了很多。潜在的坑是数据类型不太好处理,容易出运行时的问题
字节码增强&动态类加载方案:使用asm等字节码增强技术实时修改JVM运行时的字节码来达到,这个方案难度继续提高,工作量相比前一个差不多。潜在的坑是字节码增强技术配合任意代码使用,不异于重写一个编译器,可能会重新发明一次JShell和部分的javac。
因为我这么懒必然不会优先考虑前面的,因此一直在关注有什么已经做的差不多的功能,稍加拼接就能复用的方案。
移花接木方案1:因为按之前的思路是想继续使用Java的生态直接复用,特意看了下java在9之后出的JShell,理论上这个能作为一个后端使用,让这个后端和已有的JVM共享类加载器,麻烦的是需要自己解决类加载器的问题
移花接木方案2:IDE自带的部分功能和历史上有人实现的插件做到了类似的能力,参考他们的原理和代码稍加修改也许能和jupyter结合起来。
2.前端方案
3.执行引擎方案
3.1.embedded kotlin compiler //demo测试成功
实际的依赖是kotlin-scripting-compiler-embeddable
可以从源码看到IDEA主平台只声明了接口,由各自的插件自行实现Factory接口,根据追踪可以看到名为KotlinJsr223StandardScriptEngineFactory4Idea的类,这里已经处理好了IDEA主JVM的类加载器,因此模仿IDEA的核心代码调用即可。
官方的功能相对比较简单且不是核心功能,只能选取部分代码传给script engine执行动作。因和不同的实现相关,控制台并不都会显示输出。因此相关的资料也及其稀少,通过阅读大量源码和官方的bug反馈,对比git log、release note等方式才能找到一点有用的信息作为参考,另外还需要防备官方后续废弃这个功能。
测试脚本
0 1 2 3 4 5 |
import com.intellij.openapi.ui.Messages.showInfoMessage var sum: Long = 0L val arr = "35907 77134 453661 175096 23673 29350".split(" ") arr.forEach { sum+=it.length } showInfoMessage((sum.toFloat() / arr.size).toString(), "test") |
环境测试
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
//not ok import Messages Class failed IntelliJ IDEA 2022.1.4 (Community Edition) Build #IC-221.6008.13, built on July 19, 2022 Runtime version: 11.0.15+10-b2043.56 amd64 VM: OpenJDK 64-Bit Server VM by JetBrains s.r.o. Windows 10 10.0 GC: G1 Young Generation, G1 Old Generation Memory: 750M Cores: 16 Non-Bundled Plugins: cn.hylstudio.skykoma.plugin.idea (0.0.7) Kotlin: 221-1.6.21-release-337-IJ6008.13 Kotlin: 221-1.8.10-release-430-IJ5591.52 //ok succ IntelliJ IDEA 2022.3.2 (Community Edition) Build #IC-223.8617.56, built on January 26, 2023 Runtime version: 17.0.5+1-b653.25 amd64 VM: OpenJDK 64-Bit Server VM by JetBrains s.r.o. Windows 10 10.0 GC: G1 Young Generation, G1 Old Generation Memory: 750M Cores: 16 Non-Bundled Plugins: cn.hylstudio.skykoma.plugin.idea (0.0.7) Kotlin: 223-1.8.0-release-345-IJ8617.56 //not ok Kotlin: Cannot access java.io.Serializable’ which is a supertype of ‘kotlin.Int’ IntelliJ IDEA 2023.1.1 (Community Edition) Build #IC-231.8770.65, built on April 27, 2023 Runtime version: 17.0.6+10-b829.9 amd64 VM: OpenJDK 64-Bit Server VM by JetBrains s.r.o. Windows 10.0 GC: G1 Young Generation, G1 Old Generation Memory: 750M Cores: 16 Non-Bundled Plugins: cn.hylstudio.skykoma.plugin.idea (0.0.7) Kotlin: 231-1.8.21-IJ8770.65 |
3.2.kotlin-repl //待详细调研
0 1 2 3 4 5 6 7 8 9 10 11 |
D:\lib\jdk-17\bin\java.exe -Dkotlin.repl.ideMode=true -Dfile.encoding=UTF-8 @C:\Users\hyl\AppData\Local\Temp\idea_arg_file1818181911 idea_arg_file1818181911文件内容如下 -classpath D:\Program" "Files\JetBrains\IntelliJ" "IDEA" "Community" "Edition" "2023.1.1\plugins\Kotlin\kotlinc\lib\kotlin-compiler.jar;D:\Program" "Files\JetBrains\IntelliJ" "IDEA" "Community" "Edition" "2023.1.1\plugins\Kotlin\kotlinc\lib\kotlin-stdlib.jar;D:\Program" "Files\JetBrains\IntelliJ" "IDEA" "Community" "Edition" "2023.1.1\plugins\Kotlin\kotlinc\lib\kotlin-reflect.jar;D:\Program" "Files\JetBrains\IntelliJ" "IDEA" "Community" "Edition" "2023.1.1\plugins\Kotlin\kotlinc\lib\kotlin-script-runtime.jar;D:\Program" "Files\JetBrains\IntelliJ" "IDEA" "Community" "Edition" "2023.1.1\plugins\Kotlin\kotlinc\lib\trove4j.jar;D:\Program" "Files\JetBrains\IntelliJ" "IDEA" "Community" "Edition" "2023.1.1\plugins\Kotlin\kotlinc\lib\kotlin-daemon.jar;D:\Program" "Files\JetBrains\IntelliJ" "IDEA" "Community" "Edition" "2023.1.1\plugins\Kotlin\kotlinc\lib\kotlin-scripting-compiler.jar;D:\Program" "Files\JetBrains\IntelliJ" "IDEA" "Community" "Edition" "2023.1.1\plugins\Kotlin\kotlinc\lib\kotlin-scripting-compiler-impl.jar;D:\Program" "Files\JetBrains\IntelliJ" "IDEA" "Community" "Edition" "2023.1.1\plugins\Kotlin\kotlinc\lib\kotlin-scripting-common.jar;D:\Program" "Files\JetBrains\IntelliJ" "IDEA" "Community" "Edition" "2023.1.1\plugins\Kotlin\kotlinc\lib\kotlin-scripting-jvm.jar;D:\Program" "Files\JetBrains\IntelliJ" "IDEA" "Community" "Edition" "2023.1.1\plugins\Kotlin\kotlinc\lib\annotations-13.0.jar org.jetbrains.kotlin.cli.jvm.K2JVMCompiler -cp D:\code\skykoma-plugin-idea\out\production\classes;D:\code\skykoma-plugin-idea\out\production\resources;D:\code\skykoma-plugin-idea\out\production\classes;D:\code\skykoma-plugin-idea\out\production\resources;C:\Users\hyl\.gradle\caches\modules-2\files-2.1\org.jetbrains.kotlinx\kotlin-jupyter-kernel\0.11.0-358\c27456274ae614e163a0d2b788b2c12c66ab8764\kotlin-jupyter-kernel-0.11.0-358.jar;C:\Users\hyl\.gradle\caches\modules-2\files-2.1\org.jetbrains.kotlinx\kotlin-jupyter-api\0.11.0-358\4270be15730d6628a8d3ff9c849e63c71060614b\kotlin-jupyter-api-0.11.0-358.jar;C:\Users\hyl\.gradle\caches\modules-2\files-2.1\com.squareup.okhttp3\okhttp\4.10.0\cd63657ac15770ed1420647154c9f44645533bef\okhttp-4.10.0.jar;C:\Users\hyl\.gradle\caches\modules-2\files-2.1\org.jetbrains.kotlin\kotlin-stdlib-jdk8\1.8.21\67f57e154437cd9e6e9cf368394b95814836ff88\kotlin-stdlib-jdk8-1.8.21.jar;C:\Users\hyl\.gradle\caches\modules-2\files-2.1\org.projectlombok\lombok\1.18.22\9c08ea24c6eb714e2d6170e8122c069a0ba9aacf\lombok-1.18.22.jar;C:\Users\hyl\.gradle\caches\modules-2\files-2.1\org.jetbrains.kotlin\kotlin-scripting-jvm\1.6.21\ab52f6af29c00a8a9c89ea2b34b5f4d27960bd3f\kotlin-scripting-jvm-1.6.21.jar;C:\Users\hyl\.gradle\caches\modules-2\files-2.1\org.jetbrains\annotations\24.0.0\69b8b443c437fdeefa8d20c18d257b94836a92b9\annotations-24.0.0.jar;C:\Users\hyl\.gradle\caches\modules-2\files-2.1\com.jetbrains.intellij.idea\ideaIC\2022.1.4\e3ffd300c9b86b78a24cd23fdc358ac8493afdf5\ideaIC-2022.1.4\plugins\java\lib\aether-dependency-resolver.jar;C:\Users\hyl\.gradle\caches\modules-2\files-2.1\com.jetbrains.intellij.idea\ideaIC\2022.1.4\e3ffd300c9b86b78a24cd23fdc358ac8493afdf5\ideaIC-2022.1.4\plugins\java\lib\debugger-memory-agent.jar;C:\Users\hyl\.gradle\caches\modules-2\files-2.1\com.jetbrains.intellij.idea\ideaIC\2022.1.4\e3ffd300c9b86b78a24cd23fdc358ac8493afdf5\ideaIC-2022.1.4\plugins\java\lib\java-impl.jar;C:\Users\hyl\.gradle\caches\modules-2\files-2.1\com.jetbrains.intellij.idea\ideaIC\2022.1.4\e3ffd300c9b86b78a24cd23fdc358ac8493afdf5\ideaIC-2022.1.4\plugins\java\lib\javac2.jar;C:\Users\hyl\.gradle\caches\modules-2\files-2.1\com.jetbrains.intellij.idea\ideaIC\2022.1.4\e3ffd300c9b86b78a24cd23fdc358ac8493afdf5\ideaIC-2022.1.4\plugins\java\lib\jb-jdi.jar;C:\Users\hyl\.gradle\caches\modules-2\files-2.1\com.jetbrains.intellij.idea\ideaIC\2022.1.4\e3ffd300c9b86b78a24cd23fdc358ac8493afdf5\ideaIC-2022.1.4\plugins\java\lib\jgoodies-common.jar;C:\Users\hyl\.gradle\caches\modules-2\files-2.1\com.jetbrains.intellij.idea\ideaIC\2022.1.4\e3ffd300c9b86b78a24cd23fdc358ac8493afdf5\ideaIC-2022.1.4\plugins\java\lib\jps-builders.jar;C:\Users\hyl\.gradle\caches\modules-2\files-2.1\com.jetbrains.intellij.idea\ideaIC\2022.1.4\e3ffd300c9b86b78a24cd23fdc358ac8493afdf5\ideaIC-2022.1.4\plugins\java\lib\jps-builders-6.jar;C:\Users\hyl\.gradle\caches\modules-2\files-2.1\com.jetbrains.intellij.idea\ideaIC\2022.1.4\e3ffd300c9b86b78a24cd23fdc358ac8493afdf5\ideaIC-2022.1.4\plugins\java\lib\jps-javac-extension.jar;C:\Users\hyl\.gradle\caches\modules-2\files-2.1\com.jetbrains.intellij.idea\ideaIC\2022.1.4\e3ffd300c9b86b78a24cd23fdc358ac8493afdf5\ideaIC-2022.1.4\plugins\java\lib\jps-launcher.jar;C:\Users\hyl\.gradle\caches\modules-2\files-2.1\com.jetbrains.intellij.idea\ideaIC\2022.1.4\e3ffd300c9b86b78a24cd23fdc358ac8493afdf5\ideaIC-2022.1.4\plugins\java\lib\jshell-frontend.jar;C:\Users\hyl\.gradle\caches\modules-2\files-2.1\com.jetbrains.intellij.idea\ideaIC\2022.1.4\e3ffd300c9b86b78a24cd23fdc358ac8493afdf5\ideaIC-2022.1.4\plugins\java\lib\jshell-protocol.jar;C:\Users\hyl\.gradle\caches\modules-2\files-2.1\com.jetbrains.intellij.idea\ideaIC\2022.1.4\e3ffd300c9b86b78a24cd23fdc358ac8493afdf5\ideaIC-2022.1.4\plugins\java\lib\sa-jdwp.jar;C:\Users\hyl\.gradle\caches\modules-2\files-2.1\com.jetbrains.intellij.idea\ideaIC\2022.1.4\e3ffd300c9b86b78a24cd23fdc358ac8493afdf5\ideaIC-2022.1.4\lib\3rd-party-rt.jar;C:\Users\hyl\.gradle\caches\modules-2\files-2.1\com.jetbrains.intellij.idea\ideaIC\2022.1.4\e3ffd300c9b86b78a24cd23fdc358ac8493afdf5\ideaIC-2022.1.4\lib\ant\lib\ant.jar;C:\Users\hyl\.gradle\caches\modules-2\files-2.1\com.jetbrains.intellij.idea\ideaIC\2022.1.4\e3ffd300c9b86b78a24cd23fdc358ac8493afdf5\ideaIC-2022.1.4\lib\app.jar;C:\Users\hyl\.gradle\caches\modules-2\files-2.1\com.jetbrains.intellij.idea\ideaIC\2022.1.4\e3ffd300c9b86b78a24cd23fdc358ac8493afdf5\ideaIC-2022.1.4\lib\asm-7.1.jar;C:\Users\hyl\.gradle\caches\modules-2\files-2.1\com.jetbrains.intellij.idea\ideaIC\2022.1.4\e3ffd300c9b86b78a24cd23fdc358ac8493afdf5\ideaIC-2022.1.4\lib\asm-analysis-7.1.jar;C:\Users\hyl\.gradle\caches\modules-2\files-2.1\com.jetbrains.intellij.idea\ideaIC\2022.1.4\e3ffd300c9b86b78a24cd23fdc358ac8493afdf5\ideaIC-2022.1.4\lib\asm-commons-7.1.jar;C:\Users\hyl\.gradle\caches\modules-2\files-2.1\com.jetbrains.intellij.idea\ideaIC\2022.1.4\e3ffd300c9b86b78a24cd23fdc358ac8493afdf5\ideaIC-2022.1.4\lib\asm-tree-7.1.jar;C:\Users\hyl\.gradle\caches\modules-2\files-2.1\com.jetbrains.intellij.idea\ideaIC\2022.1.4\e3ffd300c9b86b78a24cd23fdc358ac8493afdf5\ideaIC-2022.1.4\lib\asm-util-7.1.jar;C:\Users\hyl\.gradle\caches\modules-2\files-2.1\com.jetbrains.intellij.idea\ideaIC\2022.1.4\e3ffd300c9b86b78a24cd23fdc358ac8493afdf5\ideaIC-2022.1.4\lib\byte-buddy-agent.jar;C:\Users\hyl\.gradle\caches\modules-2\files-2.1\com.jetbrains.intellij.idea\ideaIC\2022.1.4\e3ffd300c9b86b78a24cd23fdc358ac8493afdf5\ideaIC-2022.1.4\lib\dbus-java-3.2.1.jar;C:\Users\hyl\.gradle\caches\modules-2\files-2.1\com.jetbrains.intellij.idea\ideaIC\2022.1.4\e3ffd300c9b86b78a24cd23fdc358ac8493afdf5\ideaIC-2022.1.4\lib\dom-impl.jar;C:\Users\hyl\.gradle\caches\modules-2\files-2.1\com.jetbrains.intellij.idea\ideaIC\2022.1.4\e3ffd300c9b86b78a24cd23fdc358ac8493afdf5\ideaIC-2022.1.4\lib\dom-openapi.jar;C:\Users\hyl\.gradle\caches\modules-2\files-2.1\com.jetbrains.intellij.idea\ideaIC\2022.1.4\e3ffd300c9b86b78a24cd23fdc358ac8493afdf5\ideaIC-2022.1.4\lib\duplicates-analysis.jar;C:\Users\hyl\.gradle\caches\modules-2\files-2.1\com.jetbrains.intellij.idea\ideaIC\2022.1.4\e3ffd300c9b86b78a24cd23fdc358ac8493afdf5\ideaIC-2022.1.4\lib\error-prone-annotations.jar;C:\Users\hyl\.gradle\caches\modules-2\files-2.1\com.jetbrains.intellij.idea\ideaIC\2022.1.4\e3ffd300c9b86b78a24cd23fdc358ac8493afdf5\ideaIC-2022.1.4\lib\external-system-rt.jar;C:\Users\hyl\.gradle\caches\modules-2\files-2.1\com.jetbrains.intellij.idea\ideaIC\2022.1.4\e3ffd300c9b86b78a24cd23fdc358ac8493afdf5\ideaIC-2022.1.4\lib\externalProcess-rt.jar;C:\Users\hyl\.gradle\caches\modules-2\files-2.1\com.jetbrains.intellij.idea\ideaIC\2022.1.4\e3ffd300c9b86b78a24cd23fdc358ac8493afdf5\ideaIC-2022.1.4\lib\forms_rt.jar;C:\Users\hyl\.gradle\caches\modules-2\files-2.1\com.jetbrains.intellij.idea\ideaIC\2022.1.4\e3ffd300c9b86b78a24cd23fdc358ac8493afdf5\ideaIC-2022.1.4\lib\groovy.jar;C:\Users\hyl\.gradle\caches\modules-2\files-2.1\com.jetbrains.intellij.idea\ideaIC\2022.1.4\e3ffd300c9b86b78a24cd23fdc358ac8493afdf5\ideaIC-2022.1.4\lib\grpc-netty-shaded.jar;C:\Users\hyl\.gradle\caches\modules-2\files-2.1\com.jetbrains.intellij.idea\ideaIC\2022.1.4\e3ffd300c9b86b78a24cd23fdc358ac8493afdf5\ideaIC-2022.1.4\lib\idea_rt.jar;C:\Users\hyl\.gradle\caches\modules-2\files-2.1\com.jetbrains.intellij.idea\ideaIC\2022.1.4\e3ffd300c9b86b78a24cd23fdc358ac8493afdf5\ideaIC-2022.1.4\lib\intellij-coverage-agent-1.0.656.jar;C:\Users\hyl\.gradle\caches\modules-2\files-2.1\com.jetbrains.intellij.idea\ideaIC\2022.1.4\e3ffd300c9b86b78a24cd23fdc358ac8493afdf5\ideaIC-2022.1.4\lib\intellij-test-discovery.jar;C:\Users\hyl\.gradle\caches\modules-2\files-2.1\com.jetbrains.intellij.idea\ideaIC\2022.1.4\e3ffd300c9b86b78a24cd23fdc358ac8493afdf5\ideaIC-2022.1.4\lib\java-utils-1.0.6.jar;C:\Users\hyl\.gradle\caches\modules-2\files-2.1\com.jetbrains.intellij.idea\ideaIC\2022.1.4\e3ffd300c9b86b78a24cd23fdc358ac8493afdf5\ideaIC-2022.1.4\lib\jffi-1.2.19.jar;C:\Users\hyl\.gradle\caches\modules-2\files-2.1\com.jetbrains.intellij.idea\ideaIC\2022.1.4\e3ffd300c9b86b78a24cd23fdc358ac8493afdf5\ideaIC-2022.1.4\lib\jffi-1.2.19-native.jar;C:\Users\hyl\.gradle\caches\modules-2\files-2.1\com.jetbrains.intellij.idea\ideaIC\2022.1.4\e3ffd300c9b86b78a24cd23fdc358ac8493afdf5\ideaIC-2022.1.4\lib\jna.jar;C:\Users\hyl\.gradle\caches\modules-2\files-2.1\com.jetbrains.intellij.idea\ideaIC\2022.1.4\e3ffd300c9b86b78a24cd23fdc358ac8493afdf5\ideaIC-2022.1.4\lib\jnr-a64asm-1.0.0.jar;C:\Users\hyl\.gradle\caches\modules-2\files-2.1\com.jetbrains.intellij.idea\ideaIC\2022.1.4\e3ffd300c9b86b78a24cd23fdc358ac8493afdf5\ideaIC-2022.1.4\lib\jnr-constants-0.9.12.jar;C:\Users\hyl\.gradle\caches\modules-2\files-2.1\com.jetbrains.intellij.idea\ideaIC\2022.1.4\e3ffd300c9b86b78a24cd23fdc358ac8493afdf5\ideaIC-2022.1.4\lib\jnr-enxio-0.21.jar;C:\Users\hyl\.gradle\caches\modules-2\files-2.1\com.jetbrains.intellij.idea\ideaIC\2022.1.4\e3ffd300c9b86b78a24cd23fdc358ac8493afdf5\ideaIC-2022.1.4\lib\jnr-ffi-2.1.10.jar;C:\Users\hyl\.gradle\caches\modules-2\files-2.1\com.jetbrains.intellij.idea\ideaIC\2022.1.4\e3ffd300c9b86b78a24cd23fdc358ac8493afdf5\ideaIC-2022.1.4\lib\jnr-posix-3.0.50.jar;C:\Users\hyl\.gradle\caches\modules-2\files-2.1\com.jetbrains.intellij.idea\ideaIC\2022.1.4\e3ffd300c9b86b78a24cd23fdc358ac8493afdf5\ideaIC-2022.1.4\lib\jnr-unixsocket-0.23.jar;C:\Users\hyl\.gradle\caches\modules-2\files-2.1\com.jetbrains.intellij.idea\ideaIC\2022.1.4\e3ffd300c9b86b78a24cd23fdc358ac8493afdf5\ideaIC-2022.1.4\lib\jnr-x86asm-1.0.2.jar;C:\Users\hyl\.gradle\caches\modules-2\files-2.1\com.jetbrains.intellij.idea\ideaIC\2022.1.4\e3ffd300c9b86b78a24cd23fdc358ac8493afdf5\ideaIC-2022.1.4\lib\jps-model.jar;C:\Users\hyl\.gradle\caches\modules-2\files-2.1\com.jetbrains.intellij.idea\ideaIC\2022.1.4\e3ffd300c9b86b78a24cd23fdc358ac8493afdf5\ideaIC-2022.1.4\lib\jsch-agent.jar;C:\Users\hyl\.gradle\caches\modules-2\files-2.1\com.jetbrains.intellij.idea\ideaIC\2022.1.4\e3ffd300c9b86b78a24cd23fdc358ac8493afdf5\ideaIC-2022.1.4\lib\jsp-base-openapi.jar;C:\Users\hyl\.gradle\caches\modules-2\files-2.1\com.jetbrains.intellij.idea\ideaIC\2022.1.4\e3ffd300c9b86b78a24cd23fdc358ac8493afdf5\ideaIC-2022.1.4\lib\junit4.jar;C:\Users\hyl\.gradle\caches\modules-2\files-2.1\com.jetbrains.intellij.idea\ideaIC\2022.1.4\e3ffd300c9b86b78a24cd23fdc358ac8493afdf5\ideaIC-2022.1.4\lib\junixsocket-core.jar;C:\Users\hyl\.gradle\caches\modules-2\files-2.1\com.jetbrains.intellij.idea\ideaIC\2022.1.4\e3ffd300c9b86b78a24cd23fdc358ac8493afdf5\ideaIC-2022.1.4\lib\lz4-java.jar;C:\Users\hyl\.gradle\caches\modules-2\files-2.1\com.jetbrains.intellij.idea\ideaIC\2022.1.4\e3ffd300c9b86b78a24cd23fdc358ac8493afdf5\ideaIC-2022.1.4\lib\platform-objectSerializer-annotations.jar;C:\Users\hyl\.gradle\caches\modules-2\files-2.1\com.jetbrains.intellij.idea\ideaIC\2022.1.4\e3ffd300c9b86b78a24cd23fdc358ac8493afdf5\ideaIC-2022.1.4\lib\platform-statistics-devkit.jar;C:\Users\hyl\.gradle\caches\modules-2\files-2.1\com.jetbrains.intellij.idea\ideaIC\2022.1.4\e3ffd300c9b86b78a24cd23fdc358ac8493afdf5\ideaIC-2022.1.4\lib\protobuf.jar;C:\Users\hyl\.gradle\caches\modules-2\files-2.1\com.jetbrains.intellij.idea\ideaIC\2022.1.4\e3ffd300c9b86b78a24cd23fdc358ac8493afdf5\ideaIC-2022.1.4\lib\pty4j.jar;C:\Users\hyl\.gradle\caches\modules-2\files-2.1\com.jetbrains.intellij.idea\ideaIC\2022.1.4\e3ffd300c9b86b78a24cd23fdc358ac8493afdf5\ideaIC-2022.1.4\lib\rd-core.jar;C:\Users\hyl\.gradle\caches\modules-2\files-2.1\com.jetbrains.intellij.idea\ideaIC\2022.1.4\e3ffd300c9b86b78a24cd23fdc358ac8493afdf5\ideaIC-2022.1.4\lib\rd-framework.jar;C:\Users\hyl\.gradle\caches\modules-2\files-2.1\com.jetbrains.intellij.idea\ideaIC\2022.1.4\e3ffd300c9b86b78a24cd23fdc358ac8493afdf5\ideaIC-2022.1.4\lib\rd-swing.jar;C:\Users\hyl\.gradle\caches\modules-2\files-2.1\com.jetbrains.intellij.idea\ideaIC\2022.1.4\e3ffd300c9b86b78a24cd23fdc358ac8493afdf5\ideaIC-2022.1.4\lib\rd-text.jar;C:\Users\hyl\.gradle\caches\modules-2\files-2.1\com.jetbrains.intellij.idea\ideaIC\2022.1.4\e3ffd300c9b86b78a24cd23fdc358ac8493afdf5\ideaIC-2022.1.4\lib\stats.jar;C:\Users\hyl\.gradle\caches\modules-2\files-2.1\com.jetbrains.intellij.idea\ideaIC\2022.1.4\e3ffd300c9b86b78a24cd23fdc358ac8493afdf5\ideaIC-2022.1.4\lib\structuralsearch.jar;C:\Users\hyl\.gradle\caches\modules-2\files-2.1\com.jetbrains.intellij.idea\ideaIC\2022.1.4\e3ffd300c9b86b78a24cd23fdc358ac8493afdf5\ideaIC-2022.1.4\lib\testFramework.jar;C:\Users\hyl\.gradle\caches\modules-2\files-2.1\com.jetbrains.intellij.idea\ideaIC\2022.1.4\e3ffd300c9b86b78a24cd23fdc358ac8493afdf5\ideaIC-2022.1.4\lib\tests_bootstrap.jar;C:\Users\hyl\.gradle\caches\modules-2\files-2.1\com.jetbrains.intellij.idea\ideaIC\2022.1.4\e3ffd300c9b86b78a24cd23fdc358ac8493afdf5\ideaIC-2022.1.4\lib\uast-tests.jar;C:\Users\hyl\.gradle\caches\modules-2\files-2.1\com.jetbrains.intellij.idea\ideaIC\2022.1.4\e3ffd300c9b86b78a24cd23fdc358ac8493afdf5\ideaIC-2022.1.4\lib\util.jar;C:\Users\hyl\.gradle\caches\modules-2\files-2.1\com.jetbrains.intellij.idea\ideaIC\2022.1.4\e3ffd300c9b86b78a24cd23fdc358ac8493afdf5\ideaIC-2022.1.4\lib\util_rt.jar;C:\Users\hyl\.gradle\caches\modules-2\files-2.1\com.jetbrains.intellij.idea\ideaIC\2022.1.4\e3ffd300c9b86b78a24cd23fdc358ac8493afdf5\ideaIC-2022.1.4\lib\winp.jar;C:\Users\hyl\.gradle\caches\modules-2\files-2.1\org.jetbrains.kotlinx\kotlin-jupyter-shared-compiler\0.11.0-358\4d6ce525bc9391fb404150fd08b10b715e3fe3d6\kotlin-jupyter-shared-compiler-0.11.0-358.jar;C:\Users\hyl\.gradle\caches\modules-2\files-2.1\org.jetbrains.kotlin\kotlin-stdlib\1.8.21\43d50ab85bc7587adfe3dda3dbe579e5f8d51265\kotlin-stdlib-1.8.21.jar;C:\Users\hyl\.gradle\caches\modules-2\files-2.1\org.jetbrains.kotlin\kotlin-stdlib-jdk7\1.8.21\7473b8cd3c0ef9932345baf569bc398e8a717046\kotlin-stdlib-jdk7-1.8.21.jar;C:\Users\hyl\.gradle\caches\modules-2\files-2.1\org.jetbrains.kotlin\kotlin-scripting-common\1.6.21\2e2e17b6e20c9c44f1d76d0df4f8f0b3fcfa944f\kotlin-scripting-common-1.6.21.jar;C:\Users\hyl\.gradle\caches\modules-2\files-2.1\org.jetbrains.kotlin\kotlin-script-runtime\1.6.21\99c6675100da5d6d5b1c5a1032f27f28008d101b\kotlin-script-runtime-1.6.21.jar;C:\Users\hyl\.gradle\caches\modules-2\files-2.1\org.jetbrains.kotlinx\kotlin-jupyter-lib\0.11.0-358\e4febcd07fe4d5df82d3adf39fa790597954d9ee\kotlin-jupyter-lib-0.11.0-358.jar;C:\Users\hyl\.gradle\caches\modules-2\files-2.1\org.jetbrains.kotlinx\kotlin-jupyter-common-dependencies\0.11.0-358\83e6eaab29bb455d885683c9a5bfdb3659f970fc\kotlin-jupyter-common-dependencies-0.11.0-358.jar;C:\Users\hyl\.gradle\caches\modules-2\files-2.1\org.zeromq\jeromq\0.5.3\c5db6965902a67fd248163e387d4b63fa160c373\jeromq-0.5.3.jar;C:\Users\hyl\.gradle\caches\modules-2\files-2.1\org.jetbrains.kotlinx\kotlinx-serialization-json-jvm\1.4.1\e6430b33f06dcdff88998abfcb2e78bc3cd0a1f6\kotlinx-serialization-json-jvm-1.4.1.jar;C:\Users\hyl\.gradle\caches\modules-2\files-2.1\com.squareup.okio\okio-jvm\3.0.0\ab5a73fa2ccb4a36b0b5c69fe10b16d0255bcf8\okio-jvm-3.0.0.jar;C:\Users\hyl\.gradle\caches\modules-2\files-2.1\org.jetbrains.kotlin\kotlin-stdlib-common\1.8.21\d749cd5ae25da36d06e5028785038e24f9d37976\kotlin-stdlib-common-1.8.21.jar;C:\Users\hyl\.gradle\caches\modules-2\files-2.1\eu.neilalexander\jnacl\1.0.0\82e9034fb81a33cb9d7e0c4cd241a2ba84802ae2\jnacl-1.0.0.jar;C:\Users\hyl\.gradle\caches\modules-2\files-2.1\org.jetbrains.kotlinx\kotlinx-serialization-core-jvm\1.4.1\e0c2c11e5d0d541ca343c8f09602c0c2287d15a1\kotlinx-serialization-core-jvm-1.4.1.jar;C:\Users\hyl\.gradle\caches\modules-2\files-2.1\org.jetbrains.kotlin\kotlin-script-util\1.8.20\bc32b0ff3eaefc692ae89b37bd0e4f9a7a1bf27f\kotlin-script-util-1.8.20.jar;C:\Users\hyl\.gradle\caches\modules-2\files-2.1\org.jetbrains.kotlin\kotlin-scripting-ide-services\1.8.20\39decbde982a59dd2f4c1d4c3b70a486924b723b\kotlin-scripting-ide-services-1.8.20.jar;C:\Users\hyl\.gradle\caches\modules-2\files-2.1\org.jetbrains.kotlin\kotlin-compiler-embeddable\1.8.20\78d9baa57f65babf9e0a93e51f62f26f5f35ac3e\kotlin-compiler-embeddable-1.8.20.jar;C:\Users\hyl\.gradle\caches\modules-2\files-2.1\org.jetbrains.kotlin\kotlin-reflect\1.8.20\ea6ffe3c1bb1229f4d9279ae51395c54e7132d53\kotlin-reflect-1.8.20.jar;C:\Users\hyl\.gradle\caches\modules-2\files-2.1\org.jetbrains.kotlin\kotlin-scripting-compiler-embeddable\1.8.20\3c8fdcb527dd400398ec8e2985c89dba4af8871e\kotlin-scripting-compiler-embeddable-1.8.20.jar;C:\Users\hyl\.gradle\caches\modules-2\files-2.1\org.jetbrains.kotlin\kotlin-scripting-compiler-impl-embeddable\1.8.20\3b1ec379939d04bc0e1264b695ed949bc5c9bea3\kotlin-scripting-compiler-impl-embeddable-1.8.20.jar;C:\Users\hyl\.gradle\caches\modules-2\files-2.1\org.jetbrains.kotlin\kotlin-scripting-common\1.8.20\f19996e3a40658541fe2108c483fd3301c4a3416\kotlin-scripting-common-1.8.20.jar;C:\Users\hyl\.gradle\caches\modules-2\files-2.1\com.github.ajalt\clikt\2.8.0\a182947a09b84370380970c8ba31902ae1d92b1e\clikt-jvm-2.8.0.jar;C:\Users\hyl\.gradle\caches\modules-2\files-2.1\org.jetbrains\annotations\23.1.0\d095a317cafe983999c7c8ad14da1a503288b55e\annotations-23.1.0.jar;C:\Users\hyl\.gradle\caches\modules-2\files-2.1\org.jetbrains.kotlin\kotlin-scripting-dependencies-maven-all\1.8.20\1ce4dd9745e94ea7623953841386e625e8921c53\kotlin-scripting-dependencies-maven-all-1.8.20.jar;C:\Users\hyl\.gradle\caches\modules-2\files-2.1\org.jetbrains.kotlin\kotlin-serialization\1.8.20\799da151f694e52358f1f862ab05c0380a9c7b0f\kotlin-serialization-1.8.20-gradle74.jar;C:\Users\hyl\.gradle\caches\modules-2\files-2.1\ch.qos.logback\logback-classic\1.3.6\4801f031c2a8e6f521853f143986899438f06d52\logback-classic-1.3.6.jar;C:\Users\hyl\.gradle\caches\modules-2\files-2.1\org.http4k\http4k-client-apache\4.34.3.0\f6a9f0053e8d21cfb6b91d31b7f7607173fb8cd\http4k-client-apache-4.34.3.0.jar;C:\Users\hyl\.gradle\caches\modules-2\files-2.1\org.slf4j\slf4j-api\2.0.5\3a759df277e854f7c4ca951e5899bcec0dbdca73\slf4j-api-2.0.5.jar;C:\Users\hyl\.gradle\caches\modules-2\files-2.1\org.http4k\http4k-core\4.34.3.0\e605fd4354a1d8da7e6114df5b24378ca648bb5a\http4k-core-4.34.3.0.jar;C:\Users\hyl\.gradle\caches\modules-2\files-2.1\org.jetbrains.kotlinx\kotlinx-coroutines-core-jvm\1.6.4\2c997cd1c0ef33f3e751d3831929aeff1390cb30\kotlinx-coroutines-core-jvm-1.6.4.jar;C:\Users\hyl\.gradle\caches\modules-2\files-2.1\org.jetbrains.kotlin\kotlin-daemon-client\1.8.20\b6f15c748f4c2f3aeb1735ce52400ed3c0eae09a\kotlin-daemon-client-1.8.20.jar;C:\Users\hyl\.gradle\caches\modules-2\files-2.1\org.jetbrains.kotlin\kotlin-scripting-jvm\1.8.20\51c8efbe177ebcaa89c82d01663c60060a120dd2\kotlin-scripting-jvm-1.8.20.jar;C:\Users\hyl\.gradle\caches\modules-2\files-2.1\org.jetbrains.kotlin\kotlin-script-runtime\1.8.20\c850771e723701f9d63dbcf641429c0f29290074\kotlin-script-runtime-1.8.20.jar;C:\Users\hyl\.gradle\caches\modules-2\files-2.1\org.jetbrains.intellij.deps\trove4j\1.0.20200330\3afb14d5f9ceb459d724e907a21145e8ff394f02\trove4j-1.0.20200330.jar;C:\Users\hyl\.gradle\caches\modules-2\files-2.1\org.jetbrains.kotlin\kotlin-daemon-embeddable\1.8.20\c1b808fbe5fee60bd0504a54778120ef40f383d4\kotlin-daemon-embeddable-1.8.20.jar;C:\Users\hyl\.gradle\caches\modules-2\files-2.1\net.java.dev.jna\jna\5.6.0\330f2244e9030119ab3030fc3fededc86713d9cc\jna-5.6.0.jar;C:\Users\hyl\.gradle\caches\modules-2\files-2.1\org.jetbrains.kotlin\kotlin-gradle-plugin-api\1.8.20\1d909998b74b7873ac71bd04ce5f145f3d68bcfd\kotlin-gradle-plugin-api-1.8.20-gradle74.jar;C:\Users\hyl\.gradle\caches\modules-2\files-2.1\ch.qos.logback\logback-core\1.3.6\5ec1805120ceafa51086b7b0448793f0fe256f0f\logback-core-1.3.6.jar;C:\Users\hyl\.gradle\caches\modules-2\files-2.1\org.apache.httpcomponents.client5\httpclient5\5.2.1\c900514d3446d9ce5d9dbd90c21192048125440\httpclient5-5.2.1.jar;C:\Users\hyl\.gradle\caches\modules-2\files-2.1\org.jetbrains.kotlin\kotlin-gradle-plugin-annotations\1.8.20\e4254b95d5b4abe86ba97afb6214877f9fc76a05\kotlin-gradle-plugin-annotations-1.8.20.jar;C:\Users\hyl\.gradle\caches\modules-2\files-2.1\org.jetbrains.kotlin\kotlin-native-utils\1.8.20\d490644e215629f7f23f1c9ba5eb8bf96f4b8504\kotlin-native-utils-1.8.20.jar;C:\Users\hyl\.gradle\caches\modules-2\files-2.1\org.jetbrains.kotlin\kotlin-project-model\1.8.20\1c22ceafd66b8e1dcd9e9c662a1bbb276528d4c7\kotlin-project-model-1.8.20.jar;C:\Users\hyl\.gradle\caches\modules-2\files-2.1\org.jetbrains.kotlin\kotlin-tooling-core\1.8.20\6ab3d6c8e8d13c2748ecf0b74978fbd191def027\kotlin-tooling-core-1.8.20.jar;C:\Users\hyl\.gradle\caches\modules-2\files-2.1\org.apache.httpcomponents.core5\httpcore5-h2\5.2\698bd8c759ccc7fd7398f3179ff45d0e5a7ccc16\httpcore5-h2-5.2.jar;C:\Users\hyl\.gradle\caches\modules-2\files-2.1\org.apache.httpcomponents.core5\httpcore5\5.2\ab7d251b8dfa3f2878f1eefbcca0e1fc0ebeba27\httpcore5-5.2.jar;C:\Users\hyl\.gradle\caches\modules-2\files-2.1\org.jetbrains.kotlin\kotlin-util-io\1.8.20\845b590111343b11034db2a6febeac83102a8cbb\kotlin-util-io-1.8.20.jar -jvm-target 1.8 -kotlin-home D:\Program" "Files\JetBrains\IntelliJ" "IDEA" "Community" "Edition" "2023.1.1\plugins\Kotlin\kotlinc |
3.3.jshell
jshell跨越宿主jvm执行动态字节码理论上不可行,推迟
3.4.jupyter 集成 //成功
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
启动jupyterlab d:\lib\Python\Python37\Scripts\jupyter.exe lab --allow-root 添加自定义kernel d:\lib\Python\Python37\python.exe -m kotlin_kernel add-kernel --name test 添加idea kernel d:\lib\Python\Python37\python.exe -m kotlin_kernel add-kernel --force --name skykoma-agent-idea --env SKYKOMA_AGENT_TYPE idea --env SKYKOMA_AGENT_SERVER_API http://127.0.0.1:2333/startJupyterKernel 安装位置 Python37\Lib\site-packages\kotlin_kernel 运行时记录 %appdata%\jupyter\runtime 默认kernel的位置 Python37\share\jupyter\kernels\kotlin 自定义kernel的位置 %appdata%\jupyter\kernels 启动kernel脚本的位置 Python37\Lib\site-packages\run_kotlin_kernel 最终脚本 CONDA_HOME=/data/lib/anaconda3 SKYKOMA_PYTHON_HOME=$CONDA_HOME/envs/skykoma SKYKOMA_PYTHON_BIN=$SKYKOMA_PYTHON_HOME/bin SKYKOMA_PIP=$SKYKOMA_PYTHON_BIN/pip RUN_KOTLIN_KERNEL_DIR=$SKYKOMA_PYTHON_HOME/lib/python3.8/site-packages/run_kotlin_kernel $CONDA_HOME/bin/conda create -n skykoma python=3.8 -y $SKYKOMA_PIP install jupyterlab kotlin-jupyter-kernel jupyterlab-lsp git+https://github.com/956237586/jupyter_client.git@v8.4.3 -i https://pypi.tuna.tsinghua.edu.cn/simple mv $RUN_KOTLIN_KERNEL_DIR/run_kernel.py $RUN_KOTLIN_KERNEL_DIR/run_kernel.py.bak wget -O $RUN_KOTLIN_KERNEL_DIR/run_kernel.py https://raw.githubusercontent.com/956237586/kotlin-jupyter/ideav0.0.1/distrib/run_kotlin_kernel/run_kernel.py $SKYKOMA_PYTHON_BIN/jupyter-lab --ip=0.0.0.0 --allow-root |
记录下当前的依赖版本
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
The following NEW packages will be INSTALLED: _libgcc_mutex pkgs/main/linux-64::_libgcc_mutex-0.1-main _openmp_mutex pkgs/main/linux-64::_openmp_mutex-5.1-1_gnu ca-certificates pkgs/main/linux-64::ca-certificates-2023.08.22-h06a4308_0 ld_impl_linux-64 pkgs/main/linux-64::ld_impl_linux-64-2.38-h1181459_1 libffi pkgs/main/linux-64::libffi-3.4.4-h6a678d5_0 libgcc-ng pkgs/main/linux-64::libgcc-ng-11.2.0-h1234567_1 libgomp pkgs/main/linux-64::libgomp-11.2.0-h1234567_1 libstdcxx-ng pkgs/main/linux-64::libstdcxx-ng-11.2.0-h1234567_1 ncurses pkgs/main/linux-64::ncurses-6.4-h6a678d5_0 openssl pkgs/main/linux-64::openssl-3.0.11-h7f8727e_2 pip pkgs/main/linux-64::pip-23.3-py38h06a4308_0 python pkgs/main/linux-64::python-3.8.18-h955ad1f_0 readline pkgs/main/linux-64::readline-8.2-h5eee18b_0 setuptools pkgs/main/linux-64::setuptools-68.0.0-py38h06a4308_0 sqlite pkgs/main/linux-64::sqlite-3.41.2-h5eee18b_0 tk pkgs/main/linux-64::tk-8.6.12-h1ccaba5_0 wheel pkgs/main/linux-64::wheel-0.41.2-py38h06a4308_0 xz pkgs/main/linux-64::xz-5.4.2-h5eee18b_0 zlib pkgs/main/linux-64::zlib-1.2.13-h5eee18b_0 Successfully installed MarkupSafe-2.1.3 anyio-4.0.0 argon2-cffi-23.1.0 argon2-cffi-bindings-21.2.0 arrow-1.3.0 asttokens-2.4.0 async-lru-2.0.4 attrs-23.1.0 babel-2.13.0 backcall-0.2.0 beautifulsoup4-4.12.2 bleach-6.1.0 certifi-2023.7.22 cffi-1.16.0 charset-normalizer-3.3.0 comm-0.1.4 debugpy-1.8.0 decorator-5.1.1 defusedxml-0.7.1 exceptiongroup-1.1.3 executing-2.0.0 fastjsonschema-2.18.1 fqdn-1.5.1 idna-3.4 importlib-metadata-6.8.0 importlib-resources-6.1.0 ipykernel-6.25.2 ipython-8.12.3 isoduration-20.11.0 jedi-0.19.1 jinja2-3.1.2 json5-0.9.14 jsonpointer-2.4 jsonschema-4.19.1 jsonschema-specifications-2023.7.1 jupyter-core-5.4.0 jupyter-events-0.8.0 jupyter-lsp-2.2.0 jupyter-server-2.8.0 jupyter-server-terminals-0.4.4 jupyter_client-8.4.3 jupyterlab-4.0.7 jupyterlab-lsp-5.0.0 jupyterlab-pygments-0.2.2 jupyterlab-server-2.25.0 kotlin-jupyter-kernel-0.11.0.385 matplotlib-inline-0.1.6 mistune-3.0.2 nbclient-0.8.0 nbconvert-7.9.2 nbformat-5.9.2 nest-asyncio-1.5.8 notebook-shim-0.2.3 overrides-7.4.0 packaging-23.2 pandocfilters-1.5.0 parso-0.8.3 pexpect-4.8.0 pickleshare-0.7.5 pkgutil-resolve-name-1.3.10 platformdirs-3.11.0 prometheus-client-0.17.1 prompt-toolkit-3.0.39 psutil-5.9.6 ptyprocess-0.7.0 pure-eval-0.2.2 pycparser-2.21 pygments-2.16.1 python-dateutil-2.8.2 python-json-logger-2.0.7 pytz-2023.3.post1 pyyaml-6.0.1 pyzmq-25.1.1 referencing-0.30.2 requests-2.31.0 rfc3339-validator-0.1.4 rfc3986-validator-0.1.1 rpds-py-0.10.6 send2trash-1.8.2 six-1.16.0 sniffio-1.3.0 soupsieve-2.5 stack-data-0.6.3 terminado-0.17.1 tinycss2-1.2.1 tomli-2.0.1 tornado-6.3.3 traitlets-5.11.2 types-python-dateutil-2.8.19.14 typing-extensions-4.8.0 uri-template-1.3.0 urllib3-2.0.7 wcwidth-0.2.8 webcolors-1.13 webencodings-0.5.1 websocket-client-1.6.4 zipp-3.17.0 |
安装完jupyterlab和kotlin-kernel后可以在python包的路径中看到相关的文件夹,kernel的描述文件主要入口是kernel.json,内容如下
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
kernel.json { "display_name": "Kotlin test", "language": "kotlin", "interrupt_mode": "message", "argv": [ "python", "-m", "run_kotlin_kernel", "{connection_file}" ], "metadata": { "jar_path_detect_command": [ "python", "-m", "kotlin_kernel", "detect-jars-location" ] } } |
其中核心内容是argv,可以看到当kernel启动时候实际执行的是run_kotlin_kernel,其中connection_file每次动态生成,内容如下
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
kernel启动文件 kernel-5c0d2ff3-0e13-4c47-8b2c-4d530ab5bfd2.json { "shell_port": 62530, "iopub_port": 62531, "stdin_port": 62532, "control_port": 62534, "hb_port": 62533, "ip": "127.0.0.1", "key": "3d6d8387-d77b2b9af1b24cd0c43ad844", "transport": "tcp", "signature_scheme": "hmac-sha256", "kernel_name": "kotlin_test" } |
文件中描述了本次内核启动需要的端口、标识、协议等信息传递给python脚本。python脚本主要用于拼接启动命令
主要是获取环境变量、寻找java可执行文件路径、获取当前文件夹等信息,拼接的命令如下。
0 1 2 3 4 5 6 7 8 9 10 11 12 |
kernel启动参数 源码位置 Python37\Lib\site-packages\run_kotlin_kernel\run_kernel.py [ 'D:\\Program Files\\Java\\jdk1.8.0_131\\bin\\java', '-jar', '-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=1044', 'd:\\lib\\python\\python37\\lib\\site-packages\\run_kotlin_kernel\\jars\\kotlin-jupyter-kernel-0.11.0-385.jar', '-classpath=d:\\lib\\python\\python37\\lib\\site-packages\\run_kotlin_kernel\\jars\\lib-0.11.0-385.jar;d:\\lib\\python\\python37\\lib\\site-packages\\run_kotlin_kernel\\jars\\api-0.11.0-385.jar;d:\\lib\\python\\python37\\lib\\site-packages\\run_kotlin_kernel\\jars\\kotlin-script-runtime-1.8.20.jar;d:\\lib\\python\\python37\\lib\\site-packages\\run_kotlin_kernel\\jars\\kotlin-reflect-1.8.20.jar;d:\\lib\\python\\python37\\lib\\site-packages\\run_kotlin_kernel\\jars\\kotlin-stdlib-1.8.20.jar;d:\\lib\\python\\python37\\lib\\site-packages\\run_kotlin_kernel\\jars\\kotlin-stdlib-common-1.8.20.jar;d:\\lib\\python\\python37\\lib\\site-packages\\run_kotlin_kernel\\jars\\annotations-13.0.jar;d:\\lib\\python\\python37\\lib\\site-packages\\run_kotlin_kernel\\jars\\kotlinx-serialization-json-jvm-1.4.1.jar;d:\\lib\\python\\python37\\lib\\site-packages\\run_kotlin_kernel\\jars\\kotlinx-serialization-core-jvm-1.4.1.jar;d:\\lib\\python\\python37\\lib\\site-packages\\run_kotlin_kernel\\jars\\kotlin-stdlib-jdk8-1.7.20.jar;d:\\lib\\python\\python37\\lib\\site-packages\\run_kotlin_kernel\\jars\\kotlin-stdlib-jdk7-1.7.20.jar', 'C:\\Users\\MY_USERNAME\\AppData\\Roaming\\jupyter\\runtime\\kernel-aed92867-20a4-4c37-b713-5385b155a17d.json', '-home=d:\\lib\\python\\python37\\lib\\site-packages\\run_kotlin_kernel', '-debugPort=1044' ] |
修改run_kernel.py如下
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 |
import json import os import shlex import subprocess import sys from kotlin_kernel import env_names from kotlin_kernel import port_generator def run_kernel(*args): try: run_kernel_impl(*args) except KeyboardInterrupt: print('Kernel interrupted') try: sys.exit(130) except SystemExit: os._exit(130) def module_install_path(): abspath = os.path.abspath(__file__) current_dir = os.path.dirname(abspath) return str(current_dir) def run_kernel_impl(connection_file, jar_args_file=None, executables_dir=None): abspath = os.path.abspath(__file__) current_dir = os.path.dirname(abspath) if jar_args_file is None: jar_args_file = os.path.join(current_dir, 'config', 'jar_args.json') if executables_dir is None: executables_dir = current_dir jars_dir = os.path.join(executables_dir, 'jars') with open(jar_args_file, 'r') as fd: jar_args_json = json.load(fd) debug_port = jar_args_json['debuggerPort'] cp = jar_args_json['classPath'] main_jar = jar_args_json['mainJar'] debug_list = [] if debug_port is not None and debug_port != '': if debug_port == 'generate': debug_port = port_generator.get_port_not_in_use(port_generator .DEFAULT_DEBUG_PORT) debug_list.append( '-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address={}' .format(debug_port)) else: debug_port = None class_path_arg = os.pathsep.join([os.path.join(jars_dir, jar_name) for jar_name in cp]) main_jar_path = os.path.join(jars_dir, main_jar) java_exec = os.getenv(env_names.KERNEL_JAVA_EXECUTABLE) java_home = os.getenv(env_names.KERNEL_JAVA_HOME) or os.getenv( env_names.JAVA_HOME) if java_exec is not None: java = java_exec elif java_home is not None: java = os.path.join(java_home, 'bin', 'java') else: java = 'java' jvm_arg_str = os.getenv(env_names.KERNEL_JAVA_OPTS) or os.getenv( env_names.JAVA_OPTS) or '' extra_args = os.getenv(env_names.KERNEL_EXTRA_JAVA_OPTS) if extra_args is not None: jvm_arg_str += ' ' + extra_args kernel_args = os.getenv(env_names.KERNEL_INTERNAL_ADDED_JAVA_OPTS) if kernel_args is not None: jvm_arg_str += ' ' + kernel_args jvm_args = shlex.split(jvm_arg_str) jar_args = [main_jar_path, '-classpath=' + class_path_arg, connection_file, '-home=' + executables_dir] if debug_port is not None: jar_args.append('-debugPort=' + str(debug_port)) #for skykoma-agent-idea begin skykoma_agent_idea = 'idea' in os.getenv('SKYKOMA_AGENT_TYPE', '') if skykoma_agent_idea: import requests import time skykoma_agent_server_api = os.getenv('SKYKOMA_AGENT_SERVER_API') payload = json.dumps(jar_args[1:]) print('launch skykoma agent idea jupyter repl server, api: {}, args: {}'.format(skykoma_agent_server_api, payload)) headers = {"Content-Type": "application/json"} response = requests.post(skykoma_agent_server_api, data=payload, headers=headers) print(response.status_code) print(response.json()) while True: time.sleep(10000) #avoid current process exit else: print([java] + jvm_args + ['-jar'] + debug_list + jar_args) #for debug only subprocess.call([java] + jvm_args + ['-jar'] + debug_list + jar_args) # subprocess.call([java] + jvm_args + ['-jar'] + debug_list + jar_args) #for skykoma-agent-idea end if __name__ == '__main__': run_kernel(*sys.argv[1:]) |
目前add_kernel支持设置环境变量之类的参数,理论上可以把这个过程从原流程中剥离出来独立出一个jar来执行,这样可以不破坏原有的python文件同时完成自定义kernel的接入,目前仅是demo直接暴力修改了python脚本不是很优雅
0.0.9初步实现了用自动注册kernel,可手动指定python的目录,支持动态修改kernel.json。
剥离对官方run_kernel.py的依赖,暂时使用shell替换整个文件
0 1 2 |
<del>mv $RUN_KOTLIN_KERNEL_DIR/run_kernel.py $RUN_KOTLIN_KERNEL_DIR/run_kernel.py.bak wget -O $RUN_KOTLIN_KERNEL_DIR/run_kernel.py https://raw.githubusercontent.com/956237586/kotlin-jupyter/ideav0.0.1/distrib/run_kotlin_kernel/run_kernel.py</del> |
20250201更新:更换为独立模块摆脱对官方的依赖 https://github.com/956237586/run_kotlin_kernel_idea
尝试手动指定、远程分配监听端口:根据调用栈可追踪,需要修改逻辑
https://github.com/jupyter-server/jupyter_server
https://github.com/jupyter-server/jupyter_client
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
[<FrameSummary file /data/lib/anaconda3/envs/skykoma/bin/jupyter-lab, line 8 in <module>>, <FrameSummary file /data/lib/anaconda3/envs/skykoma/lib/python3.8/site-packages/jupyter_server/extension/application.py, line 614 in launch_instance>, <FrameSummary file /data/lib/anaconda3/envs/skykoma/lib/python3.8/site-packages/jupyter_server/serverapp.py, line 2968 in start>, <FrameSummary file /data/lib/anaconda3/envs/skykoma/lib/python3.8/site-packages/jupyter_server/serverapp.py, line 2954 in start_ioloop>, <FrameSummary file /data/lib/anaconda3/envs/skykoma/lib/python3.8/site-packages/tornado/platform/asyncio.py, line 195 in start>, <FrameSummary file /data/lib/anaconda3/envs/skykoma/lib/python3.8/asyncio/base_events.py, line 570 in run_forever>, <FrameSummary file /data/lib/anaconda3/envs/skykoma/lib/python3.8/asyncio/base_events.py, line 1859 in _run_once>, <FrameSummary file /data/lib/anaconda3/envs/skykoma/lib/python3.8/asyncio/events.py, line 81 in _run>, <FrameSummary file /data/lib/anaconda3/envs/skykoma/lib/python3.8/site-packages/jupyter_client/multikernelmanager.py, line 239 in _add_kernel_when_ready>, <FrameSummary file /data/lib/anaconda3/envs/skykoma/lib/python3.8/site-packages/jupyter_core/utils/__init__.py, line 189 in ensure_async>, <FrameSummary file /data/lib/anaconda3/envs/skykoma/lib/python3.8/site-packages/jupyter_server/services/kernels/kernelmanager.py, line 739 in wrapped_method>, <FrameSummary file /data/lib/anaconda3/envs/skykoma/lib/python3.8/site-packages/jupyter_server/services/kernels/kernelmanager.py, line 844 in start_kernel>, <FrameSummary file /data/lib/anaconda3/envs/skykoma/lib/python3.8/site-packages/jupyter_client/manager.py, line 85 in wrapper>, <FrameSummary file /data/lib/anaconda3/envs/skykoma/lib/python3.8/site-packages/jupyter_client/manager.py, line 401 in _async_start_kernel>, <FrameSummary file /data/lib/anaconda3/envs/skykoma/lib/python3.8/site-packages/jupyter_client/manager.py, line 366 in _async_pre_start_kernel>, <FrameSummary file /data/lib/anaconda3/envs/skykoma/lib/python3.8/site-packages/jupyter_client/provisioning/local_provisioner.py, line 193 in pre_launch>, <FrameSummary file /data/lib/anaconda3/envs/skykoma/lib/python3.8/site-packages/jupyter_client/connect.py, line 494 in write_connection_file>, <FrameSummary file /data/lib/anaconda3/envs/skykoma/lib/python3.8/site-packages/jupyter_client/connect.py, line 146 in write_connection_file>] |
fork官方库后修改对应的代码强制使用环境变量中的端口,打tag v8.4.3后可从github安装指定版本
0 1 |
pip install git+https://github.com/956237586/jupyter_client.git@v8.4.3 |
之后可支持在kernel.json的环境变量指定端口
0 1 2 3 4 5 |
JUPYTER_SERVER_HB_PORT=2334 JUPYTER_SERVER_SHELL_PORT=2335 JUPYTER_SERVER_IOPUB_PORT=2336 JUPYTER_SERVER_STDIN_PORT=2337 JUPYTER_SERVER_CONTROL_PORT=2338 |
继续分析脚本逻辑,为了方便理解简化启动命令为 java -jar xxx.jar -classpath=xxx xxx.json -home=xxx -debugPort=xxx,可以看到入口是kotlin-jupyter-kernel-0.11.0-385.jar,这个jar是kotlin编写的
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
进入main方法 kotlin-jupyter\src\main\kotlin\org\jetbrains\kotlinx\jupyter\ikotlin.kt 304 [main] INFO ikotlin - Kernel args: -classpath=d:\lib\python\python37\lib\site-packages\run_kotlin_kernel\jars\lib-0.11.0-385.jar;d:\lib\python\python37\lib\site-packages\run_kotlin_kernel\jars\api-0.11.0-385.jar;d:\lib\python\python37\lib\site-packages\run_kotlin_kernel\jars\kotlin-script-runtime-1.8.20.jar;d:\lib\python\python37\lib\site-packages\run_kotlin_kernel\jars\kotlin-reflect-1.8.20.jar;d:\lib\python\python37\lib\site-packages\run_kotlin_kernel\jars\kotlin-stdlib-1.8.20.jar;d:\lib\python\python37\lib\site-packages\run_kotlin_kernel\jars\kotlin-stdlib-common-1.8.20.jar;d:\lib\python\python37\lib\site-packages\run_kotlin_kernel\jars\annotations-13.0.jar;d:\lib\python\python37\lib\site-packages\run_kotlin_kernel\jars\kotlinx-serialization-json-jvm-1.4.1.jar;d:\lib\python\python37\lib\site-packages\run_kotlin_kernel\jars\kotlinx-serialization-core-jvm-1.4.1.jar;d:\lib\python\python37\lib\site-packages\run_kotlin_kernel\jars\kotlin-stdlib-jdk8-1.7.20.jar;d:\lib\python\python37\lib\site-packages\run_kotlin_kernel\jars\kotlin-stdlib-jdk7-1.7.20.jar, %appdata%\jupyter\runtime\kernel-74030245-825b-42a9-86c8-27d6d1611f73.json, -home=d:\lib\python\python37\lib\site-packages\run_kotlin_kernel, -debugPort=1044 实际参数是4个,依次是 -classpath=xxxx %appdata%\jupyter\runtime\kernel-74030245-825b-42a9-86c8-27d6d1611f73.json -home=d:\lib\python\python37\lib\site-packages\run_kotlin_kernel -debugPort=1044 代码会读取json文件中的端口信息生成KernelConfig对象并启动kotlin repl server 872 [main] INFO ikotlin - Starting server with config: KernelConfig(ports={HB=60300, SHELL=60297, CONTROL=60301, STDIN=60299, IOPUB=60298}, transport=tcp, signatureScheme=hmac-sha256, signatureKey=d64037f7-bbd2219eda35a777b2acf6d3, scriptClasspath=[d:\lib\python\python37\lib\site-packages\run_kotlin_kernel\jars\lib-0.11.0-385.jar, d:\lib\python\python37\lib\site-packages\run_kotlin_kernel\jars\api-0.11.0-385.jar, d:\lib\python\python37\lib\site-packages\run_kotlin_kernel\jars\kotlin-script-runtime-1.8.20.jar, d:\lib\python\python37\lib\site-packages\run_kotlin_kernel\jars\kotlin-reflect-1.8.20.jar, d:\lib\python\python37\lib\site-packages\run_kotlin_kernel\jars\kotlin-stdlib-1.8.20.jar, d:\lib\python\python37\lib\site-packages\run_kotlin_kernel\jars\kotlin-stdlib-common-1.8.20.jar, d:\lib\python\python37\lib\site-packages\run_kotlin_kernel\jars\annotations-13.0.jar, d:\lib\python\python37\lib\site-packages\run_kotlin_kernel\jars\kotlinx-serialization-json-jvm-1.4.1.jar, d:\lib\python\python37\lib\site-packages\run_kotlin_kernel\jars\kotlinx-serialization-core-jvm-1.4.1.jar, d:\lib\python\python37\lib\site-packages\run_kotlin_kernel\jars\kotlin-stdlib-jdk8-1.7.20.jar, d:\lib\python\python37\lib\site-packages\run_kotlin_kernel\jars\kotlin-stdlib-jdk7-1.7.20.jar], homeDir=d:\lib\python\python37\lib\site-packages\run_kotlin_kernel, debugPort=1044, clientType=null, jvmTargetForSnippets=null) 为了方便后面从java中调用,记录这个文件编译完的路径 kotlin-jupyter-kernel-0.11.0-385.jar!/org/jetbrains/kotlinx/jupyter/IkotlinKt.class |
根据日志和源码的情况,如果我们想模拟这个过程,只需要让server在idea插件的上下文启动。
因为端口描述的文件每次都是动态生成的,因此修改run_kernel.py把命令行参数传给idea插件,idea插件再启动replserver
在idea插件里启动一个httpserver监听请求,接读取原来的参数调用embedKernel,同时替换classpath为当前线程上下文的classpath,示例请求如下
0 1 |
curl --X POST --url http://localhost:2333/startJupyterKernel --header 'content-type: application/json' --data '["-classpath=d:\\lib\\python\\python37\\lib\\site-packages\\run_kotlin_kernel\\jars\\lib-0.11.0-385.jar;d:\\lib\\python\\python37\\lib\\site-packages\\run_kotlin_kernel\\jars\\api-0.11.0-385.jar;d:\\lib\\python\\python37\\lib\\site-packages\\run_kotlin_kernel\\jars\\kotlin-script-runtime-1.8.20.jar;d:\\lib\\python\\python37\\lib\\site-packages\\run_kotlin_kernel\\jars\\kotlin-reflect-1.8.20.jar;d:\\lib\\python\\python37\\lib\\site-packages\\run_kotlin_kernel\\jars\\kotlin-stdlib-1.8.20.jar;d:\\lib\\python\\python37\\lib\\site-packages\\run_kotlin_kernel\\jars\\kotlin-stdlib-common-1.8.20.jar;d:\\lib\\python\\python37\\lib\\site-packages\\run_kotlin_kernel\\jars\\annotations-13.0.jar;d:\\lib\\python\\python37\\lib\\site-packages\\run_kotlin_kernel\\jars\\kotlinx-serialization-json-jvm-1.4.1.jar;d:\\lib\\python\\python37\\lib\\site-packages\\run_kotlin_kernel\\jars\\kotlinx-serialization-core-jvm-1.4.1.jar;d:\\lib\\python\\python37\\lib\\site-packages\\run_kotlin_kernel\\jars\\kotlin-stdlib-jdk8-1.7.20.jar;d:\\lib\\python\\python37\\lib\\site-packages\\run_kotlin_kernel\\jars\\kotlin-stdlib-jdk7-1.7.20.jar", "C:\\Users\\MY_USERNAME\\AppData\\Roaming\\jupyter\\runtime\\kernel-c1c0ec36-932d-48dc-9eda-4f0beb0edc60.json", "-home=d:\\lib\\python\\python37\\lib\\site-packages\\run_kotlin_kernel", "-debugPort=1044"]' |
这样启动之后就可以尝试jupyter中执行kotlin了,遇到的错误如下
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
Unable to initialize repl compiler: DEBUG Using JDK home inferred from java.home: D:\\Program Files\\JetBrains\\IntelliJ IDEA Community Edition 2023.1\ \jbr DEBUG Using JVM IR backend DEBUG Using JVM IR backend ERROR 'void org.jetbrains.kotlin.scripting.definitions.ScriptDependenciesProvider.<init>(org.je tbrains.kotlin.com.intellij.openapi.project.Project)': java.lang.NoSuchMethodError: 'void org.jetbrains.kotlin.scripting.definitions.ScriptDependenciesProvider.<in it>(org.jetbrains.kotlin.com.intellij.openapi.project.Project)'", "traceback":[ "org.jetbrains.kotlinx.jupyter.repl.impl.JupyterCompilerImpl.compileSync(JupyterCompilerImpl.kt:174)", "org.jetbrains.kotlinx.jupyter.repl.impl.InternalEvaluatorImpl.eval(InternalEvaluatorImpl.kt:99)", "org.jetbrains.kotlinx.jupyter.repl.impl.CellExecutorImpl$execute$1$result$1.invoke(CellExecutorImpl.kt:75)", "org.jetbrains.kotlinx.jupyter.repl.impl.CellExecutorImpl$execute$1$result$1.invoke(CellExecutorImpl.kt:73)", "org.jetbrains.kotlinx.jupyter.ReplForJupyterImpl.withHost(repl.kt:666)", "org.jetbrains.kotlinx.jupyter.repl.impl.CellExecutorImpl.execute(CellExecutorImpl.kt:73)", "org.jetbrains.kotlinx.jupyter.repl.CellExecutor$DefaultImpls.execute$default(CellExecutor.kt:15)", "org.jetbrains.kotlinx.jupyter.ReplForJupyterImpl$evalEx$1.invoke(repl.kt:479)", "org.jetbrains.kotlinx.jupyter.ReplForJupyterImpl$evalEx$1.invoke(repl.kt:470)", "org.jetbrains.kotlinx.jupyter.ReplForJupyterImpl.withEvalContext(repl.kt:433)", "org.jetbrains.kotlinx.jupyter.ReplForJupyterImpl.evalEx(repl.kt:470)", "org.jetbrains.kotlinx.jupyter.messaging.ProtocolKt$shellMessagesHandler$2$res$1.invoke(protocol.kt:318)", "org.jetbrains.kotlinx.jupyter.messaging.ProtocolKt$shellMessagesHandler$2$res$1.invoke(protocol.kt:312)", "org.jetbrains.kotlinx.jupyter.JupyterExecutorImpl$runExecution$execThread$1.invoke(execution.kt:37)", "org.jetbrains.kotlinx.jupyter.JupyterExecutorImpl$runExecution$execThread$1.invoke(execution.kt:32)", "kotlin.concurrent.ThreadsKt$thread$thread$1.run(Thread.kt:30) org.jetbrains.kotlin.com.intellij.mock.MockProject public class MockProject extends MockComponentManager implements Project { org.jetbrains.kotlin.com.intellij.openapi.project.Project java.lang.NoSuchMethodError: 'void org.jetbrains.kotlin.scripting.definitions.ScriptDependenciesProvider.<init>(org.jetbrains.kotlin.com.intellij.openapi.project.Project)' at org.jetbrains.kotlin.scripting.compiler.plugin.definitions.CliScriptDependenciesProvider.<init>(CliScriptDependenciesProvider.kt:19) at org.jetbrains.kotlin.scripting.compiler.plugin.ScriptingCompilerConfigurationComponentRegistrar.registerProjectComponents(pluginRegisrar.kt:71) at org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment$Companion.registerExtensionsFromPlugins$cli(KotlinCoreEnvironment.kt:671) at org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment$ProjectEnvironment.registerExtensionsFromPlugins(KotlinCoreEnvironment.kt:162) at org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment$Companion.configureProjectEnvironment(KotlinCoreEnvironment.kt:572) at org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment.<init>(KotlinCoreEnvironment.kt:192) at org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment.<init>(KotlinCoreEnvironment.kt:107) at org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment$Companion.createForProduction(KotlinCoreEnvironment.kt:442) at org.jetbrains.kotlin.scripting.compiler.plugin.impl.CompilationContextKt.createIsolatedCompilationContext(compilationContext.kt:93) at org.jetbrains.kotlin.scripting.compiler.plugin.impl.KJvmReplCompilerBase$Companion.createCompilationState(KJvmReplCompilerBase.kt:331) at org.jetbrains.kotlin.scripting.ide_services.compiler.KJvmReplCompilerWithIdeServices$1.invoke(KJvmReplCompilerWithIdeServices.kt:30) at org.jetbrains.kotlin.scripting.ide_services.compiler.KJvmReplCompilerWithIdeServices$1.invoke(KJvmReplCompilerWithIdeServices.kt:29) at org.jetbrains.kotlin.scripting.compiler.plugin.repl.JvmReplCompilerState.initializeCompilation(jvmReplCompilation.kt:61) at org.jetbrains.kotlin.scripting.compiler.plugin.repl.JvmReplCompilerState.getCompilationState(jvmReplCompilation.kt:47) at org.jetbrains.kotlin.scripting.compiler.plugin.impl.KJvmReplCompilerBase.compile$suspendImpl(KJvmReplCompilerBase.kt:74) at org.jetbrains.kotlin.scripting.compiler.plugin.impl.KJvmReplCompilerBase.compile(KJvmReplCompilerBase.kt) at kotlin.script.experimental.api.ReplCompiler.compile$suspendImpl(replCompilation.kt:49) at kotlin.script.experimental.api.ReplCompiler.compile(replCompilation.kt) at org.jetbrains.kotlinx.jupyter.repl.impl.JupyterCompilerImpl$compileSync$resultWithDiagnostics$1.invokeSuspend(JupyterCompilerImpl.kt:173) at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33) at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106) at kotlinx.coroutines.EventLoopImplBase.processNextEvent(EventLoop.common.kt:284) at kotlinx.coroutines.BlockingCoroutine.joinBlocking(Builders.kt:85) at kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking(Builders.kt:59) at kotlinx.coroutines.BuildersKt.runBlocking(Unknown Source) at kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking$default(Builders.kt:38) at kotlinx.coroutines.BuildersKt.runBlocking$default(Unknown Source) at org.jetbrains.kotlinx.jupyter.repl.impl.JupyterCompilerImpl.compileSync(JupyterCompilerImpl.kt:173) at org.jetbrains.kotlinx.jupyter.repl.impl.InternalEvaluatorImpl.eval(InternalEvaluatorImpl.kt:99) at org.jetbrains.kotlinx.jupyter.repl.impl.CellExecutorImpl$execute$1$result$1.invoke(CellExecutorImpl.kt:75) at org.jetbrains.kotlinx.jupyter.repl.impl.CellExecutorImpl$execute$1$result$1.invoke(CellExecutorImpl.kt:73) at org.jetbrains.kotlinx.jupyter.ReplForJupyterImpl.withHost(repl.kt:666) at org.jetbrains.kotlinx.jupyter.repl.impl.CellExecutorImpl.execute(CellExecutorImpl.kt:73) at org.jetbrains.kotlinx.jupyter.repl.CellExecutor$DefaultImpls.execute$default(CellExecutor.kt:15) at org.jetbrains.kotlinx.jupyter.ReplForJupyterImpl$evalEx$1.invoke(repl.kt:479) at org.jetbrains.kotlinx.jupyter.ReplForJupyterImpl$evalEx$1.invoke(repl.kt:470) at org.jetbrains.kotlinx.jupyter.ReplForJupyterImpl.withEvalContext(repl.kt:433) at org.jetbrains.kotlinx.jupyter.ReplForJupyterImpl.evalEx(repl.kt:470) at org.jetbrains.kotlinx.jupyter.messaging.ProtocolKt$shellMessagesHandler$2$res$1.invoke(protocol.kt:318) at org.jetbrains.kotlinx.jupyter.messaging.ProtocolKt$shellMessagesHandler$2$res$1.invoke(protocol.kt:312) at org.jetbrains.kotlinx.jupyter.JupyterExecutorImpl$runExecution$execThread$1.invoke(execution.kt:37) at org.jetbrains.kotlinx.jupyter.JupyterExecutorImpl$runExecution$execThread$1.invoke(execution.kt:32) at kotlin.concurrent.ThreadsKt$thread$thread$1.run(Thread.kt:30) |
避开之前测试引入的库影响同时保证编译通过,仅保留相关的依赖
0 1 2 3 4 5 |
仅保留 implementation("org.jetbrains.kotlinx:kotlin-jupyter-api:0.11.0-385") implementation("org.jetbrains.kotlinx:kotlin-jupyter-kernel:0.11.0-385") implementation("org.jetbrains.kotlin:kotlin-compiler-embeddable:1.8.20") implementation("org.jetbrains.kotlin:kotlin-scripting-jvm:1.8.20") |
再次继续测试错误如下
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
"content":{"status":"error","execution_count":9,"ename":"org.jetbrains.kotlinx.jupyter.exceptions.ReplCompilerException","evalue":"Line_8.jupyter.kts (1:1 - 9) Cannot access script base class 'jupyter.kotlin.ScriptTemplateWithDisplayHelpers'. Check your module classpath for missing or conflicting dependencies","traceback":["org.jetbrains.kotlinx.jupyter.repl.impl.JupyterCompilerImpl.compileSync(JupyterCompilerImpl.kt:174)","org.jetbrains.kotlinx.jupyter.repl.impl.InternalEvaluatorImpl.eval(InternalEvaluatorImpl.kt:99)","org.jetbrains.kotlinx.jupyter.repl.impl.CellExecutorImpl$execute$1$result$1.invoke(CellExecutorImpl.kt:75)","org.jetbrains.kotlinx.jupyter.repl.impl.CellExecutorImpl$execute$1$result$1.invoke(CellExecutorImpl.kt:73)","org.jetbrains.kotlinx.jupyter.ReplForJupyterImpl.withHost(repl.kt:666)","org.jetbrains.kotlinx.jupyter.repl.impl.CellExecutorImpl.execute(CellExecutorImpl.kt:73)","org.jetbrains.kotlinx.jupyter.repl.CellExecutor$DefaultImpls.execute$default(CellExecutor.kt:15)","org.jetbrains.kotlinx.jupyter.ReplForJupyterImpl$evalEx$1.invoke(repl.kt:479)","org.jetbrains.kotlinx.jupyter.ReplForJupyterImpl$evalEx$1.invoke(repl.kt:470)","org.jetbrains.kotlinx.jupyter.ReplForJupyterImpl.withEvalContext(repl.kt:433)","org.jetbrains.kotlinx.jupyter.ReplForJupyterImpl.evalEx(repl.kt:470)","org.jetbrains.kotlinx.jupyter.messaging.ProtocolKt$shellMessagesHandler$2$res$1.invoke(protocol.kt:318)","org.jetbrains.kotlinx.jupyter.messaging.ProtocolKt$shellMessagesHandler$2$res$1.invoke(protocol.kt:312)","org.jetbrains.kotlinx.jupyter.JupyterExecutorImpl$runExecution$execThread$1.invoke(execution.kt:37)","org.jetbrains.kotlinx.jupyter.JupyterExecutorImpl$runExecution$execThread$1.invoke(execution.kt:32)","kotlin.concurrent.ThreadsKt$thread$thread$1.run(Thread.kt:30)"],"additionalInfo":{"lineStart":1,"colStart":1,"lineEnd":1,"colEnd":9,"message":"Cannot access script base class 'jupyter.kotlin.ScriptTemplateWithDisplayHelpers'. Check your module classpath for missing or conflicting dependencies","path":"Line_8.jupyter.kts"}}} 为了排除环境问题,单开一个独立jvmdemo测试,记录日志做对比。并开启debug ['D:\\lib\\jdk-17\\bin\\java', '-jar', '-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=1046', 'd:\\lib\\python\\python37\\lib\\site-packages\\run_kotlin_kernel\\jars\\Test-Kernel-1.0.jar', '-classpath=d:\\lib\\python\\python37\\lib\\site-packages\\run_kotlin_kernel\\jars\\lib-0.11.0-385.jar;d:\\lib\\python\\python37\\lib\\site-packages\\run_kotlin_kernel\\jars\\api-0.11.0-385.jar;d:\\lib\\python\\python37\\lib\\site-packages\\run_kotlin_kernel\\jars\\kotlin-script-runtime-1.8.20.jar;d:\\lib\\python\\python37\\lib\\site-packages\\run_kotlin_kernel\\jars\\kotlin-reflect-1.8.20.jar;d:\\lib\\python\\python37\\lib\\site-packages\\run_kotlin_kernel\\jars\\kotlin-stdlib-1.8.20.jar;d:\\lib\\python\\python37\\lib\\site-packages\\run_kotlin_kernel\\jars\\kotlin-stdlib-common-1.8.20.jar;d:\\lib\\python\\python37\\lib\\site-packages\\run_kotlin_kernel\\jars\\annotations-13.0.jar;d:\\lib\\python\\python37\\lib\\site-packages\\run_kotlin_kernel\\jars\\kotlinx-serialization-json-jvm-1.4.1.jar;d:\\lib\\python\\python37\\lib\\site-packages\\run_kotlin_kernel\\jars\\kotlinx-serialization-core-jvm-1.4.1.jar;d:\\lib\\python\\python37\\lib\\site-packages\\run_kotlin_kernel\\jars\\kotlin-stdlib-jdk8-1.7.20.jar;d:\\lib\\python\\python37\\lib\\site-packages\\run_kotlin_kernel\\jars\\kotlin-stdlib-jdk7-1.7.20.jar', 'C:\\Users\\MY_USERNAME\\AppData\\Roaming\\jupyter\\runtime\\kernel-a417a922-63b3-4d8b-ad3b-2dccf9ca31a3.json', '-home=d:\\lib\\python\\python37\\lib\\site-packages\\run_kotlin_kernel', '-debugPort=1046'] Listening for transport dt_socket at address: 1046 220 [main] INFO ikotlin - Starting server with config: KernelConfig(ports={HB=55566, SHELL=55563, CONTROL=55567, STDIN=55565, IOPUB=55564}, transport=tcp, signatureScheme=hmac-sha256, signatureKey=1582cece-18dea6798936efb8ba7c260d, scriptClasspath=[d:\lib\python\python37\lib\site-packages\run_kotlin_kernel\jars\Test-Kernel-1.0.jar], homeDir=null, debugPort=null, clientType=null, jvmTargetForSnippets=null) 491 [main] DEBUG SocketWrapper - [HB] listen: tcp://*:55566 503 [main] DEBUG SocketWrapper - [SHELL] listen: tcp://*:55563 511 [main] DEBUG SocketWrapper - [CONTROL] listen: tcp://*:55567 523 [main] DEBUG SocketWrapper - [STDIN] listen: tcp://*:55565 1044 [main] DEBUG SocketWrapper - [IOPUB] listen: tcp://*:55564 1090 [main] INFO ikotlin - Current classpath: D:\lib\Python\Python37\Lib\site-packages\run_kotlin_kernel\jars\Test-Kernel-1.0.jar 1091 [main] INFO ikotlin - Begin listening for events 1112 [main] INFO ikotlin - Detecting Jupyter client type 1253 [main] INFO ikotlin - Inspecting process: D:\lib\jdk-17\bin\java.exe 1254 [main] INFO ikotlin - Inspecting process: D:\lib\Python\Python37\python.exe 1255 [main] INFO ikotlin - Inspecting process: D:\lib\Python\Python37\python.exe 1256 [main] INFO ikotlin - Inspecting process: D:\lib\Python\Python37\Scripts\jupyter-lab.exe 1257 [main] INFO ikotlin - Detected type is JUPYTER_LAB 1357 [main] INFO ikotlin - Starting kotlin REPL engine. Compiler version: 1.8.20 1358 [main] INFO ikotlin - Kernel version: 0.11.0.385 1358 [main] INFO ikotlin - Classpath used in script: [d:\lib\python\python37\lib\site-packages\run_kotlin_kernel\jars\Test-Kernel-1.0.jar] |
按独立demo调整后错误消失,但我忘了为啥了,下一个错误是构造器初始化失败提示类型不匹配,还去github开了issue问
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
https://github.com/Kotlin/kotlin-jupyter/issues/433 argument type mismatch java.lang.IllegalArgumentException: argument type mismatch at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:77) at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:499) at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:480) at kotlin.script.experimental.jvm.BasicJvmScriptEvaluator.evalWithConfigAndOtherScriptsResults(BasicJvmScriptEvaluator.kt:105) at kotlin.script.experimental.jvm.BasicJvmScriptEvaluator.invoke$suspendImpl(BasicJvmScriptEvaluator.kt:47) at kotlin.script.experimental.jvm.BasicJvmScriptEvaluator.invoke(BasicJvmScriptEvaluator.kt) at kotlin.script.experimental.jvm.BasicJvmReplEvaluator.eval(BasicJvmReplEvaluator.kt:49) at org.jetbrains.kotlinx.jupyter.repl.impl.InternalEvaluatorImpl$eval$resultWithDiagnostics$1.invokeSuspend(InternalEvaluatorImpl.kt:103) at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33) at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106) at kotlinx.coroutines.EventLoopImplBase.processNextEvent(EventLoop.common.kt:284) at kotlinx.coroutines.BlockingCoroutine.joinBlocking(Builders.kt:85) at kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking(Builders.kt:59) at kotlinx.coroutines.BuildersKt.runBlocking(Unknown Source) at kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking$default(Builders.kt:38) at kotlinx.coroutines.BuildersKt.runBlocking$default(Unknown Source) at org.jetbrains.kotlinx.jupyter.repl.impl.InternalEvaluatorImpl.eval(InternalEvaluatorImpl.kt:103) at org.jetbrains.kotlinx.jupyter.repl.impl.CellExecutorImpl$execute$1$result$1.invoke(CellExecutorImpl.kt:75) at org.jetbrains.kotlinx.jupyter.repl.impl.CellExecutorImpl$execute$1$result$1.invoke(CellExecutorImpl.kt:73) at org.jetbrains.kotlinx.jupyter.ReplForJupyterImpl.withHost(repl.kt:666) at org.jetbrains.kotlinx.jupyter.repl.impl.CellExecutorImpl.execute(CellExecutorImpl.kt:73) at org.jetbrains.kotlinx.jupyter.repl.CellExecutor$DefaultImpls.execute$default(CellExecutor.kt:15) at org.jetbrains.kotlinx.jupyter.ReplForJupyterImpl$evalEx$1.invoke(repl.kt:479) at org.jetbrains.kotlinx.jupyter.ReplForJupyterImpl$evalEx$1.invoke(repl.kt:470) at org.jetbrains.kotlinx.jupyter.ReplForJupyterImpl.withEvalContext(repl.kt:433) at org.jetbrains.kotlinx.jupyter.ReplForJupyterImpl.evalEx(repl.kt:470) at org.jetbrains.kotlinx.jupyter.messaging.ProtocolKt$shellMessagesHandler$2$res$1.invoke(protocol.kt:318) at org.jetbrains.kotlinx.jupyter.messaging.ProtocolKt$shellMessagesHandler$2$res$1.invoke(protocol.kt:312) at org.jetbrains.kotlinx.jupyter.JupyterExecutorImpl$runExecution$execThread$1.invoke(execution.kt:37) at org.jetbrains.kotlinx.jupyter.JupyterExecutorImpl$runExecution$execThread$1.invoke(execution.kt:32) at kotlin.concurrent.ThreadsKt$thread$thread$1.run(Thread.kt:30) |
通过反复和demo对比,发现classLoader的继承关系不一样,虽然是相同的类但被不通的类加载器加载后实际是无法通用的
0 1 2 3 4 5 |
观测如下变量 Thread.currentThread().contextClassLoader org.jetbrains.kotlin.scripting.compiler.plugin.impl.CompiledScriptClassLoader@52e77672 args[1].getClass().classLoader PluginClassLoader(plugin=PluginDescriptor(name=Skykoma Plugin For IDEA, id=cn.hylstudio.skykoma.plugin.idea, descriptorPath=plugin.xml, path=D:\code\source\skykoma-plugin-idea\build\idea-sandbox\plugins\skykoma-plugin-idea, version=0.0.8, package=null, isBundled=false), packagePrefix=null, instanceId=54, state=active) |
构造测试脚本
0 1 2 3 4 5 6 7 |
import com.intellij.openapi.application.Application import com.intellij.openapi.application.ApplicationManager import com.intellij.openapi.ui.Messages.showInfoMessage val application = ApplicationManager.getApplication() application.invokeLater { showInfoMessage("1","test") } |
最后根据调整ide scripting console时候的经验,修改最初启动server入口独立Thread的classLoader为idea加载插件所用的classLoader即可解决问题
0 1 2 3 4 5 |
Thread thread = new Thread(() -> { embedKernel(xxxxx) }); thread.setContextClassLoader(pluginClassLoader); thread.start(); |
效果如下
在java11和下面的环境组合下测试,代码分支https://github.com/dev-assistant/skykoma-plugin-idea/tree/test-jupyter-java11
Unable to instantiate class Line_4_jupyter
0 1 2 3 4 5 6 7 8 9 10 |
IntelliJ IDEA 2021.2.3 (Community Edition) Build #IC-212.5457.46, built on October 12, 2021 Runtime version: 11.0.12+7-b1504.40 amd64 VM: OpenJDK 64-Bit Server VM by JetBrains s.r.o. GC: G1 Young Generation, G1 Old Generation Memory: 8192M Cores: 8 Non-Bundled Plugins: cn.hylstudio.skykoma.plugin.idea (0.0.8) Kotlin: 212-1.5.10-release-IJ5457.46 Current Desktop: Undefined |
目前在java17和下面环境组合下测试成功,代码分支https://github.com/dev-assistant/skykoma-plugin-idea/tree/test-jupyter-java17
0 1 2 3 4 5 6 7 8 9 10 11 12 |
IntelliJ IDEA 2022.2 (Community Edition) Build #IC-222.3345.118, built on July 26, 2022 Runtime version: 17.0.3+7-b469.32 amd64 VM: OpenJDK 64-Bit Server VM by JetBrains s.r.o. Windows 10 10.0 GC: G1 Young Generation, G1 Old Generation Memory: 2048M Cores: 16 Non-Bundled Plugins: cn.hylstudio.skykoma.plugin.idea (0.0.8) Kotlin: 222-1.7.10-release-334-IJ3345.118 |
0 1 2 3 4 5 6 7 8 9 10 11 12 |
IntelliJ IDEA 2022.3.2 (Community Edition) Build #IC-223.8617.56, built on January 26, 2023 Runtime version: 17.0.5+1-b653.25 amd64 VM: OpenJDK 64-Bit Server VM by JetBrains s.r.o. Windows 10 10.0 GC: G1 Young Generation, G1 Old Generation Memory: 750M Cores: 16 Non-Bundled Plugins: cn.hylstudio.skykoma.plugin.idea (0.0.8) Kotlin: 223-1.8.0-release-345-IJ8617.56 |
0 1 2 3 4 5 6 7 8 9 10 11 12 |
IntelliJ IDEA 2023.1.1 (Community Edition) Build #IC-231.8770.65, built on April 27, 2023 Runtime version: 17.0.6+10-b829.9 amd64 VM: OpenJDK 64-Bit Server VM by JetBrains s.r.o. Windows 10.0 GC: G1 Young Generation, G1 Old Generation Memory: 750M Cores: 8 Non-Bundled Plugins: cn.hylstudio.skykoma.plugin.idea (0.0.8) Kotlin: 231-1.8.21-IJ8770.65 |
3.5.livePlugin的实现方案//待调研
附录
JSR-223
https://www.jcp.org/en/jsr/detail?id=223
livePlugin
https://plugins.jetbrains.com/plugin/7282-liveplugin
https://saturncloud.io/blog/how-to-get-autocomplete-in-jupyter-notebook-without-using-tab/
https://browse.arxiv.org/pdf/2309.12499.pdf
0 Comments