"It works on my machine."
If you're a developer, chances you've heard, and said, it at least once in your life are huge. There can be tons of reasons for that: your processor architecture, your operational system, your compiler version, may be different from your colleague's. Even worse scenario is when you deploy your applications in cloud environments and they crash. But how? It worked on my machine!
In a recent past, for Java projects - more specifically Spring Boot ones, I used to install sdkman and tried to arrange with the whole team to use the very same vendor and version of the JDK. Problem is, it depends on human actions to work. And humans can fail.
With that in mind, I'd like to introduce to you a whole new world: development of a Spring Boot application in Visual Studio Code and compile, test and run in a Docker container. I know you just turned up the nose about Java and VS Code, but trust me, it's gonna work and be worth it.
So, no need for a JDK installed on your machine. But you'll need VS Code and Docker, of course. After you install them, open your VS Code. In the Extensions menu, search for "Remote - Containers" and install it:
Then, head to Spring Initializr, scaffold a new project, download and extract the files on your machine:
Remember to add Spring Web and Spring Boot DevTools.
Now, in your VS Code, open the Command Palette (usually Ctrl or Command + Shift + P) and type ">Remote-Containers: Open Folder in Container", select it and choose the location of your extracted Spring Boot application:
Now, it's time to configure your development environment container.
Select "Java - Develop Java applications":
Select your Java version, in my case, 11:
Select "Install Maven":
By now, your VS Code should have created a new folder in your project, called .devcontainer with a Dockerfile and devcontainer.json. You don't need to worry about them for now. Since this will be the first time your VS Code will run your application in a Docker container, it can take some time to download the images. Be patient. Once it is finished, you will be notified.
Select the Run menu, click on "Open a file" and navigate to your Main class, in my case HelloFromContainerApplication:
Now, if you click on the button "Run and Debug" it will run the application. Optionally, clicking on "No Configuration" and then "Add Configuration", VS Code will create a launch.json configuration file.
Finally, if you hit http://localhost:8080/ in your browser you will see that the application is up and running in Debug mode, perfect to install some breakpoints and start your awesome solution. And remember DevTools? Go ahead and add a new endpoint to your application. It will live-reload in the container as well.
Now comes the controversy part. Although it's recommended that you do not push specific IDE configuration files to your repository, I believe that if the whole team agrees to work in that manner, the .devcontainer could reside remotely. By doing this, you will mitigate the human failures and there will be no more "it works on my machine" excuses. Every environment, regardless of operational system, processor architecture or previous JDK installations, will behave similarly. This may even improve the speed of newcomers to the project for it will require less guidance and hit fewer issues related to environment setup.
As a final hint, if you look closely to the Dockerfile created by VS Code inside .devcontainer folder, you will see a comment like:
// See here for image contents: https://github.com/microsoft/vscode-dev-containers/tree/v0.158.0/containers/java/.devcontainer/base.Dockerfile
This can be your guidance to creating your own Dockerfile, based on your local working environment. In this case, the Java image being used is the openjdk:11-jdk-buster and I would most likely want to use the same in production.