Let’s start our Java setup journey. If you want to configure the Java development environment on your Ubuntu machine, you have many options. There are different versions of Java runtime environments available along with a multitude of pre-packaged libraries. You can use various tools, but if you need a stable environment, reasonable protection from the supply chain attacks, including mitigation for known vulnerabilities, it is not a good idea to pull random binaries from different corners of the Internet. You definitely want to rely on the Ubuntu software library, the packages providing LTS guarantees and protecting your supply chain. And there are plenty of those published by Canonical. Of course, you can endlessly fiddle with the apt-cache search and snap find to select the appropriate packages and fine-tune your own environment. Is it secure? Yes. Is it reproducible? No. What if you want to set up all machines for all your team members in the same way? Not to mention that you definitely want your CI/CD environment to follow the same package selection to have exactly the same environment.
This is where the devpack-for-spring command-line tool comes in handy. Start with interactive selection on your local machine, even in a throw away environment. By the way, you can use multipass for that, it provides excellent isolation and integration with the host at the same time. Once happy with the selection you made, devpack-for-spring generates the list of packages for you as a reusable configuration you can feed back to devpack-for-spring later and have your exact configuration reproduced effortlessly. Now you can easily use devpack-for-spring to clone exactly the same setup on all the development machines and your CI/CD boxes while downloading everything from the trusted Ubuntu repositories. devpack-for-spring comes with a sensible selection of packages but nothing prevents you from providing your own templates suitable for your own environment. Just create your own setup-configuration.yaml and place it under $HOME/.config/devpack-for-spring/ or simply create an environment variable SPRING_CLI_SETUP_COMMANDS_CONFIGURATION pointing to your version of this file. Essential Spring libraries provided as snaps help you easily keep your development environment updated.
devpack-for-spring 1.3.6, recently released on the edge channel, has added an extra feature helping with automation. It is now capable of generating the manifest for non-interactive installation, something you had to manually prepare before, thanks to the new --save and --file options. Note: a non-interactive installation itself is not a new feature, it has been implemented for a while (see --add option), but you had to review the list of available packages and copy the required names paying attention to all the details. --save/--file combination enables you to use the nice TUI menu to finalise the package selection.
Let’s start with a simple task – configure our local environment in the way you will like it and produce a script that will help us reproduce in the same setup on a different machine.
First of all, make sure you have devpack-for-spring version 1.3.6 or newer. At the time of writing, it is available from the edge channel (use snap info devpack-for-spring to verify):
$ snap info devpack-for-spring
name: devpack-for-spring
summary: Development tools for Spring® projects
publisher: Canonical✓
[ ... skipped ... ]
channels:
latest/stable: 1.3.3 2026-04-22 (233) 215MB classic
latest/candidate: ↑
latest/beta: ↑
latest/edge: 1.4.1 2026-07-06 (268) 219MB classic
$ sudo snap install devpack-for-spring --channel latest/edge --classic
Let’s create our own selection of packages and install those locally (you can skip local installation step and create the re-usable configuration only, this feature is available in version 1.4.1 and above – add --save-only to the command line):
$ devpack-for-spring setup --save config.yaml
? OpenJDK openjdk-21-jdk
? Container environment
? Integrated Development Environment intellij-idea-community
? Additional tools git,rockcraft,snapcraft
? Remove unselected software? false
[ ... package installation output truncated]
OpenJDK 21 was successfully installed.
intellij-idea-community 2026.1.3 from jetbrains✓ installed
Intellij Idea Community snap was successfully installed.
Package git is already installed.
snapcraft 9.0.0 from Canonical✓ installed
snapcraft - easily create snaps was successfully installed.
rockcraft 1.19.0 from Canonical✓ installed
rockcraft - a craft like experience to create rocks was successfully installed.
$ # --save-only, no packages installed/removed:
$ devpack-for-spring setup --save-only --save config.yaml
? OpenJDK openjdk-21-jdk
? Container environment
? Integrated Development Environment intellij-idea-community
? Additional tools git,rockcraft,snapcraft
? Remove unselected software? false
Save only: would install package openjdk-21-jdk.
Save only: would install snap intellij-idea-community.
Save only: would install package git.
Save only: would install snap snapcraft.
Save only: would install snap rockcraft.
$
Note: If you want to avoid downloading big packages while playing with devpack-for-spring, make sure not to select large bundles, like openjdk or IDEs.
Now we have config.yaml that we can copy it anywhere and rely on devpack-for-spring’s ability to reproduce the same setup. It is safe to run devpack-for-spring using the same configuration since it will not change the environment because all packages are already installed.
$ devpack-for-spring setup --file config.yaml
[ ... package installation output truncated]
OpenJDK 21 was successfully installed.
intellij-idea-community 2026.1.3 from jetbrains✓ installed
Intellij Idea Community snap was successfully installed.
Package git is already installed.
snapcraft 9.0.0 from Canonical✓ installed
snapcraft - easily create snaps was successfully installed.
rockcraft 1.19.0 from Canonical✓ installed
rockcraft - a craft like experience to create rocks was successfully installed.
$
There is option --uninstall to make sure de-selected packages are removed, for example, when you have to make sure everyone migrates to the required JDK version. Of course, it will remove only packages explicitly enumerated in your setup-configuration.yaml making it easier to synchronise changes. Please check the documentation for further details.
The script you created can be checked into your code repository and everyone will have access to a “one click” environment set up recipe. Of course you can use it to upgrade packages on any development machines. Now let’s use the script we created to configure another machine.
Create a multipass VM as a model of our remote CI/CD box:
$ sudo snap install multipass
$ multipass launch --memory 4G --disk 8G --cpus 2 --name java-dev
Copy our list of packages and let devpack-for-spring install them:
$ multipass transfer config.yaml java-dev:
$ multipass exec java-dev -- \
sudo snap install devpack-for-spring --channel latest/edge --classic
YYYY-MM-DDTHH:mm:SS+ss:ss INFO Waiting for automatic snapd restart...
devpack-for-spring (edge) 1.3.6 from Canonical✓ installed
$ multipass exec java-dev -- devpack-for-spring setup --file config.yaml
[ ... package installation output truncated]
OpenJDK 21 was successfully installed.
intellij-idea-community 2026.1.3 from jetbrains✓ installed
Intellij Idea Community snap was successfully installed.
Package git is already installed.
snapcraft 9.0.0 from Canonical✓ installed
snapcraft - easily create snaps was successfully installed.
rockcraft 1.19.0 from Canonical✓ installed
rockcraft - a craft like experience to create rocks was successfully installed.
$ multipass exec java-dev -- java -version
openjdk version "21.0.11" 2026-04-21
OpenJDK Runtime Environment (build 21.0.11+10-1-26.04.2-Ubuntu)
OpenJDK 64-Bit Server VM (build 21.0.11+10-1-26.04.2-Ubuntu, mixed mode, sharing)
As you can see, moving exactly the same script to your CI/CD boxes lets you have exactly the same environment for reproducibly building and packaging your software.
And remember, devpack-for-spring is an open source software (devpack-for-spring tool repository, snap packaging repository), your contributions are welcome!
P.S. When you no longer need a multipass VM, just delete it as follows: multipass delete --purge java-dev
Additional publications about devpack-for-spring:
-
YouTube ““Devpack for Spring: Feature Walkthrough” and the related “Spring support available on Ubuntu” blog post
-
Blog post “From Jammy to Resolute: how Ubuntu’s toolchains have evolved”
-
Project repository and direct link to documentation.
-
For the latest news regarding
devpack-for-springdevelopment, look for “Foundations Team Updates” on discourse.ubuntu.com.