Monthly Archives: October 2024

Java, Maven and Gitpod, part 3: Configuring Java

This is the 3rd post about using Java in Gitpod.

It assumes you have already read the first and second posts.

On the bottom, we can see that there are two warnings on our project; let’s click the icon and see them in the “Problems” tab:

Since this is not a Java project managed by Visual Studio Code but a Maven project, we must fix the warning in the POM.

Let’s assume we want to update our project to use the Java version installed in the Gitpod workspace: Java 11 (we can tell that from the warning, but we could also run “java -version” from a terminal to verify that). We open the POM file and update the corresponding properties of Java 1.7: we change “1.7” to “11”:

As soon as we modify the POM, we get a pop-up: the Java LSP detects a change in the project configuration and offers to synchronize the classpath and rebuild the project. Of course, we accept. We accept that, and after a few seconds, the warnings go away.

Note that our choice leads to creating the settings file for this option. We can choose to rebuild the project automatically (“Always”), and the settings file will be updated accordingly. Of course, it makes sense to store such a file in the Git repository.

We can now create a commit with our changes and push them to GitHub.

Remember that the JSON editor is aware of the corresponding schema, so we can enjoy code completion for the string value:

Let’s now say we want to use Java 17 for our project. The workspace provides Java 11, so we must also have Java 17 installed in the Gitpod workspace.

Let’s modify the POM for Java 17 and rebuild the project. Let’s try to run the main file. The Java application still runs, as we can see from the terminal:

Gitpod workspace uses SDKMAN to provide a few versions of tools like the JDK and uses the version required by the project (in this example, Java 17).

We can list the installed JDK in the terminal (and the current one):

If we wanted to go for Java 21, we should install that version with SDKMAN, but we wouldn’t want to do that manually each time we open a Gitpod workspace. Moreover, instead of the “Zulu” distribution, we might use the “Temurin” distribution.

The recommended way is to provide a custom Dockerfile for our Gitpod workspace to have full explicit control over the versions of the tools we use; this will be part of the Git repository and live with the code.

So we create in the root of our project the file “.gitpod.Dockerfile,” and we configure SDKMAN for the version of Java we want to install and set as the current (the available versions can be discovered with “sdk list java”):

Then, we refer to this Dockerfile in the “.gitpod.yml”:

As before, we can let Gitpod validate our configuration and start a new workspace with the rebuilt Docker image.

As shown in my previous post on Gitpod, you might want to start from a smaller base image with only the needed tools like Java. That would decrease the time to build the custom Docker image. That is out of the scope of this post.

However, rebuilding the Docker image will be done the first time you start a workspace, and the custom image will be cached.

On the new workspace, we can verify that we are using the Java version we installed and set as default:

Again, we commit our changes (including the new custom Dockerfile) and push them to GitHub.

One could use the same strategy for installing a specific version of Maven through SDKMAN. Maven is also installed in the workspace through SDKMAN.

I want to conclude that this process seems long. Still, once you get familiar with the configuration of Gitpod for Java/Maven projects, for new repositories of the same kind, it is enough to immediately put in the Git repository the “.gitpod.yml” and the “.gitpod.Dockerfile.” You can immediately start coding with Gitpod! 🙂

Remember, though, that the first time, you will still have to wait for the build of your custom Docker image.

Stay tuned for the fourth part.

How I manage Neovim configuration with Chezmoi

I love to manage my dotfiles with Chezmoi, which I highly recommend! In a single Git repository, I have common dotfiles and Window Manager specific (KDE, GNOME, Hyprland, and Sway).

However, I prefer to have my Neovim configuration in another Git repository, separate from my Chezmoi dotfiles. I’ve just started learning Neovim, and I’m not yet 100% sure the configuration I use will be the ultimate one (I use Lazyvim); that’s why I want to keep them separate.

Chezmoi offers mechanisms for such situations: https://www.chezmoi.io/user-guide/include-files-from-elsewhere/. In particular, I use “Include a subdirectory from a git repository”: this way, Chezmoi will clone the external Git repository for my Neovim configuration on the first run and will keep it up to date (i.e., “git pull”) at some specified intervals (remember, the default interval is 0!).

You need to create the file “.chezmoiexternal.toml” in the root folder of your Chezmoi file and follow the syntax in the documentation.

For example, I want my “~/.config/nvim” directory (where Neovim configuration lives) to be populated (and kept up-to-date) with the contents of my GitHub repository “https://github.com/LorenzoBettini/starter” (as I said above, I’m using a fork of the Starter repository of Lazyvim):

Note that I specified a 1-hour refresh interval. Thus, if I issue a “chezmoi update,” it will keep that interval into consideration when deciding whether to check for updates (i.e., “pull”) in the Git repository. However, you also have this option in Chezmoi to force the Git update:

That’s all, and enjoy your dotfiles! 🙂