dflib / jjava

A Jupyter kernel for Java notebooks
MIT License
18 stars 2 forks source link

Implement auto-loading of extensions #32

Closed m-dzianishchyts closed 3 months ago

m-dzianishchyts commented 3 months ago

About this PR:

Implements auto-loading according to #28 keeping all JJAVA_ script variables at place for now. Provides JJAVA_LOAD_EXTENSIONS env var that will disable auto-loading if defined and falsy.

Testing

Tested with DFLib using the next patch:

DFLib patch (outdated, see discussion) ```patch Subject: [PATCH] DFLib auto-bootstrap --- Index: dflib-jupyter/pom.xml IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== diff --git a/dflib-jupyter/pom.xml b/dflib-jupyter/pom.xml --- a/dflib-jupyter/pom.xml (revision 999f4df786c42bc2e00a2dbaaf6fd83a10f14dd3) +++ b/dflib-jupyter/pom.xml (date 1723804202101) @@ -47,6 +47,11 @@ ${project.version} + org.dflib + jjava + 1.0-SNAPSHOT + + org.slf4j slf4j-simple Index: dflib-jupyter/src/main/resources/META-INF/services/org.dflib.jjava.magics.PluginBootstrap IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== diff --git a/dflib-jupyter/src/main/resources/META-INF/services/org.dflib.jjava.magics.PluginBootstrap b/dflib-jupyter/src/main/resources/META-INF/services/org.dflib.jjava.magics.PluginBootstrap new file mode 100644 --- /dev/null (date 1723804946702) +++ b/dflib-jupyter/src/main/resources/META-INF/services/org.dflib.jjava.magics.PluginBootstrap (date 1723804946702) @@ -0,0 +1,1 @@ +org.dflib.jupyter.bootstrap.DFLibBootstrap Index: dflib-jupyter/src/main/java/org/dflib/jupyter/bootstrap/DFLibBootstrap.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== diff --git a/dflib-jupyter/src/main/java/org/dflib/jupyter/bootstrap/DFLibBootstrap.java b/dflib-jupyter/src/main/java/org/dflib/jupyter/bootstrap/DFLibBootstrap.java new file mode 100644 --- /dev/null (date 1723808907023) +++ b/dflib-jupyter/src/main/java/org/dflib/jupyter/bootstrap/DFLibBootstrap.java (date 1723808907023) @@ -0,0 +1,23 @@ +package org.dflib.jupyter.bootstrap; + +import org.dflib.jjava.magics.PluginBootstrap; + +import java.util.List; + +public class DFLibBootstrap implements PluginBootstrap { + + @Override + public List getImports() { + return List.of( + "org.dflib.jupyter.*", + "org.dflib.*" + ); + } + + @Override + public String getBootstrapScript() { + String script = PluginBootstrap.super.getBootstrapScript(); + script += "DFLibJupyter.init(getKernelInstance());\n"; + return script; + } +} ```
andrus commented 3 months ago

Great! This may become my new favorite feature. I haven't tested the implementation, but I sure have an opinion on naming and the public API 🙂 This was not defined in the original task, but now that we have the working code, I think we are ready to have this discussion.

  1. Maybe instead of talking about "bootstrap", we present this to the user as a process of "loading extensions"? I think it may be less confusing:
  1. PluginBootstrap / Extension API - I am unsure about the 3 separate methods. getBootstrapScript may be just enough for the extension authors.
  2. I suggest to make the extension API even more powerful by replacing getBootstrapScript with a callback method that is passed JavaKernel instance. So the extension would install itself. E.g.:
void install(JavaKernel kernel) { ... }
m-dzianishchyts commented 3 months ago

Applied requested changes. Here is updated DFLib patch that was used during testing:

DFLib patch ```patch Subject: [PATCH] DFLib auto-bootstrap --- Index: dflib-jupyter/pom.xml IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== diff --git a/dflib-jupyter/pom.xml b/dflib-jupyter/pom.xml --- a/dflib-jupyter/pom.xml (revision 999f4df786c42bc2e00a2dbaaf6fd83a10f14dd3) +++ b/dflib-jupyter/pom.xml (date 1723804202101) @@ -47,6 +47,11 @@ ${project.version} + org.dflib + jjava + 1.0-SNAPSHOT + + org.slf4j slf4j-simple Index: dflib-jupyter/src/main/resources/META-INF/services/org.dflib.jjava.Extension IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== diff --git a/dflib-jupyter/src/main/resources/META-INF/services/org.dflib.jjava.Extension b/dflib-jupyter/src/main/resources/META-INF/services/org.dflib.jjava.Extension new file mode 100644 --- /dev/null (date 1724068960243) +++ b/dflib-jupyter/src/main/resources/META-INF/services/org.dflib.jjava.Extension (date 1724068960243) @@ -0,0 +1,1 @@ +org.dflib.jupyter.bootstrap.DFLibExtension Index: dflib-jupyter/src/main/java/org/dflib/jupyter/bootstrap/DFLibExtension.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== diff --git a/dflib-jupyter/src/main/java/org/dflib/jupyter/bootstrap/DFLibExtension.java b/dflib-jupyter/src/main/java/org/dflib/jupyter/bootstrap/DFLibExtension.java new file mode 100644 --- /dev/null (date 1724068963666) +++ b/dflib-jupyter/src/main/java/org/dflib/jupyter/bootstrap/DFLibExtension.java (date 1724068963666) @@ -0,0 +1,20 @@ +package org.dflib.jupyter.bootstrap; + +import org.dflib.jjava.Extension; +import org.dflib.jjava.JavaKernel; + +public class DFLibExtension implements Extension { + + @Override + public void install(JavaKernel kernel) { + StringBuilder bootstrapScript = new StringBuilder(); + bootstrapScript.append("import org.dflib.jupyter.*;\n"); + bootstrapScript.append("import org.dflib.*;\n"); + bootstrapScript.append("DFLibJupyter.init(getKernelInstance());\n"); + try { + kernel.eval(bootstrapScript.toString()); + } catch (Exception e) { + throw new RuntimeException(e); + } + } +} ```