Add custom JARs using a persistent volume

Custom JARs are typically built into your container images (see Kubernetes installation). This guide shows how to add JARs without rebuilding your images: stage them on a persistent volume, mount that volume to pods, and add the mounted path to the classpath.

You can make the JARs available to system service pods (such as the Controller and the query and merge servers), to worker pods, or to both. Steps 1, 2, 3, and 5 apply in every case, because both volume mounts are Helm values that take effect only after the Helm upgrade in Step 5. Step 4 applies to system service pods, and Step 6 applies to workers.

Step 1: Create a PersistentVolumeClaim

Create a PersistentVolumeClaim (PVC) for your custom JARs.

If you mount the volume to more than one pod (for example, both system services and workers), use a storage class that supports ReadWriteMany (RWX). A ReadWriteOnce (RWO) class causes multi-attach errors when pods are scheduled on different nodes.

For RWX storage options, see Configure shared storage.

Create a file called custom-jars-pvc.yaml:

Apply it:

Step 2: Stage JARs to the volume

Create a temporary pod to copy your JARs to the persistent volume. The pod's image must provide sh, sleep, and tar, because kubectl cp requires tar.

Create a file called jar-staging-pod.yaml:

Tip

If your cluster can't pull from Docker Hub, replace busybox with an image from a registry your cluster can reach that includes sh, sleep, and tar, and add any imagePullSecrets that registry requires. You can use the Deephaven management shell image if it includes those tools in your installation. Look up its name with kubectl get deploy/management-shell -o jsonpath='{.spec.template.spec.containers[].image}'.

Apply the pod and copy your JARs:

The chmod command is needed because the staging pod owns the copied files, while Deephaven processes run as other users.

Step 3: Mount the volume to pods

Add one or both of the following sections to your Helm values override file (for example, my-values.yaml). To make the same JARs available to both system services and workers, use both.

For system service pods

Use extraVolumes to mount the PVC to system service pods. These mounts are read-write.

For worker pods

Use workerExtraVolumes to mount the PVC to worker pods. For more on mounting data in workers, see How do I make a certificate or other piece of external data available within my Persistent Queries?

Note

Query worker mounts are always read-only: because of a Helm template limitation, setting readOnly: false has no effect on them. Merge workers mount extra volumes read-write by default; to make a merge worker volume read-only, set readOnly: true.

Step 4: Add the JARs to the system service classpath

If you mounted the volume to system service pods, add the mounted path to their classpath in the same values file. Use classpathPre to load the JARs before Deephaven classes, or classpathPost to load them after:

To configure a single process instead of all processes, use the process name in place of common:

Step 5: Apply the Helm configuration

Scale down your deployment and run a Helm upgrade with your values file, as described in Install the Deephaven Helm chart:

Step 6: Add the JARs to the worker classpath

If you mounted the volume to worker pods, add the mounted path to the worker classpath. Worker classpaths are set per Persistent Query or Code Studio, not in the Helm chart, so this step needs no Helm upgrade beyond the one in Step 5.

The volume mount from Step 3 and this classpath setting apply only to workers started after you make the change. Restart any Persistent Queries or Code Studios that were already running.

In the Show Advanced section of the Persistent Query or Code Studio settings, add the mounted path to the Extra Classpaths field. This works for both Legacy and Core+ workers:

Note

For Core+ workers, you can instead set DND_EXTRA_CLASSPATH=/custom/jars/* in Extra Env Variables. A DND_EXTRA_CLASSPATH value set there replaces anything entered in Extra Classpaths, so use one or the other.