{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Manipulating the Java Classpath and Imports\n", "\n", "The magic `%classpath` adds jars to the kernel. The magics `%import` and `%unimport` control which classes are visible by default in your code (in Groovy the regular `import` command is local to the cell where it runs.\n", "\n", "These magics work in all the BeakerX JVM kernels.\n", "\n", "## Example\n", "\n", "This first cell shows that you get an error if you try to import a class not built-in to BeakerX:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import com.example.Demo" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Then load a jar into the kernel:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "%classpath add jar ../resources/jar/demo.jar" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "After that, it imports and runs:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import com.example.Demo\n", "Demo demo = new Demo();\n", "println demo.getObjectTest()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You can add multiple jars. Wildcards also work, like they normally do in the classpath (in this case the code could say `../resources/jar/*`)." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "%classpath add jar ../resources/jar/demo.jar\n", "%classpath add jar ../resources/jar/BeakerXClasspathTest.jar\n", "\n", "println com.example.Demo.staticTest();\n", "\n", "import com.example.Demo\n", "\n", "Demo demo = new Demo();\n", "println demo.getObjectTest()\n", "\n", "import com.beaker.BeakerXClasspathTest\n", "BeakerXClasspathTest t = new BeakerXClasspathTest();\n", "println com.beaker.BeakerXClasspathTest.staticTest;\n", "println t.getObjectTest();\n", "OutputCell.HIDDEN" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The source code for these jars is in the repository. See [Demo.java](https://github.com/twosigma/beakerx/blob/master/kernel/demoProjects/demo/src/main/java/com/example/Demo.java), and [BeakerXClasspathTest.java](https://github.com/twosigma/beakerx/blob/master/kernel/demoProjects/BeakerXClasspathTest/src/main/java/com/beaker/BeakerXClasspathTest.java)\n", "\n", "With no arguments the classpath magic prints-out all loaded jars:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "%classpath" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Loading a Single Dependency with Grapes and Maven\n", "\n", "Groovy has a dependency manager called [Grape](http://docs.groovy-lang.org/latest/html/documentation/grape.html) built-in and you can access it as follows:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "@Grab(group='com.google.code.gson', module='gson', version='2.2.4')\n", "import com.google.gson.GsonBuilder\n", "new GsonBuilder().create().toJson([grab:[]], System.out)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The `%classpath` magic also supports loading from [maven central](https://search.maven.org):" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "%classpath add mvn com.google.code.gson gson 2.2.4\n", "new com.google.gson.GsonBuilder().create().toJson([magic:[]], System.out)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You can also use gradle-like syntax to load dependencies:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "%classpath add mvn com.sun.jersey:jersey-core:1.19.4\n", "import com.sun.jersey.api.uri.UriBuilderImpl\n", "return new UriBuilderImpl()\n", " .path(\"http://beakerx.com/\")\n", " .path(\"documentation\")\n", " .build();" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## POM-Type Dependencies\n", "\n", "Most dependencies are JARs, but a few such as [Jena are POMs](https://jena.apache.org/download/maven.html). They can be loaded like this:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "%classpath add mvn org.apache.jena apache-jena-libs 3.6.0 pom\n", "model = org.apache.jena.rdf.model.ModelFactory.createDefaultModel()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## POM-Classifier Dependencies" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "%classpath add mvn org.platanios tensorflow_2.11 0.1.1 jar linux-cpu-x86_64\n", "import org.platanios.tensorflow.api.core.Shape\n", "Shape.matrix(2,5)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Custom Repository\n", "\n", "The `%classpath config resolver` gives you able to define custom repository:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "%classpath config resolver repository.spring.snapshot http://repo.spring.io/snapshot" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "%classpath add mvn org.springframework spring-context 5.0.3.BUILD-SNAPSHOT" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Loading Multiple Dependencies with Maven\n", "\n", "Use the `%%classpath` cell magic to load multiple dependencies at once. This magic creates a POM file containing all the dependencies listed in the cell, solves them together with Maven, and adds the result to the classpath." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "%%classpath add mvn\n", "org.slf4j slf4j-api 1.7.25\n", "org.slf4j slf4j-nop 1.7.25" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Loading Jars from a Dynamic Location\n", "\n", "The above magics work on literal strings. If you need to compute the location of a jar, use the dynamic classpath magic. It has two versions one that works with a single string, and another that takes a list of strings:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "location = \"../resources/jar/\"" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "%classpath add dynamic location + \"demo.jar\"" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "%classpath add dynamic [location + \"demo.jar\", location + \"BeakerXClasspathTest.jar\"]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Location of the Maven Cache and Using a Local Repository\n", "\n", "Maven normally downloads jars to `~/.m2/repository/`. But unfortunately this cache is [not safe for concurrent access](https://issues.apache.org/jira/browse/MNG-2802).\n", "To avoid corrupting it, BeakerX by default uses its own Maven cache in the conda environment at `$(CONDA_PREFIX)/share/beakerx/maven`. The `M2_HOME` environment variable overrides the default if set.\n", "\n", "If you want to use a normal IDE to develop a library, publish it to your local Maven repository, and then load that library into BeakerX, you can, like this:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "%classpath config resolver mvnLocal" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "That is shorthand for a `%classpath config resolver local` magic with a `file:` path to the local repository.\n", "\n", "## Clearing the Maven Cache\n", "\n", "If you have painted yourself into a corner, you can clear the contents of the maven cache as follows.\n", "This is useful for example if you have locally published [non-snapshot artifacts](https://maven.apache.org/guides/getting-started/index.html#What_is_a_SNAPSHOT_version). After resetting the cache, you will be prompted to restart your kernel." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "%classpath reset" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Import and Unimport\n", "\n", "Normally `import` in Groovy only works in the cell where you use it. To make a class import automatically into all cells, use `%import` magic." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "%import com.twosigma.beakerx.widget.IntSlider\n", "w = new IntSlider()\n", "w.value = 60\n", "w" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "w2 = new IntSlider()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "%unimport com.twosigma.beakerx.widget.IntSlider" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "w3 = new IntSlider()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "%import static java.lang.Math.PI" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "PI" ] } ], "metadata": { "beakerx_kernel_parameters": {}, "kernelspec": { "display_name": "Groovy", "language": "groovy", "name": "groovy" }, "language_info": { "codemirror_mode": "groovy", "file_extension": ".groovy", "mimetype": "", "name": "Groovy", "nbconverter_exporter": "", "version": "2.4.3" } }, "nbformat": 4, "nbformat_minor": 1 }