|
2 | 2 | title: Install and use Java packages |
3 | 3 | --- |
4 | 4 |
|
5 | | -This guide discusses how to install Java packages and use them in Deephaven queries. |
| 5 | +You can add JARs to the classpath in Deephaven Community workers to make Java packages available to your queries. All of Deephaven's deployment options support this, and this guide covers them all. |
6 | 6 |
|
7 | | -Java packages are installed for use with Deephaven by adding them to the Deephaven Docker images. This way, they are available every time Deephaven is launched. |
8 | | - |
9 | | -Once a package is installed, it can be imported and used like any other Java package. |
| 7 | +Once installed, a package can be imported and used like any other Java package. |
10 | 8 |
|
11 | 9 | > [!CAUTION] |
12 | | -> If a Java package has dependencies that Deephaven does not have, those packages will not work unless the required dependencies are installed as well. Java packages can also have dependencies that conflict with Deephaven's, so it's important to be careful when adding Java packages. |
13 | | -
|
14 | | -## Add packages to a custom Docker image |
15 | | - |
16 | | -In order to use Java packages within Deephaven, you must put the associated `.jar` files in the `/apps/libs` directory of your `server` image. (The `/apps/libs` directory is the default `EXTRA_CLASSPATH` location in the [Docker images](./configuration/docker-application.md).) |
17 | | - |
18 | | -In this section, we add the [Java CryptoCompare API client](https://mvnrepository.com/artifact/com.github.jeffreytai/cryptocompare-api-wrapper) to a custom Dockerfile and reference it from Deephaven so that we can use it in more than one session. |
| 10 | +> Care should be taken when adding JARs to Deephaven workers. Java packages may be missing dependencies or have dependencies that conflict with Deephaven's. |
19 | 11 |
|
20 | | -In order to use packages more than once, you can create a custom Docker image, and then use that image in Deephaven. The steps for accomplishing this differ slightly depending on how you launch Deephaven. Let's start with the steps that are common between both. |
| 12 | +The examples in this guide add the [Plexus Common Utilities](https://codehaus-plexus.github.io/plexus-utils/) library to a Deephaven Community instance. |
21 | 13 |
|
22 | | -### Prerequisites |
23 | | - |
24 | | -Before a custom Docker image can be built, you must acquire the necessary base images. This process differs based upon how you launch Deephaven: |
25 | | - |
26 | | -- If you [launch from pre-built images](../tutorials/docker-install.md), ensure you have run the following command to download the necessary base images: |
27 | | - |
28 | | -```shell |
29 | | -docker compose pull |
30 | | -``` |
| 14 | +## Docker |
31 | 15 |
|
32 | | -- If you [launch from source code](./launch-build.md), ensure you have built the project so that you have the necessary base images. |
| 16 | +If you [Run Deephaven with Docker](../tutorials/docker-install.md), you can either build a custom Docker image or mount a volume containing the JAR into the container. |
33 | 17 |
|
34 | | -### Create a custom Dockerfile |
| 18 | +### Build a custom Docker image |
35 | 19 |
|
36 | | -To begin, create a new directory. This directory should not be in a Deephaven deployment directory. You can name it whatever you'd like. For this guide, we'll name ours `deephaven-custom`. |
| 20 | +To build a custom Docker image, create a Dockerfile that downloads the JAR and adds it to the image. The following `Dockerfile` adds `plexus-utils-4.0.2.jar` to `/apps/libs` in the image. The Deephaven Docker images automatically include `/apps/libs/*` in the JVM classpath at startup: |
37 | 21 |
|
38 | | -```shell |
39 | | -mkdir deephaven-custom |
40 | | -cd deephaven-custom |
| 22 | +```dockerfile |
| 23 | +FROM ghcr.io/deephaven/server:latest |
| 24 | +ADD https://repo1.maven.org/maven2/org/codehaus/plexus/plexus-utils/4.0.2/plexus-utils-4.0.2.jar /apps/libs/plexus-utils-4.0.2.jar |
41 | 25 | ``` |
42 | 26 |
|
43 | | -Now, in this directory, create a file called `Dockerfile`. `Dockerfile` should use `ghcr.io/deephaven/server` as the base image and should contain a recipe for installing the new package. When adding the [Java CryptoCompare API client](https://mvnrepository.com/artifact/com.github.jeffreytai/cryptocompare-api-wrapper), it looks like this: |
| 27 | +You then need to build your image. If you use Docker without Compose, run `docker build` and `docker run`: |
44 | 28 |
|
45 | | -``` |
46 | | -FROM ghcr.io/deephaven/server |
47 | | -RUN curl --output /apps/libs https://repo1.maven.org/maven2/com/github/jeffreytai/cryptocompare-api-wrapper/1.0.0/cryptocompare-api-wrapper-1.0.0.jar |
| 29 | +```bash |
| 30 | +docker build --tag deephaven-plexus-utils . |
| 31 | +docker run --rm --name deephaven-with-plexus-utils -p 10000:10000 deephaven-plexus-utils |
48 | 32 | ``` |
49 | 33 |
|
50 | | -### Create a custom Docker image |
| 34 | +Alternatively, if you use Docker Compose, you can have Compose build the image for you. The following YAML assumes that the Dockerfile lives in the same directory: |
51 | 35 |
|
52 | | -Now that we have the `Dockerfile` in place, we need to create the custom Docker image. To do so, run a command from the directory with `Dockerfile` that looks like: |
53 | | - |
54 | | -```shell |
55 | | -docker build --tag <user>/server-<custom> . |
| 36 | +```yaml |
| 37 | +services: |
| 38 | + deephaven: |
| 39 | + build: . |
| 40 | + ports: |
| 41 | + - "${DEEPHAVEN_PORT:-10000}:10000" |
| 42 | + volumes: |
| 43 | + - ./data:/data |
| 44 | + environment: |
| 45 | + - START_OPTS=-Xmx4g |
56 | 46 | ``` |
57 | 47 |
|
58 | | -This creates a new Docker image named `<user>/server-<custom>`. For this guide, we will call the image `guide/server-cryptocompare`: |
| 48 | +### Mount the JAR into the container manually |
59 | 49 |
|
60 | | -```shell |
61 | | -docker build --tag guide/server-cryptocompare . |
62 | | -``` |
| 50 | +Adding JARs to a Docker container does not require building a custom image. Instead, you can simply mount a folder into the container that contains whatever JARs you wish to use. Since the Deephaven Docker images automatically include `/apps/libs/*` in the JVM classpath, mounting your local JAR directory to `/apps/libs` makes them immediately available. |
63 | 51 |
|
64 | | -When the command finishes running, you can see the new image in your system: |
| 52 | +The following command assumes you've placed the JAR file into a folder called `/home/user/java/libs`: |
65 | 53 |
|
66 | | -```shell |
67 | | -docker image ls |
| 54 | +```bash |
| 55 | +docker run --rm -v /home/user/java/libs:/apps/libs -p 10000:10000 ghcr.io/deephaven/server:latest |
68 | 56 | ``` |
69 | 57 |
|
70 | | -### Reference the new image |
| 58 | +## Production application |
71 | 59 |
|
72 | | -To put it all together, we now need to reference this new image in the `docker-compose` file we use to launch Deephaven. The particular file depends on how you build and launch Deephaven: |
| 60 | +The [Production application](../tutorials/production-application.md) uses the environment variable `EXTRA_CLASSPATH` to include additional JARs in the classpath. See [Configure the production application](./configuration/configure-production-application.md#environment-variables) for more details, including other configuration options. |
73 | 61 |
|
74 | | -- If you [launch from pre-built images](../tutorials/docker-install.md), the file is `docker-compose.yml` and can be found in your `deephaven-deployment` directory. |
| 62 | +## Build from source |
75 | 63 |
|
76 | | -- If you [launch from source code](./launch-build.md), the file is `docker-compose-common.yml` and can be found in your `deephaven-core` directory. |
| 64 | +Adding Java packages to [Deephaven built from source code](./launch-build.md) is similar to the [production application](#production-application). It does, however, change how you launch Deephaven built from source. |
77 | 65 |
|
78 | | -In the Docker Compose file, there are three lines of text that look like: |
| 66 | +Rather than run `./gradlew server-jetty-app:run`, run this instead: |
79 | 67 |
|
| 68 | +```bash |
| 69 | +./gradlew server-jetty-app:installDist |
80 | 70 | ``` |
81 | | -services: |
82 | | - server: |
83 | | - image: <IMAGE_NAME> |
84 | | -``` |
85 | | - |
86 | | -The image used by default depends on how you build and launch Deephaven. Regardless, this line is where you need to insert your custom image name. Modify the `image` line to use your new image: |
87 | | - |
88 | | -``` |
89 | | -services: |
90 | | - server: |
91 | | - image: guide/server-cryptocompare:latest |
92 | | -``` |
93 | | - |
94 | | -Now, when you launch Deephaven again, you can use the package! |
95 | | - |
96 | | -```groovy skip-test |
97 | | -import com.google.gson.JsonObject |
98 | | -import com.crypto.cryptocompare.api.CryptoCompareApi |
99 | 71 |
|
100 | | -CryptoCompareApi api = new CryptoCompareApi() |
| 72 | +This creates the directory `./server/jetty-app/build/install/server-jetty/bin`, which contains a `start` script that you can pass additional parameters to, such as an `EXTRA_CLASSPATH` environment variable. |
101 | 73 |
|
102 | | -JsonObject response = api.priceMulti( |
103 | | - "BTC", |
104 | | - "USD", |
105 | | - new LinkedHashMap<String, Object>() {{ |
106 | | - put("extraParams", "TestProject"); |
107 | | - }} |
108 | | -); |
| 74 | +> [!CAUTION] |
| 75 | +> Use quotes around the classpath value to prevent shell expansion of asterisks. The JVM needs to receive the literal `*` character to include all JARs in the directory. |
109 | 76 |
|
110 | | -bitcoin_price = response.get("BTC").get("USD").getAsFloat() |
| 77 | +You can pass it directly to the command: |
111 | 78 |
|
112 | | -println bitcoin_price |
| 79 | +```bash |
| 80 | +EXTRA_CLASSPATH="/path/to/libs/*:/apps/libs/*" ./server/jetty-app/build/install/server-jetty/bin/start |
113 | 81 | ``` |
114 | 82 |
|
115 | | -> [!CAUTION] |
116 | | -> When base images are updated by rebuilding source code or redownloading pre-built images, custom images must be rebuilt to incorporate the base image changes. |
117 | | -
|
118 | | -## List all available Java packages |
119 | | - |
120 | | -You can check what Java packages are available to Deephaven by running the following command from your Deephaven installation while Deephaven is running. |
| 83 | +Or you can export the environment variable before running the script: |
121 | 84 |
|
122 | 85 | ```bash |
123 | | -docker-compose exec server ls /apps/libs |
| 86 | +export EXTRA_CLASSPATH="/path/to/libs/*:/apps/libs/*" |
| 87 | +./server/jetty-app/build/install/server-jetty/bin/start |
124 | 88 | ``` |
125 | 89 |
|
126 | 90 | ## Use Java packages in query strings |
127 | 91 |
|
128 | | -Installed Java packages can be used in query strings. We'll use the [Apache Commons Lang](https://commons.apache.org/proper/commons-lang/) [`RandomUtils`](https://commons.apache.org/proper/commons-lang/apidocs/org/apache/commons/lang3/RandomUtils.html) class to create a table with ten rows of random integers in a range. |
| 92 | +Not only can you import and use the extra Java packages in normal Python code, but you can also call them in query strings. You'll need to provide the full package name unless you construct an instance of the class beforehand. The following code calls [`org.codehaus.plexus.util.StringUtils.abbreviate`](https://codehaus-plexus.github.io/plexus-utils/apidocs/org/codehaus/plexus/util/StringUtils.html#abbreviate(java.lang.String,int)) from the [Plexus Common Utilities](https://codehaus-plexus.github.io/plexus-utils/) library to abbreviate a string. |
| 93 | + |
| 94 | +<!-- This test is skipped because it requires installing the Plexus Common Utilities JAR. --> |
| 95 | + |
| 96 | +```python skip-test |
| 97 | +from deephaven import empty_table |
129 | 98 |
|
130 | | -```groovy |
131 | | -t = emptyTable(10).update("X = org.apache.commons.lang3.RandomUtils.nextInt(1, 99)") |
| 99 | +source = empty_table(1).update( |
| 100 | + [ |
| 101 | + "StringColumn = `Hello world`", |
| 102 | + "Abbreviated = org.codehaus.plexus.util.StringUtils.abbreviate(StringColumn, 9)", |
| 103 | + ] |
| 104 | +) |
132 | 105 | ``` |
133 | 106 |
|
134 | 107 | ## Related documentation |
135 | 108 |
|
| 109 | +- [Create an empty table](./new-and-empty-table.md#emptytable) |
136 | 110 | - [How to install packages](./install-packages.md) |
137 | 111 | - [How to configure the Deephaven Docker application](./configuration/docker-application.md) |
138 | 112 | - [Launch Deephaven from pre-built images](../tutorials/docker-install.md) |
139 | 113 | - [Build and launch Deephaven from source code](./launch-build.md) |
| 114 | +- [How to use Java packages in query strings](./install-and-use-java-packages.md#use-java-packages-in-query-strings) |
140 | 115 | - [Access your file system with Docker data volumes](../conceptual/docker-data-volumes.md) |
0 commit comments