{"id":13675927,"url":"https://github.com/allen-ball/ganymede","last_synced_at":"2025-04-28T23:31:22.935Z","repository":{"id":45860725,"uuid":"353431324","full_name":"allen-ball/ganymede","owner":"allen-ball","description":"The Ganymede Kernel is a Jupyter Notebook Java kernel based on the Java Shell tool, JShell.","archived":false,"fork":false,"pushed_at":"2024-10-21T06:09:08.000Z","size":11992,"stargazers_count":61,"open_issues_count":9,"forks_count":3,"subscribers_count":4,"default_branch":"trunk","last_synced_at":"2024-10-21T08:56:30.477Z","etag":null,"topics":["java","jupyter-kernel","jupyter-notebook"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/allen-ball.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-03-31T17:04:15.000Z","updated_at":"2024-10-21T06:08:55.000Z","dependencies_parsed_at":"2024-01-14T14:31:27.828Z","dependency_job_id":"c79edbde-3158-42f3-a6fc-2d237c0a894f","html_url":"https://github.com/allen-ball/ganymede","commit_stats":null,"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/allen-ball%2Fganymede","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/allen-ball%2Fganymede/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/allen-ball%2Fganymede/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/allen-ball%2Fganymede/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/allen-ball","download_url":"https://codeload.github.com/allen-ball/ganymede/tar.gz/refs/heads/trunk","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":224137269,"owners_count":17261985,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["java","jupyter-kernel","jupyter-notebook"],"created_at":"2024-08-02T12:01:06.058Z","updated_at":"2024-11-11T16:31:02.436Z","avatar_url":"https://github.com/allen-ball.png","language":"Java","funding_links":[],"categories":["Active Java Kernels"],"sub_categories":[],"readme":"[![Ganymede](README/ganymede.png)](https://images.nasa.gov/details-GSFC_20171208_Archive_e002091)\n\n\nGanymede: Jupyter Notebook Java Kernel\n======================================\n\nThe [Ganymede Kernel] is a [Jupyter Notebook] Java [kernel][Jupyter Kernel].\nJava code is compiled and interpreted with the Java Shell tool, [JShell].\nThis kernel offers the following additional features:\n\n* Integrated Project Object Model (POM) for [Apache Maven] artifact\n  dependency resolution\u003csup id=\"ref1\"\u003e[1](#endnote1)\u003c/sup\u003e\n\n* Integrated support for [Structured Query Language] (SQL) through [JDBC]\n  and [jOOQ]\n\n* Integrated support for [JSR 223] scripting languages including:\n\n    * [Groovy]\n    * [Javascript]\u003csup id=\"ref2\"\u003e[2](#endnote2)\u003c/sup\u003e\n    * [Kotlin]\n\n* Templates (via any of [Thymeleaf], [Markdown] ([CommonMark]) with\n  [JMustache], [FreeMarker][Apache FreeMarker], and\n  [Velocity][Apache Velocity])\n\n* Support for [Apache Spark] and [Scala] binary distributions\n\n\n## Installation\n\nThe [Ganymede Kernel] is distributed as a single JAR\n([download here][Ganymede Kernel download]).\n\n\u003e :warning:\n\u003e Only [Jupyter Notebook] versions before 7 (`\u003c7`) are fully supported at this\n\u003e time.  See the `Pipfile` in [ganymede-notebooks] for a minimal Python\n\u003e configuration.\n\nJava 11 or later is required.  In addition to Java, the [Jupyter Notebook]\nmust be [installed][Jupyter Notebook Installation] first and the `jupyter`\nand `python` commands must be on the `${PATH}`.  Then the typical (and\nminimal) installation command line:\n\n```bash\n$ java -jar ganymede-2.1.2.20230910.jar -i\n```\n\nThe [kernel][Ganymede Kernel] will be configured to use the same `java`\ninstallation as invoked in the install command above.  These additional\ncommand line options are supported.\n\n| Option                               | Action                                                                                    | Default                                                  |\n| ---                                  | ---                                                                                       | ---                                                      |\n| --id-prefix=\u0026lt;prefix\u0026gt;           | Adds prefix to kernel ID                                                                  | \u0026lt;none\u0026gt;                                             |\n| --id=\u0026lt;id\u0026gt;                      | Specifies kernel ID                                                                       | `ganymede-${version}-java-${java.specification.version}` |\n| --id-suffix=\u0026lt;suffix\u0026gt;           | Adds suffix to kernel ID                                                                  | \u0026lt;none\u0026gt;                                             |\n| --display-name-prefix=\u0026lt;prefix\u0026gt; | Adds prefix to kernel display name                                                        | \u0026lt;none\u0026gt;                                             |\n| --display-name=\u0026lt;name\u0026gt;          | Specifies kernel display name                                                             | Ganymede `${version}` (Java `${java.specification.version}`) |\n| --display-name-suffix=\u0026lt;suffix\u0026gt; | Adds suffix to kernel display name                                                        | \u0026lt;none\u0026gt;                                             |\n| --env                                | Specify NAME=VALUE pair(s) to add to kernel environment                                   |                                                          |\n| --copy-jar=\u0026lt;boolean\u0026gt;           | Copies the [Ganymede Kernel] JAR to the `kernelspec` directory                            | true                                                     |\n| --sys-prefix\u003cbr/\u003eor --user           | Install in the system prefix or user path (see the `jupyter kernelspec install` command). | --user                                                   |\n\nThe following Java system properties may be configured.\n\n| System Properties | Action                                | Default(s)                                                                                                                          |\n|-------------------|---------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------|\n| maven.repo.local  | Configures the local Maven repository | \u003ctable\u003e\u003ctr\u003e\u003ctd\u003e--sys-prefix\u003c/td\u003e\u003ctd\u003e${jupyter.data}/repository/\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e--user\u003c/td\u003e\u003ctd\u003e${user.home}/.m2/\u003c/td\u003e\u003c/tr\u003e\u003c/table\u003e |\n\nThe following OS environment variables may be configured:\n\n| Environment Variable | Option                    | Action                                                                                |\n|----------------------|---------------------------|---------------------------------------------------------------------------------------|\n| SPARK_HOME           | --spark-home=\u0026lt;path\u0026gt; | If configured, the kernel will add the [Apache Spark] JARs to the kernel's classpath. |\n| HIVE_HOME            | --hive-home=\u0026lt;path\u0026gt;  | If configured, the kernel will add the [Apache Hive] JARs to the kernel's classpath.  |\n\nFor example, a sophisticated configuration to test a snapshot out of a\nuser's local [Maven][Apache Maven] repository:\n\n```bash\n$ export JAVA_HOME=$(/usr/libexec/java_home -v 11)\n$ ${JAVA_HOME}/bin/java \\\n      -jar ${HOME}/.m2/repository/ganymede/ganymede/2.2.0-SNAPSHOT/ganymede-2.2.0-SNAPSHOT.jar \\\n      -i --sys-prefix --copy-jar=false \\\n      --id-suffix=spark-3.3.4 --display-name-suffix=\"with Spark 3.3.4\" \\\n      --spark_home=/path/to/spark-home --hive_home=/path/to/hive-home\n$ jupyter kernelspec list\nAvailable kernels:\n...\n  ganymede-2.2.0-java-11-spark-3.3.4             /.../share/jupyter/kernels/ganymede-2.2.0-java-11-spark-3.3.4\n...\n```\n\nwould result in the configured\n`${jupyter.data}/kernels/ganymede-2.2.0-java-11-spark-3.3.4/kernel.json`\nkernelspec:\n\n```json\n{\n  \"argv\": [\n    \"/Library/Java/JavaVirtualMachines/graalvm-ce-java11-22.3.0/Contents/Home/bin/java\",\n    \"--add-opens\",\n    \"java.base/jdk.internal.misc=ALL-UNNAMED\",\n    \"--illegal-access=permit\",\n    \"-Djava.awt.headless=true\",\n    \"-Djdk.disableLastUsageTracking=true\",\n    \"-Dmaven.repo.local=/Users/ball/Notebooks/.venv/share/jupyter/repository\",\n    \"-jar\",\n    \"/Users/ball/.m2/repository/dev/hcf/ganymede/ganymede/2.2.0-SNAPSHOT/ganymede-2.2.0-SNAPSHOT.jar\",\n    \"-f\",\n    \"{connection_file}\"\n  ],\n  \"display_name\": \"Ganymede 2.2.0 (Java 11) with Spark 3.3.4\",\n  \"env\": {\n    \"JUPYTER_CONFIG_DIR\": \"/Users/ball/.jupyter\",\n    \"JUPYTER_CONFIG_PATH\": \"/Users/ball/.jupyter:/Users/ball/Notebooks/.venv/etc/jupyter:/usr/local/etc/jupyter:/etc/jupyter\",\n    \"JUPYTER_DATA_DIR\": \"/Users/ball/Library/Jupyter\",\n    \"JUPYTER_RUNTIME_DIR\": \"/Users/ball/Library/Jupyter/runtime\",\n    \"SPARK_HOME\": \"/path/to/spark-home\"\n  },\n  \"interrupt_mode\": \"message\",\n  \"language\": \"java\"\n}\n```\n\nThe [kernel][Ganymede Kernel] makes extensive use of templates and POM\nfragments.  While not strictly required, the authors suggest that the\n[Hide Input] extension is enabled so notebook authors can hide the input\ntemplates and POMs for any finished product.  This may be set from the\ncommand line with:\n\n```bash\n$ jupyter nbextension enable hide_input/main --sys-prefix\n```\n\n(or `--user` as appropriate).\n\n\n## Features and Usage\n\nThe following subsections outline many of the features of the\n[kernel][Ganymede Kernel].\n\n\n### Java\n\nThe Java REPL is [JShell] and has all the Java features of the installed\nJVM.  The minimum required Java version is 11 and subsequent versions are\nsupported.\n\nThe [JShell] environment includes builtin functions implemented through\nmethods that wrap the `public` methods defined in [NotebookContext] class\nannotated with [@NotebookFunction][NotebookFunction].  These functions\ninclude:\n\n| Method                                                                                                                    | Description                            |\n|---------------------------------------------------------------------------------------------------------------------------|----------------------------------------|\n| [print(Object)](https://allen-ball.github.io/ganymede/ganymede/notebook/NotebookContext.html#print(java.lang.Object))     | Render the Object to a Notebook format |\n| [display(Object)](https://allen-ball.github.io/ganymede/ganymede/notebook/NotebookContext.html#display(java.lang.Object)) | Render the Object to a Notebook format |\n| [asJson(Object)](https://allen-ball.github.io/ganymede/ganymede/notebook/NotebookContext.html#asJson(java.lang.Object))   | Convert argument to JsonNode           |\n| [asYaml(Object)](https://allen-ball.github.io/ganymede/ganymede/notebook/NotebookContext.html#asYaml(java.lang.Object))   | Convert argument to YAML (String)      |\n\nThe builtin functions are mostly concerned with \"printing\" or displaying\n(rendering) Objects to multimedia formats.  For example, `print(byte[])`\nwill render the byte array as an image.  Integrated renderers for chart and\nplot objects include:\n\n* [JFreeChart]\n\n* [Tablesaw] (wrapping [Plotly])\n\n* [XChart]\n\nThe [trig.ipynb] notebook demonstrates rendering of an [XChart].\n\nAs discussed in the next section, the magic identifier for java is `%%java`.\nA cell identified with `%%java` with no code will provide a table of variable\nbindings in the context with types and values.  The types are links to the\ncorresponding javadoc (if known).\n\n\u003cdiv\u003e\n  \u003ctable border=\"1\" class=\"bindings\"\u003e\n    \u003cthead\u003e\n      \u003ctr\u003e\u003cth\u003eName\u003c/th\u003e\u003cth\u003eType\u003c/th\u003e\u003cth\u003eValue\u003c/th\u003e\u003c/tr\u003e\n    \u003c/thead\u003e\n    \u003ctbody\u003e\n      \u003ctr\u003e\u003ctd\u003e$$\u003c/td\u003e\u003ctd\u003e\u003ca href=\"https://allen-ball.github.io/ganymede/ganymede/notebook/NotebookContext.html?is-external=true\" target=\"_newtab\"\u003e\u003ccode\u003eganymede.notebook.NotebookContext\u003c/code\u003e\u003c/a\u003e\u003c/td\u003e\u003ctd\u003eNotebookContext(super=ganymede.notebook.NotebookContext@af7e376)\u003c/td\u003e\u003c/tr\u003e\n      \u003ctr\u003e\u003ctd\u003eby_state\u003c/td\u003e\u003ctd\u003e\u003ca href=\"https://spark.apache.org/docs/latest/api/java/org/apache/spark/sql/Dataset.html?is-external=true\" target=\"_newtab\"\u003e\u003ccode\u003eorg.apache.spark.sql.Dataset\u0026lt;Row\u0026gt;\u003c/code\u003e\u003c/a\u003e\u003c/td\u003e\u003ctd\u003e[Country/Region: string, Province/State: string ... 1 more field]\u003c/td\u003e\u003c/tr\u003e\n      \u003ctr\u003e\u003ctd\u003echart\u003c/td\u003e\u003ctd\u003e\u003ca href=\"https://knowm.org/javadocs/xchart/org/knowm/xchart/PieChart.html?is-external=true\" target=\"_newtab\"\u003e\u003ccode\u003eorg.knowm.xchart.PieChart\u003c/code\u003e\u003c/a\u003e\u003c/td\u003e\u003ctd\u003eorg.knowm.xchart.PieChart@767f4a69\u003c/td\u003e\u003c/tr\u003e\n      \u003ctr\u003e\u003ctd\u003ecountries_aggregated\u003c/td\u003e\u003ctd\u003e\u003ca href=\"https://spark.apache.org/docs/latest/api/java/org/apache/spark/sql/Dataset.html?is-external=true\" target=\"_newtab\"\u003e\u003ccode\u003eorg.apache.spark.sql.Dataset\u0026lt;Row\u0026gt;\u003c/code\u003e\u003c/a\u003e\u003c/td\u003e\u003ctd\u003e[Date: date, Country: string ... 3 more fields]\u003c/td\u003e\u003c/tr\u003e\n      \u003ctr\u003e\u003ctd\u003edates\u003c/td\u003e\u003ctd\u003e\u003ca href=\"https://spark.apache.org/docs/latest/api/java/org/apache/spark/sql/Dataset.html?is-external=true\" target=\"_newtab\"\u003e\u003ccode\u003eorg.apache.spark.sql.Dataset\u0026lt;Row\u0026gt;\u003c/code\u003e\u003c/a\u003e\u003c/td\u003e\u003ctd\u003e[Date: date]\u003c/td\u003e\u003c/tr\u003e\n      \u003ctr\u003e\u003ctd\u003einterval\u003c/td\u003e\u003ctd\u003e\u003ca href=\"https://spark.apache.org/docs/latest/api/java/org/apache/spark/sql/Row.html?is-external=true\" target=\"_newtab\"\u003e\u003ccode\u003eorg.apache.spark.sql.Row\u003c/code\u003e\u003c/a\u003e\u003c/td\u003e\u003ctd\u003e[2020-01-22,2022-04-16]\u003c/td\u003e\u003c/tr\u003e\n      \u003ctr\u003e\u003ctd\u003ekey_countries_pivoted\u003c/td\u003e\u003ctd\u003e\u003ca href=\"https://spark.apache.org/docs/latest/api/java/org/apache/spark/sql/Dataset.html?is-external=true\" target=\"_newtab\"\u003e\u003ccode\u003eorg.apache.spark.sql.Dataset\u0026lt;Row\u0026gt;\u003c/code\u003e\u003c/a\u003e\u003c/td\u003e\u003ctd\u003e[Date: date, China: int ... 7 more fields]\u003c/td\u003e\u003c/tr\u003e\n      \u003ctr\u003e\u003ctd\u003ereader\u003c/td\u003e\u003ctd\u003e\u003ca href=\"https://spark.apache.org/docs/latest/api/java/org/apache/spark/sql/DataFrameReader.html?is-external=true\" target=\"_newtab\"\u003e\u003ccode\u003eorg.apache.spark.sql.DataFrameReader\u003c/code\u003e\u003c/a\u003e\u003c/td\u003e\u003ctd\u003eorg.apache.spark.sql.DataFrameReader@5a88849\u003c/td\u003e\u003c/tr\u003e\n      \u003ctr\u003e\u003ctd\u003ereference\u003c/td\u003e\u003ctd\u003e\u003ca href=\"https://spark.apache.org/docs/latest/api/java/org/apache/spark/sql/Dataset.html?is-external=true\" target=\"_newtab\"\u003e\u003ccode\u003eorg.apache.spark.sql.Dataset\u0026lt;Row\u0026gt;\u003c/code\u003e\u003c/a\u003e\u003c/td\u003e\u003ctd\u003e[UID: int, iso2: string ... 10 more fields]\u003c/td\u003e\u003c/tr\u003e\n      \u003ctr\u003e\u003ctd\u003esession\u003c/td\u003e\u003ctd\u003e\u003ca href=\"https://spark.apache.org/docs/latest/api/java/org/apache/spark/sql/SparkSession.html?is-external=true\" target=\"_newtab\"\u003e\u003ccode\u003eorg.apache.spark.sql.SparkSession\u003c/code\u003e\u003c/a\u003e\u003c/td\u003e\u003ctd\u003eorg.apache.spark.sql.SparkSession@1b6683c4\u003c/td\u003e\u003c/tr\u003e\n      \u003ctr\u003e\u003ctd\u003esnapshot\u003c/td\u003e\u003ctd\u003e\u003ca href=\"https://spark.apache.org/docs/latest/api/java/org/apache/spark/sql/Dataset.html?is-external=true\" target=\"_newtab\"\u003e\u003ccode\u003eorg.apache.spark.sql.Dataset\u0026lt;Row\u0026gt;\u003c/code\u003e\u003c/a\u003e\u003c/td\u003e\u003ctd\u003e[Country/Region: string, Deaths: int]\u003c/td\u003e\u003c/tr\u003e\n      \u003ctr\u003e\u003ctd\u003etime_series_19_covid_combined\u003c/td\u003e\u003ctd\u003e\u003ca href=\"https://spark.apache.org/docs/latest/api/java/org/apache/spark/sql/Dataset.html?is-external=true\" target=\"_newtab\"\u003e\u003ccode\u003eorg.apache.spark.sql.Dataset\u0026lt;Row\u0026gt;\u003c/code\u003e\u003c/a\u003e\u003c/td\u003e\u003ctd\u003e[Date: date, Country/Region: string ... 4 more fields]\u003c/td\u003e\u003c/tr\u003e\n      \u003ctr\u003e\u003ctd\u003eus_confirmed\u003c/td\u003e\u003ctd\u003e\u003ca href=\"https://spark.apache.org/docs/latest/api/java/org/apache/spark/sql/Dataset.html?is-external=true\" target=\"_newtab\"\u003e\u003ccode\u003eorg.apache.spark.sql.Dataset\u0026lt;Row\u0026gt;\u003c/code\u003e\u003c/a\u003e\u003c/td\u003e\u003ctd\u003e[Admin2: string, Date: date ... 3 more fields]\u003c/td\u003e\u003c/tr\u003e\n      \u003ctr\u003e\u003ctd\u003eus_deaths\u003c/td\u003e\u003ctd\u003e\u003ca href=\"https://spark.apache.org/docs/latest/api/java/org/apache/spark/sql/Dataset.html?is-external=true\" target=\"_newtab\"\u003e\u003ccode\u003eorg.apache.spark.sql.Dataset\u0026lt;Row\u0026gt;\u003c/code\u003e\u003c/a\u003e\u003c/td\u003e\u003ctd\u003e[Admin2: string, Date: date ... 3 more fields]\u003c/td\u003e\u003c/tr\u003e\n      \u003ctr\u003e\u003ctd\u003eus_simplified\u003c/td\u003e\u003ctd\u003e\u003ca href=\"https://spark.apache.org/docs/latest/api/java/org/apache/spark/sql/Dataset.html?is-external=true\" target=\"_newtab\"\u003e\u003ccode\u003eorg.apache.spark.sql.Dataset\u0026lt;Row\u0026gt;\u003c/code\u003e\u003c/a\u003e\u003c/td\u003e\u003ctd\u003e[Date: date, Admin2: string ... 4 more fields]\u003c/td\u003e\u003c/tr\u003e\n      \u003ctr\u003e\u003ctd\u003eworldwide_aggregate\u003c/td\u003e\u003ctd\u003e\u003ca href=\"https://spark.apache.org/docs/latest/api/java/org/apache/spark/sql/Dataset.html?is-external=true\" target=\"_newtab\"\u003e\u003ccode\u003eorg.apache.spark.sql.Dataset\u0026lt;Row\u0026gt;\u003c/code\u003e\u003c/a\u003e\u003c/td\u003e\u003ctd\u003e[Date: date, Confirmed: int ... 3 more fields]\u003c/td\u003e\u003c/tr\u003e\n    \u003c/tbody\u003e\n  \u003c/table\u003e\n\u003c/div\u003e\n\n\n### Magics\n\nCell magic commands are identified by `%%` starting the first line of a code\ncell.  The list of available magic commands is shown below.  The default\ncell magic is `java`.\n\n\u003cdiv\u003e\n  \u003ctable border=\"1\" class=\"magics\"\u003e\n    \u003cthead\u003e\n      \u003ctr\u003e\u003cth\u003eName(s)\u003c/th\u003e\u003cth\u003eDescription\u003c/th\u003e\u003c/tr\u003e\n    \u003c/thead\u003e\n    \u003ctbody\u003e\n      \u003ctr\u003e\n        \u003ctd\u003e!, script\u003c/td\u003e\n        \u003ctd\u003eExecute script with the argument command\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n        \u003ctd\u003ebash\u003c/td\u003e\n        \u003ctd\u003eExecute script with \u0026#39;bash\u0026#39; command\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n        \u003ctd\u003eclasspath\u003c/td\u003e\n        \u003ctd\u003eAdd to or print JShell classpath\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n        \u003ctd\u003eenv\u003c/td\u003e\n        \u003ctd\u003eAdd/Update or print the environment\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n        \u003ctd\u003efreemarker\u003c/td\u003e\n        \u003ctd\u003eFreeMarker template evaluator\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n        \u003ctd\u003egroovy\u003c/td\u003e\n        \u003ctd\u003eExecute code in groovy REPL\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n        \u003ctd\u003ehtml\u003c/td\u003e\n        \u003ctd\u003eHTML template evaluator\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n        \u003ctd\u003ejava\u003c/td\u003e\n        \u003ctd\u003eExecute code in Java REPL\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n        \u003ctd\u003ejavascript, js\u003c/td\u003e\n        \u003ctd\u003eExecute code in javascript REPL\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n        \u003ctd\u003ekotlin\u003c/td\u003e\n        \u003ctd\u003eExecute code in kotlin REPL\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n        \u003ctd\u003emagics\u003c/td\u003e\n        \u003ctd\u003eLists available cell magics\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n        \u003ctd\u003emarkdown\u003c/td\u003e\n        \u003ctd\u003eMarkdown template evaluator\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n        \u003ctd\u003emustache, handlebars\u003c/td\u003e\n        \u003ctd\u003eMustache template evaluator\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n        \u003ctd\u003eperl\u003c/td\u003e\n        \u003ctd\u003eExecute script with \u0026#39;perl\u0026#39; command\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n        \u003ctd\u003epom\u003c/td\u003e\n        \u003ctd\u003eDefine the Notebook\u0026#39;s Project Object Model\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n        \u003ctd\u003eruby\u003c/td\u003e\n        \u003ctd\u003eExecute script with \u0026#39;ruby\u0026#39; command\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n        \u003ctd\u003escala\u003c/td\u003e\n        \u003ctd\u003eExecute code in scala REPL\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n        \u003ctd\u003esh\u003c/td\u003e\n        \u003ctd\u003eExecute script with \u0026#39;sh\u0026#39; command\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n        \u003ctd\u003espark-session\u003c/td\u003e\n        \u003ctd\u003eConfigure and start a Spark session\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n        \u003ctd\u003esql\u003c/td\u003e\n        \u003ctd\u003eExecute code in SQL REPL\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n        \u003ctd\u003ethymeleaf\u003c/td\u003e\n        \u003ctd\u003eThymeleaf template evaluator\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n        \u003ctd\u003evelocity\u003c/td\u003e\n        \u003ctd\u003eVelocity template evaluator\u003c/td\u003e\n      \u003c/tr\u003e\n    \u003c/tbody\u003e\n  \u003c/table\u003e\n\u003c/div\u003e\n\n`script`, `bash`, `perl`, etc. are executed by creating a [Process]\ninstance.  [`groovy`][Groovy], [`javascript`][Javascript],\n[`kotlin`][Kotlin], etc. are provided through their respective [JSR 223]\ninterfaces.\u003csup id=\"ref3\"\u003e[3](#endnote3)\u003c/sup\u003e  Dependency and classpath\nmanagement are provided with the `classpath` and `pom` magics and are\ndescribed in detail in a subsequent subsection.  `thymeleaf` and `html`\nprovide [Thymeleaf] template evaluation.\n\nThe [kernel][Ganymede Kernel] does not implement any \"line\" magics.\n\n\n### Dependency and Classpath Management\n\nThe `classpath` magic adds JAR and directory paths to the [JShell]\nclasspath.  The `pom` magic resolves and downloads [Maven][Apache Maven]\nartifacts and then adds those artifacts to the classpath.\n\nThe [trig.ipynb] notebook demonstrates the use of the `pom` magic to resolve\nthe `org.knowm.xchart:xchart:LATEST` artifact and its transient dependencies.\n\n```yaml\n%%pom\ndependencies:\n- org.knowm.xchart:xchart:LATEST\n```\n\nThe POM is expressed in [YAML] and repositories and dependencies may be\nexpressed.  The Notebook's POM may be split across multiple cells since each\nrepository and dependency is added or merged and dependency resolution is\nattempted whenever a `pom` cell is executed.  The default/initial Notebook\nPOM is:\n\n```yaml\nrepositories:\n  - id: central\n    layout: default\n    url: https://repo1.maven.org/maven2\n    snapshots:\n      enabled: false\n```\n\nDependencies may either be expressed in \"expanded\" YAML or in\n`groupId:artifactId[:extension]:version` format:\n\n```yaml\ndependencies:\n  - groupId: groupA\n    artifactId: groupAartifact1\n    version: 1.0\n  - groupB:groupB-artifact2:2.0\n```\n\nThe specific attributes for repositories and dependencies are defined by the\n[Apache Maven Artifact Resolver] classes [RemoteRepository] (with\n[RepositoryPolicy]) and [Dependency].  (Note that these classes are slightly\ndifferent than their [Maven][Apache Maven] settings counterparts.)\n\nWhenever a JAR is added to the classpath, it is analyzed to determine if its\n[Maven coordinates] can be determined and, if they can be determined, the\nJAR is added as an artifact to the\n[resolver][Apache Maven Artifact Resolver].  The following checks are made\nbefore adding the JAR to the [JShell] classpath:\n\n1. It is a new, unique path\n\n2. No previously resolved artifact with the same `groupId:artifactId` on the\n   classpath\n\n3. Special heuristics for logging configuration:\n\n    a. Ignore `commons-logging:commons-logging:jar`\n\n    b. Allow only one of `org.slf4j:jcl-over-slf4j:jar` or\n    `org.springframework:spring-jcl:jar` to be configured\n\n    c. Allow only one of `org.slf4j:slf4j-log4j12:jar` and\n    `ch.qos.logback:logback-classic:jar` to be configured\n\nArtifacts that fail any of the above checks will be (mostly silently)\nignored.  Because only the first version of a resolved artifact is ever\nadded to the classpath, the [kernel][Ganymede Kernel] must be restarted if a\ndifferent version of the same artifact is specified for the change to take\neffect.\n\nFinally, the [kernel][Ganymede Kernel] provides special processing to add\nartifacts from [Apache Spark] binary distributions.  The dependencies for\n[Spark SQL][Apache Spark SQL] and corresponding [Scala] compiler artifacts\nfor currently available Spark binary distributions as resources.  The kernel\nsearches the `${SPARK_HOME}` for JARs for which it has the corresponding\ndependencies and then resolves the dependencies from the `${SPARK_HOME}`\nhierarchy with the heuristics described above.\n\n\n### SQL\n\nThe [SQL] [Magic] provides the client interface to database servers through\n[JDBC] and [jOOQ].  Its usage is as follows:\n\n```\n    Usage: sql [--[no-]print] [\u003curl\u003e] [\u003cusername\u003e] [\u003cpassword\u003e]\n          [\u003curl\u003e]        JDBC Connection URL\n          [\u003cusername\u003e]   JDBC Connection Username\n          [\u003cpassword\u003e]   JDBC Connection Password\n          --[no-]print   Print query results.  true by default\n```\n\nFor example:\n\n```sql\n%%sql jdbc:mysql://127.0.0.1:33061/epg?serverTimezone=UTC\nSELECT * FROM schedules LIMIT 3;\n```\n\n\u003ctable\u003e\u003cthead\u003e\u003ctr\u003e\u003cth\u003eairDateTime\u003c/th\u003e\u003cth\u003estationID\u003c/th\u003e\u003cth\u003ejson\u003c/th\u003e\u003cth\u003eduration\u003c/th\u003e\u003cth\u003emd5\u003c/th\u003e\u003cth\u003eprogramID\u003c/th\u003e\u003c/tr\u003e\u003c/thead\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd\u003e1533945600\u003c/td\u003e\u003ctd\u003e10139\u003c/td\u003e\u003ctd\u003e{\n  \u0026quot;programID\u0026quot; : \u0026quot;EP009370080215\u0026quot;,\n  \u0026quot;airDateTime\u0026quot; : \u0026quot;2018-08-11T00:00:00Z\u0026quot;,\n  \u0026quot;duration\u0026quot; : 3600,\n  \u0026quot;md5\u0026quot; : \u0026quot;S1UDH1R60Eagc1E3V5Qslw\u0026quot;,\n  \u0026quot;audioProperties\u0026quot; : [ \u0026quot;cc\u0026quot; ],\n  \u0026quot;ratings\u0026quot; : [ {\n    \u0026quot;body\u0026quot; : \u0026quot;USA Parental Rating\u0026quot;,\n    \u0026quot;code\u0026quot; : \u0026quot;TVPG\u0026quot;\n  } ]\n}\u003c/td\u003e\u003ctd\u003e3600\u003c/td\u003e\u003ctd\u003eS1UDH1R60Eagc1E3V5Qslw\u003c/td\u003e\u003ctd\u003eEP009370080215\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e1533945600\u003c/td\u003e\u003ctd\u003e10142\u003c/td\u003e\u003ctd\u003e{\n  \u0026quot;programID\u0026quot; : \u0026quot;EP006062993248\u0026quot;,\n  \u0026quot;airDateTime\u0026quot; : \u0026quot;2018-08-11T00:00:00Z\u0026quot;,\n  \u0026quot;duration\u0026quot; : 3600,\n  \u0026quot;md5\u0026quot; : \u0026quot;2FQ8y5PsXl1vtxcmUBeppg\u0026quot;,\n  \u0026quot;new\u0026quot; : true,\n  \u0026quot;audioProperties\u0026quot; : [ \u0026quot;cc\u0026quot; ],\n  \u0026quot;ratings\u0026quot; : [ {\n    \u0026quot;body\u0026quot; : \u0026quot;USA Parental Rating\u0026quot;,\n    \u0026quot;code\u0026quot; : \u0026quot;TVPG\u0026quot;\n  } ]\n}\u003c/td\u003e\u003ctd\u003e3600\u003c/td\u003e\u003ctd\u003e2FQ8y5PsXl1vtxcmUBeppg\u003c/td\u003e\u003ctd\u003eEP006062993248\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e1533945600\u003c/td\u003e\u003ctd\u003e10145\u003c/td\u003e\u003ctd\u003e{\n  \u0026quot;programID\u0026quot; : \u0026quot;EP022439260394\u0026quot;,\n  \u0026quot;airDateTime\u0026quot; : \u0026quot;2018-08-11T00:00:00Z\u0026quot;,\n  \u0026quot;duration\u0026quot; : 1800,\n  \u0026quot;md5\u0026quot; : \u0026quot;mUewfiqM8+dh24WQg2WfpQ\u0026quot;,\n  \u0026quot;audioProperties\u0026quot; : [ \u0026quot;cc\u0026quot; ]\n}\u003c/td\u003e\u003ctd\u003e1800\u003c/td\u003e\u003ctd\u003emUewfiqM8+dh24WQg2WfpQ\u003c/td\u003e\u003ctd\u003eEP022439260394\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\n\nThe [SQL] [Magic] accepts the `--print`/`--no-print` options to print or\nsuppress query results.  If no JDBC URL is specified, the most recently used\nconnection will be used.  The [List] of most recent [jOOQ] [Queries][Query]\nare stored in [$$.sql.queries][NotebookContext.SQL.queries] with\n[$$.sql.results][NotebookContext.SQL.results] containing the corresponding\n[Result]s.  For example:\n\n```sql\n%%sql --no-print\nSELECT COUNT(*) FROM programs;\n```\n\n```java\n%%java\nprint($$.sql.results.get(0));\n```\n\n\u003ctable\u003e\n  \u003cthead\u003e\u003ctr\u003e\u003cth\u003ecount(*)\u003c/th\u003e\u003c/tr\u003e\u003c/thead\u003e\n  \u003ctbody\u003e\u003ctr\u003e\u003ctd\u003e1024495\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\n\u003c/table\u003e\n\n[MySQL][MySQL Connectors] and [PostgreSQL][PostgreSQL JDBC Driver] [JDBC]\ndrivers are provided in the [Ganymede][Ganymede Kernel] runtime.\n\n\n### Spark\n\nThe `spark-session` magic is provided to initialize [Apache Spark]\n[sessions][SparkSession].\n\n```\n    Usage: spark-session [--[no-]enable-hive-if-available] [\u003cmaster\u003e] [\u003cappName\u003e]\n          [\u003cmaster\u003e]    Spark master\n          [\u003cappName\u003e]   Spark appName\n          --[no-]enable-hive-if-available\n                        Enable Hive if available.  true by default\n```\n\nIts typical usage:\n\n```\n%%spark-session local[*] covid-19\n# Optional name/value pairs parsed as Properties\n```\n\nis roughly equivalent to:\n\n```java\nvar config = new SparkConf();\n/*\n * Properties copied to SparkConf instance.\n */\nvar session =\n    SparkSession.builder()\n    .config(config)\n    .master(\"local\").appName(\"covid-19\")\n    .getOrCreate();\n```\n\nThe [SparkSession] can then be accessed in Java and other JVM code with the\n[SparkSession.active()] static method.\n\n\n### Other Laguages ([JSR 223])\n\nThe [kernel][Ganymede Kernel] leverages the [java.scripting API] to provide\n[`groovy`][Groovy], [`javascript`][Javascript], [`kotlin`][Kotlin], and\n[`scala`][Scala].\u003csup id=\"ref4\"\u003e[4](#endnote4)\u003c/sup\u003e\n\n\n### Shells\n\nThe `script` magic (with the alias `!`) may be used to run an operating\nsystem command with the remaining code in the cell fed to the [Process]'s\nstandard input.  `bash`, `perl`, `ruby`, and `sh` are provided as aliases\nfor `%%!bash`, `%%!perl`, etc., respectively.\n\n\n### Templates\n\nA number of templating languages are supported as magics:\n\n* [Markdown] ([CommonMark] preprocessed with [JMustache])\n* [Apache FreeMarker]\n* [Apache Velocity]\n* [JMustache]\n* [Thymeleaf]\n\nThe following subsections provide examples of the `markdown` and `thymeleaf`\nmagics but the other template magics are similar.  Please refer to the\ninstallation instructions for discussion of enabling the [Hide Input]\nextension so only the template output is displayed in the notebook.\n\n\n### Markdown and JMustache\n\nThe template magic `markdown` provides [Markdown] processing with [JMustache]\npreprocessing:\n\n```java\n%%java\nimport java.util.stream.Stream;\n\nimport static java.util.stream.Collectors.toList;\n\nvar fib =\n    Stream.iterate(new int[] { 0, 1 }, t -\u003e new int[] { t[1], t[0] + t[1] })\n    .mapToInt(t -\u003e t[0])\n    .limit(10)\n    .boxed()\n    .collect(toList());\n```\n\n\n```java\n%%markdown\n| Index | Value |\n| --- | --- |\n{{#fib}}| {{-index}} | {{this}} |\n{{/fib}}\n```\n\n\u003ctable\u003e\n  \u003cthead\u003e\n    \u003ctr\u003e\u003cth\u003eIndex\u003c/th\u003e\u003cth\u003eValue\u003c/th\u003e\u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n    \u003ctr\u003e\u003ctd\u003e0\u003c/td\u003e\u003ctd\u003e0\u003c/td\u003e\u003c/tr\u003e\n    \u003ctr\u003e\u003ctd\u003e1\u003c/td\u003e\u003ctd\u003e1\u003c/td\u003e\u003c/tr\u003e\n    \u003ctr\u003e\u003ctd\u003e2\u003c/td\u003e\u003ctd\u003e1\u003c/td\u003e\u003c/tr\u003e\n    \u003ctr\u003e\u003ctd\u003e3\u003c/td\u003e\u003ctd\u003e2\u003c/td\u003e\u003c/tr\u003e\n    \u003ctr\u003e\u003ctd\u003e4\u003c/td\u003e\u003ctd\u003e3\u003c/td\u003e\u003c/tr\u003e\n    \u003ctr\u003e\u003ctd\u003e5\u003c/td\u003e\u003ctd\u003e5\u003c/td\u003e\u003c/tr\u003e\n    \u003ctr\u003e\u003ctd\u003e6\u003c/td\u003e\u003ctd\u003e8\u003c/td\u003e\u003c/tr\u003e\n    \u003ctr\u003e\u003ctd\u003e7\u003c/td\u003e\u003ctd\u003e13\u003c/td\u003e\u003c/tr\u003e\n    \u003ctr\u003e\u003ctd\u003e8\u003c/td\u003e\u003ctd\u003e21\u003c/td\u003e\u003c/tr\u003e\n    \u003ctr\u003e\u003ctd\u003e9\u003c/td\u003e\u003ctd\u003e34\u003c/td\u003e\u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\n\n#### Thymeleaf\n\nThe template magics `thymeleaf` and `html` offer templating with\n[Thymeleaf].  All defined Java variables are bound into the Thymeleaf\ncontext before evaluation.  For example (Java implementation detail\nremoved):\n\n```java\n%%java\n...\nvar map = new TreeMap\u003cRanking,List\u003cCard\u003e\u003e(Ranking.COMPARATOR.reversed());\n...\nvar rankings = Arrays.asList(Ranking.values());\n...\n```\n\n```html\n%%html\n\u003ctable\u003e\n  \u003ctr th:each=\"ranking : ${rankings}\"\u003e\n    \u003cth:block th:if=\"${map.containsKey(ranking)}\"\u003e\n      \u003cth th:text=\"${ranking}\"/\u003e\u003ctd th:each=\"card : ${map.get(ranking)}\" th:text=\"${card}\"/\u003e\n    \u003c/th:block\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\u003cth\u003eRemaining\u003c/th\u003e\u003ctd th:each=\"card : ${deck}\" th:text=\"${card}\"/\u003e\u003c/tr\u003e\n\u003c/table\u003e\n```\n\nWould generate:\n\n\u003ctable\u003e\n  \u003ctr\u003e\n    \u003cth\u003eRoyalFlush\u003c/th\u003e\u003ctd\u003eA-♤\u003c/td\u003e\u003ctd\u003eK-♤\u003c/td\u003e\u003ctd\u003eQ-♤\u003c/td\u003e\u003ctd\u003eJ-♤\u003c/td\u003e\u003ctd\u003e10-♤\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003cth\u003eStraightFlush\u003c/th\u003e\u003ctd\u003eK-♡\u003c/td\u003e\u003ctd\u003eQ-♡\u003c/td\u003e\u003ctd\u003eJ-♡\u003c/td\u003e\u003ctd\u003e10-♡\u003c/td\u003e\u003ctd\u003e9-♡\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003cth\u003eFourOfAKind\u003c/th\u003e\u003ctd\u003e8-♤\u003c/td\u003e\u003ctd\u003e8-♡\u003c/td\u003e\u003ctd\u003e8-♢\u003c/td\u003e\u003ctd\u003e8-♧\u003c/td\u003e\u003ctd\u003e2-♧\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003cth\u003eFullHouse\u003c/th\u003e\u003ctd\u003eA-♡\u003c/td\u003e\u003ctd\u003eA-♢\u003c/td\u003e\u003ctd\u003eA-♧\u003c/td\u003e\u003ctd\u003eK-♢\u003c/td\u003e\u003ctd\u003eK-♧\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003cth\u003eFlush\u003c/th\u003e\u003ctd\u003eQ-♢\u003c/td\u003e\u003ctd\u003eJ-♢\u003c/td\u003e\u003ctd\u003e10-♢\u003c/td\u003e\u003ctd\u003e9-♢\u003c/td\u003e\u003ctd\u003e7-♢\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003cth\u003eStraight\u003c/th\u003e\u003ctd\u003e7-♤\u003c/td\u003e\u003ctd\u003e6-♤\u003c/td\u003e\u003ctd\u003e5-♤\u003c/td\u003e\u003ctd\u003e4-♤\u003c/td\u003e\u003ctd\u003e3-♤\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003cth\u003eThreeOfAKind\u003c/th\u003e\u003ctd\u003e6-♡\u003c/td\u003e\u003ctd\u003e6-♢\u003c/td\u003e\u003ctd\u003e6-♧\u003c/td\u003e\u003ctd\u003e3-♧\u003c/td\u003e\u003ctd\u003e4-♧\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003cth\u003eTwoPair\u003c/th\u003e\u003ctd\u003e9-♤\u003c/td\u003e\u003ctd\u003e9-♧\u003c/td\u003e\u003ctd\u003e7-♡\u003c/td\u003e\u003ctd\u003e7-♧\u003c/td\u003e\u003ctd\u003e5-♧\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003cth\u003ePair\u003c/th\u003e\u003ctd\u003e5-♡\u003c/td\u003e\u003ctd\u003e5-♢\u003c/td\u003e\u003ctd\u003e10-♧\u003c/td\u003e\u003ctd\u003eJ-♧\u003c/td\u003e\u003ctd\u003e2-♢\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003cth\u003eHighCard\u003c/th\u003e\u003ctd\u003eQ-♧\u003c/td\u003e\u003ctd\u003e3-♢\u003c/td\u003e\u003ctd\u003e4-♢\u003c/td\u003e\u003ctd\u003e2-♡\u003c/td\u003e\u003ctd\u003e3-♡\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\u003cth\u003eRemaining\u003c/th\u003e\u003ctd\u003e4-♡\u003c/td\u003e\u003ctd\u003e2-♤\u003c/td\u003e\u003c/tr\u003e\n\u003c/table\u003e\n\n\n## Documentation\n\n[Javadoc][Ganymede API Javadoc] is published at\n\u003chttps://allen-ball.github.io/ganymede\u003e.\n\n\n## License\n\n[Ganymede Kernel] is released under the\n[Apache License, Version 2.0, January 2004].\n\n\n## Endnotes\n\n\u003cb id=\"endnote1\"\u003e[1]\u003c/b\u003e\nImplemented with [Apache Maven Artifact Resolver].\n[↩](#ref1)\n\n\u003cb id=\"endnote2\"\u003e[2]\u003c/b\u003e\nWith the built-in Oracle Nashorn engine.\n[↩](#ref2)\n\n\u003cb id=\"endnote3\"\u003e[3]\u003c/b\u003e\n[`scala`][Scala] is special cased: It requires additional dependencies be\nspecified at runtime and is optimized to be used with [Apache Spark].\n[↩](#ref3)\n\n\u003cb id=\"endnote4\"\u003e[4]\u003c/b\u003e\nIbid.\n[↩](#ref4)\n\n\n[Ganymede Kernel]: https://github.com/allen-ball/ganymede\n[Ganymede Kernel download]: https://github.com/allen-ball/ganymede/releases/download/v2.1.2.20230910/ganymede-2.1.2.20230910.jar\n[Ganymede API Javadoc]: https://allen-ball.github.io/ganymede/index.html?overview-summary.html\n[Magic]: https://allen-ball.github.io/ganymede/ganymede/shell/Magic.html\n[NotebookContext]: https://allen-ball.github.io/ganymede/ganymede/notebook/NotebookContext.html\n[NotebookContext.SQL]: https://allen-ball.github.io/ganymede/ganymede/notebook/NotebookContext.SQL.html\n[NotebookContext.SQL.queries]: https://allen-ball.github.io/ganymede/ganymede/notebook/NotebookContext.SQL.html#queries\n[NotebookContext.SQL.results]: https://allen-ball.github.io/ganymede/ganymede/notebook/NotebookContext.SQL.html#results\n[NotebookFunction]: https://allen-ball.github.io/ganymede/ganymede/notebook/NotebookFunction.html\n[SQL]: https://allen-ball.github.io/ganymede/ganymede/shell/magic/SQL.html\n\n[ganymede-notebooks]: https://github.com/allen-ball/ganymede-notebooks\n[trig.ipynb]: https://github.com/allen-ball/ganymede-notebooks/blob/trunk/trig.ipynb\n\n[Apache License, Version 2.0, January 2004]: https://www.apache.org/licenses/LICENSE-2.0\n\n[Apache FreeMarker]: https://freemarker.apache.org/\n\n[Apache Hive]: https://hive.apache.org/\n\n[Apache Maven]: https://maven.apache.org/\n[Maven coordinates]: https://maven.apache.org/pom.html#Maven_Coordinates\n\n[Apache Maven Artifact Resolver]: https://maven.apache.org/resolver/index.html\n[RemoteRepository]: https://maven.apache.org/resolver/maven-resolver-api/apidocs/org/eclipse/aether/repository/RemoteRepository.html?is-external=true\n[RepositoryPolicy]: https://maven.apache.org/resolver/maven-resolver-api/apidocs/org/eclipse/aether/repository/RepositoryPolicy.html\n[Dependency]: https://maven.apache.org/resolver/maven-resolver-api/apidocs/org/eclipse/aether/graph/Dependency.html?is-external=true\n\n[Apache Spark]: http://spark.apache.org/\n[Apache Spark SQL]: https://spark.apache.org/sql/\n[SparkSession]: https://spark.apache.org/docs/latest/api/java/org/apache/spark/sql/SparkSession.html\n[SparkSession.active()]: https://spark.apache.org/docs/latest/api/java/org/apache/spark/sql/SparkSession.html#active--\n\n[Apache Velocity]: https://velocity.apache.org/\n\n[Groovy]: https://groovy-lang.org/\n\n[Java API]: https://docs.oracle.com/en/java/javase/11/docs/api\n[JShell]: https://docs.oracle.com/en/java/javase/11/docs/api/jdk.jshell/jdk/jshell/JShell.html?is-external=true\n[List]: https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/List.html?is-external=true\n[Process]: https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/Process.html\n\n[Javascript]: https://www.oracle.com/technical-resources/articles/java/jf14-nashorn.html\n\n[JDBC]: https://docs.oracle.com/javase/8/docs/technotes/guides/jdbc/\n\n[JFreeChart]: https://github.com/jfree/jfreechart\n\n[JMustache]: https://github.com/samskivert/jmustache\n\n[jOOQ]: https://www.jooq.org/doc/latest/manual\n[Query]: https://www.jooq.org/javadoc/latest/org.jooq/org/jooq/Query.html?is-external=true\n[Result]: https://www.jooq.org/javadoc/latest/org.jooq/org/jooq/Result.html?is-external=true\n\n[JSR 223]: https://jcp.org/en/jsr/detail?id=223\n[java.scripting API]: https://docs.oracle.com/en/java/javase/11/docs/api/java.scripting/module-summary.html\n\n[Jupyter Notebook]: https://jupyter-notebook.readthedocs.io/en/stable/index.html\n[Jupyter Notebook Installation]: https://jupyter.readthedocs.io/en/latest/install/notebook-classic.html\n[Hide Input]: https://jupyter-contrib-nbextensions.readthedocs.io/en/latest/nbextensions/hide_input/readme.html\n\n[Jupyter Kernel]: https://jupyter-client.readthedocs.io/en/stable/kernels.html\n\n[Kotlin]: https://kotlinlang.org/\n\n[Markdown]: https://en.wikipedia.org/wiki/Markdown\n[CommonMark]: https://commonmark.org/\n\n[MySQL Connectors]: https://www.mysql.com/products/connector/\n\n[Plotly]: https://github.com/plotly\n\n[PostgreSQL JDBC Driver]: https://jdbc.postgresql.org/\n\n[Scala]: https://www.scala-lang.org/\n\n[Structured Query Language]: https://en.wikipedia.org/wiki/SQL\n\n[Tablesaw]: https://github.com/jfree/jfreechart\n\n[Thymeleaf]: https://www.thymeleaf.org/index.html\n\n[XChart]: https://github.com/knowm/XChart\n\n[YAML]: https://yaml.org/\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fallen-ball%2Fganymede","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fallen-ball%2Fganymede","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fallen-ball%2Fganymede/lists"}