Achieving Seamless SSH Experience and Java Development Setup in VS Code DevContainers

In the dynamic world of software development, efficiency and consistency are key. Developers are continually seeking tools and practices that streamline their workflow, reducing overhead and allowing a greater focus on the creative aspects of coding. Enter the realm of Visual Studio Code’s Dev Containers – a feature revolutionizing the way developers interact with their coding environments.

Dev Containers in VS Code offer a consistent, isolated development environment, ensuring that the “it works on my machine” syndrome is a thing of the past. This innovation brings a fresh approach to the development process, allowing smoother code development, testing, and debugging.

In this article, we delve deep into setting up a robust Java development environment within Dev Containers. We also integrate SSH configuration on MacOS, promising seamless management of SSH keys and smoothing the transition between local and containerized development environments.

Whether a seasoned developer or a newcomer, understanding how to leverage these tools can significantly enhance your development practices. Join us as we explore how to streamline your development process, making it more efficient and hassle-free.

Stay tuned as we unveil the steps to set up your development environment, configure SSH keys seamlessly on MacOS, and harness the full potential of Dev Containers for Java development.

Setting Up the Essentials

Embarking on a development journey with VS Code’s Dev Containers requires some initial setup. This section guides you through the essentials, ensuring you have all the necessary tools at your disposal.

Installing Visual Studio Code

Why VS Code?
Visual Studio Code, often abbreviated as VS Code, is more than just a code editor. It’s a versatile, lightweight tool that supports multiple programming languages and platforms. Its sleek interface, combined with powerful features like IntelliSense code completion and integrated Git control, makes it a top choice for developers globally.

Steps to Get Started:

  • Visit the Visual Studio Code website.
  • Select the version compatible with your operating system (Windows, MacOS, or Linux).
  • Download and follow the installation instructions.

With VS Code installed, you’re already a step closer to a streamlined development environment.

Adding Remote Development Extensions

The Role of Remote Development Extensions:
VS Code’s Remote Development extensions are a suite of functionalities allowing developers to work in remote environments like SSH servers, Docker containers, and the Windows Subsystem for Linux (WSL). These extensions are crucial for setting up Dev Containers.

Installation Guide:

  • Launch VS Code.
  • Access the Extensions view by clicking on the square icon on the left sidebar or pressing Ctrl+Shift+X (Cmd+Shift+X on MacOS).
  • Search for “Remote Development” in the extensions marketplace.
  • Find the extension pack by Microsoft and install it.

Now, you’re equipped to handle remote development scenarios directly from your local machine.

Docker Installation and Configuration

Understanding Docker’s Role:
Docker is the cornerstone of working with Dev Containers. It allows you to create, manage, and deploy containerized applications, ensuring that your development environment is replicated accurately wherever you go.

Downloading and Configuring Docker:

  • Head to the Docker website and download Docker Desktop for your operating system.
  • Run the installer and follow the instructions.
  • After installation, launch Docker Desktop and adjust the settings if necessary to suit your system’s resources.

With Docker up and running, the stage is set for you to create isolated and reproducible development environments.

Working with Dev Containers

Dev Containers in Visual Studio Code offer a fully-fledged development environment, tailored to your project’s needs, yet isolated from your local setup. This isolation ensures consistency and replicability across development teams and environments. Here, we’ll explore how to work effectively with Dev Containers, specifically for Java development.

Opening a Project with a Dev Container

To start working with a Dev Container, you first need a project that includes a .devcontainer directory with at least a devcontainer.json file and, typically, a Dockerfile.

  1. Opening Your Project in VS Code: Navigate to your project directory that contains the .devcontainer folder. Open this folder in VS Code.

  2. Reopening in a Container: VS Code will likely prompt you to reopen the project in a container. If not, you can open the Command Palette (Ctrl+Shift+P on Windows/Linux, Cmd+Shift+P on MacOS) and select the “Remote-Containers: Open Folder in Container…” command.

Building and Starting the Container

When you open your project in a container, VS Code builds the container image based on the Dockerfile and devcontainer.json configuration. This process includes:

  • Installing Extensions: Extensions specified in the devcontainer.json file are installed within the container.
  • Setting Up the Environment: Any environment variables or settings defined in the configuration file are applied.
  • Running Post-Creation Commands: If specified, commands in the postCreateCommand field are executed after the container is built.

The Development Experience in a Container

Once the container is up and running, you can start coding, debugging, and running your Java application just as you would on your local machine, but with a few key benefits:

  • Consistency: Your development environment matches the configuration specified in your Dev Container setup, ensuring consistency across all team members and deployment environments.
  • Isolation: Dependencies and tools required for your project are confined to the container, keeping your local environment clean and uncluttered.
  • Replicability: The Dev Container can be replicated easily across different machines or for different team members, reducing the “works on my machine” problem.

Managing Containers

While working with Dev Containers, you can manage them through the Docker Desktop interface or using Docker CLI commands. This includes starting, stopping, or removing containers and images.

Debugging and Running Applications

Debugging and running applications in a Dev Container is similar to doing so in a local environment. VS Code’s powerful debugging tools are available, and thanks to port forwarding, you can access your running applications directly from your local browser or API tools.

Accessing Files and Using Terminals

  • File Access: You can access your project files within the container seamlessly through VS Code’s Explorer.
  • Integrated Terminal: Using the integrated terminal in VS Code (Ctrl+ on Windows/Linux, `Ctrl+`` on MacOS), you can run commands inside the container as if you were working on your local machine.

Version Control

Dev Containers fully support version control with Git. You can commit, push, pull, and manage your Git repositories from within the container, ensuring your development workflow remains uninterrupted.

Working with Dev Containers offers a robust, isolated, and consistent development environment, enhancing productivity and collaboration for Java developers. By leveraging this powerful feature of VS Code, teams can focus more on development and less on environment-related issues.

Configuring the Dev Container for Java - Understanding devcontainer.json

The devcontainer.json file is a key component in setting up your Java development environment within a VS Code Dev Container. This configuration file acts as a blueprint, guiding VS Code in creating a container that precisely fits your development needs.

Purpose and Functionality of devcontainer.json

The devcontainer.json file allows you to define the characteristics and behaviors of your development environment. It includes specifying the container image, setting environment variables, installing necessary extensions, and running setup scripts. This ensures that your development environment is ready with all the tools and settings required for your Java project.

Exploring Your devcontainer.json Configuration

Here’s a breakdown of the main elements in your devcontainer.json file and how they contribute to setting up your Java development environment:

.devcontainer/devcontainer.json

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
{
// Name of the container environment
"name": "Java Dev Container",

// Docker configuration specifying the Dockerfile to use
"build": {
"dockerfile": "Dockerfile"
},

// Features to include in the container, such as Java and other tools
"features": {
// Java feature with no specific version, opting not to install Maven, but to install Gradle
"ghcr.io/devcontainers/features/java:1": {
"version": "none",
"installMaven": "false",
"installGradle": "true"
},
// Google Cloud CLI feature for cloud integration
"ghcr.io/dhoeric/features/google-cloud-cli:1": {},
// Feature to enable using Docker inside the container
"ghcr.io/devcontainers/features/docker-outside-of-docker:1": {}
},

// Port forwarding configuration to access ports inside the container from the local machine
"forwardPorts": [8080],

// Command to run after the container is created, here it runs a custom script
"postCreateCommand": "bash ./.devcontainer/postCreateCommand.sh",

// Customizations for the development environment, mainly VS Code extensions
"customizations": {
"vscode": {
"extensions": [
// Extensions specific to Java development
"vscjava.vscode-lombok",
"vscjava.vscode-java-pack",
"vmware.vscode-boot-dev-pack",
// Extensions for security vulnerability analysis
"redhat.fabric8-analytics",
// Extensions for code quality
"SonarSource.sonarlint-vscode",
// Extensions for Cloud development
"GoogleCloudTools.cloudcode",
// Various tools and utilities
"bierner.markdown-mermaid",
"DavidAnson.vscode-markdownlint",
"hediet.vscode-drawio"
]
}
},

// Specifies the default user for the container; uncomment to use the root user
"remoteUser": "vscode",
}
  1. Container Name ("name"):

    • Identifies your container environment. In your case, it’s labeled as “Java Dev Container”, which helps in distinguishing it in complex setups with multiple containers.
  2. Docker Build Configuration ("build"):

    • Specifies the Dockerfile to use when creating the container. This Dockerfile defines the base image and any additional software or configurations necessary for your Java environment.
  3. Features ("features"):

    • Enhances the container with additional tools or software. For Java development, you can specify versions and tools such as Maven or Gradle. This section allows for customization to fit your specific project requirements.
  4. Port Forwarding ("forwardPorts"):

    • Essential for web development, this setting forwards specified ports from the container to the host machine. It enables you to access server applications running inside the container from your local machine.
  5. Post-Creation Command ("postCreateCommand"):

    • Executes a specified script or command after the container is created. This is where your custom setup tasks, such as configuring code formatting tools or initializing project-specific settings, are automated.
  6. Extensions ("customizations"):

    • Automatically installs a set of VS Code extensions within the container. For Java development, this could include language support, linters, and other utilities that enhance your coding experience.
  7. Remote User ("remoteUser"):

    • Defines the default user within the container. This setting ensures that your development activities run under a specific user context, which can be crucial for permission and access control within the container.

Customizing Your devcontainer.json

Your devcontainer.json is set up to provide a robust and flexible Java development environment. However, it’s designed to be adaptable to your evolving project needs. You can modify this file to change the base image, add or remove extensions, update tool versions, or adjust other settings, ensuring that your Dev Container remains perfectly aligned with your project requirements.

Impact on Your Workflow

By meticulously configuring the devcontainer.json file, you streamline the setup of your development environment. This eliminates the need for manual configuration each time you start a project, allowing you to dive straight into coding with all the necessary tools and settings at your fingertips.

Crafting the Dockerfile for Java Development

The Dockerfile is an integral part of setting up your Java development environment in a Dev Container. It serves as the blueprint for constructing your containerized environment, specifying everything from the base image to the installation of development tools and dependencies.

Understanding the Role of the Dockerfile

A Dockerfile outlines the steps to create a container’s image. For Java development, it defines the necessary environment, including the operating system, Java Development Kit (JDK), build tools like Maven or Gradle, and any other software or libraries your project might need.

Key Components of Your Dockerfile

.devcontainer/Dockerfile

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# Base image for Java development - includes Java JDK 17
FROM mcr.microsoft.com/devcontainers/java:1-17-bookworm

# Arguments for conditional installation of Maven and Gradle
# Set 'true' or 'false' to control the installation
ARG INSTALL_MAVEN="false"
ARG MAVEN_VERSION=""
ARG INSTALL_GRADLE="true"
ARG GRADLE_VERSION=""

# Script to install Maven and/or Gradle based on the above arguments
# Utilizes SDKMAN! for managing Java-related SDKs
RUN if [ "${INSTALL_MAVEN}" = "true" ]; then \
su vscode -c "umask 0002 && . /usr/local/sdkman/bin/sdkman-init.sh && sdk install maven \"${MAVEN_VERSION}\""; \
fi \
&& if [ "${INSTALL_GRADLE}" = "true" ]; then \
su vscode -c "umask 0002 && . /usr/local/sdkman/bin/sdkman-init.sh && sdk install gradle \"${GRADLE_VERSION}\""; \
fi

# Uncomment below to install additional OS packages as needed
# Useful for custom dependencies specific to your project
# RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
# && apt-get -y install --no-install-recommends <your-package-list-here>

# Uncomment to install global Node.js packages, if required
# Can be used for front-end development or build scripts
# RUN su vscode -c "source /usr/local/share/nvm/nvm.sh && npm install -g <your-package-here>" 2>&1

# Installing Node.js and NPM for projects with JavaScript components
RUN apt update -y && apt install npm -y && apt-get clean

# Installing global tools for code quality and consistency
# Prettier for code formatting, Husky for Git hooks, commitlint for commit message standards
RUN npm install -g prettier prettier-plugin-java husky lint-staged @commitlint/config-conventional @commitlint/cli
  1. Base Image Selection:

    • The Dockerfile starts with a base image that includes JDK 17, providing a solid foundation for Java development.
  2. Conditional Installation of Build Tools:

    • The use of ARG instructions allows for the conditional installation of Maven and Gradle. This flexibility is valuable in customizing the container based on the specific needs of your Java projects.
  3. SDKMAN! for Tool Management:

    • The Dockerfile utilizes SDKMAN!, a version manager for Java-related SDKs, to handle the installation of Maven or Gradle. This ensures that the desired versions of these tools are installed in the container.
  4. Installing Additional Tools and Dependencies:

    • The Dockerfile includes steps to update package lists, install Node.js and NPM (useful for projects that include front-end components or need these for build scripts), and install global tools like Prettier and Husky.
  5. Code Quality and Consistency Tools:

    • By installing Prettier and Husky globally, along with commitlint for commit message standards, your Dockerfile sets up an environment that promotes code quality and consistency.

Customizing the Dockerfile

While your Dockerfile is configured for a robust Java development setup, it is designed to be flexible and adaptable. Depending on your project’s requirements, you can modify this file to change the base image, add or remove tools, or customize configurations. This adaptability ensures that your Dev Container remains a perfect fit for your development needs.

Impact on Development Workflow

With a well-crafted Dockerfile, you can be confident that your development environment is pre-configured with all the necessary tools and settings. This minimizes setup time and allows you to focus more on coding and problem-solving, knowing that your environment is consistent, isolated, and tailored to your Java project’s requirements.

Post Creation Script (postCreateCommand.sh)

The postCreateCommand.sh script is a crucial element in finalizing the setup of your Dev Container, particularly for Java development. Executed after the container’s creation, this script automates the configuration of additional tools and settings, ensuring a fully prepared development environment.

Purpose of postCreateCommand.sh

This script’s primary role is to execute tasks that are not covered in the Dockerfile or devcontainer.json, such as configuring project-specific settings, setting up code quality tools, and initializing necessary services or databases. It’s a powerful way to automate the final touches to your development environment.

Breakdown of Your postCreateCommand.sh Script

.devcontainer/postCreateCommand.sh

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
#! /usr/bin/env bash
set -eux
set -o pipefail

# Output the current username
echo "User: $USER"
# Get and output the current working directory path
current_dir=$(pwd)
echo "Current directory: $current_dir"

# Create a Prettier configuration file
cat > .prettierrc.yaml << EOF
plugins:
- "/usr/local/lib/node_modules/prettier-plugin-java/dist/index.js"
EOF

# Create a Prettier ignore file
cat > .prettierignore << EOF
# Ignore artifacts:
.azure-devops
.devcontainer
.gradle
.history
.vscode
.git
bin
build
EOF

# Create a lint-staged configuration file
cat > .lintstagedrc.json << EOF
{
"*.+(java)": ["prettier --write"],
"*.+(json)": ["prettier --write"],
"*.+(md)": ["prettier --write"],
"*.+(yaml|yml)": ["prettier --write"]
}
EOF

# Check if the current directory is a Git repository, initialize if not
if [ ! -d ".git" ]; then
git init
fi

# Configure Git to avoid ownership check issues
git config --global --add safe.directory "$current_dir"

# Create .husky directory and initialize Husky
mkdir -p .husky
# Install Git hooks
husky install

# If .husky/pre-commit hook does not exist, add npx lint-staged command
if ! grep -q "npx lint-staged" .husky/pre-commit; then
npx husky add .husky/pre-commit "npx lint-staged"
fi

# Create a commitlint configuration file
cat > commitlint.config.js << EOF
module.exports = {
extends: ['/usr/local/lib/node_modules/@commitlint/config-conventional']
};
EOF

# If .husky/commit-msg hook does not exist, add commitlint command
if ! grep -q "commitlint --edit" .husky/commit-msg; then
npx husky add .husky/commit-msg 'npx --no-install commitlint --edit'
fi
  1. Initial Setup and Diagnostics:

    • The script starts by setting bash flags for error handling and outputting the current user and directory, which is helpful for debugging and verification.
  2. Configuring Prettier:

    • It creates a .prettierrc.yaml to specify Prettier plugins, particularly for Java, and a .prettierignore to exclude certain files and directories from formatting.
  3. Setting Up lint-staged:

    • A .lintstagedrc.json is created, configuring lint-staged to run Prettier on staged files of specific types, thus ensuring code consistency before commits.
  4. Initializing and Configuring Git:

    • The script checks if the current directory is a Git repository and initializes one if needed. It also configures Git to recognize the current directory as safe, avoiding potential ownership issues.
  5. Husky and Git Hooks Configuration:

    • Husky is initialized for managing Git hooks, and a pre-commit hook is set up to run lint-staged, ensuring that code is formatted before each commit.
  6. Setting Up commitlint:

    • A commitlint.config.js is created to define rules for commit messages, ensuring they follow the conventional commit format.
  7. Adding Husky Commit Message Hook:

    • A commit message hook is added to enforce commitlint rules, validating commit messages against the configured standards.

Impact on Development Workflow

The postCreateCommand.sh script transforms your Dev Container into an environment that not only supports Java development but also enforces best practices for code quality and consistency. It automates the setup of crucial tools like Prettier and Husky, saving time and ensuring that your project adheres to professional standards right from the start.

Seamless SSH Experience on MacOS

Incorporating a seamless SSH setup into your VS Code Dev Containers on MacOS can significantly enhance your development workflow. This integration is particularly beneficial for tasks like pushing to and pulling from Git repositories, including GitHub, within your containerized development environment.

Overview of SSH Integration in Dev Containers

  1. SSH Key Management:

    • Creating separate SSH key pairs for different scenarios, such as a dedicated key for GitHub, stored in the ~/.ssh directory. Each key should be secured with a passphrase for enhanced security.
  2. MacOS Keychain and SSH Agent Integration:

    • The integration of MacOS Keychain with SSH Agent simplifies the process of managing SSH keys. By doing this, you can bypass the manual passphrase entry when using private keys inside the container.
  3. Automating Key Loading:

    • To ensure SSH keys are automatically available after system reboots, a specific command is added to shell initialization files like .zshrc or .bashrc.

Setting Up SSH for a Smooth Workflow

  1. Adding Keys to MacOS Keychain:

    • Using the command ssh-add --apple-use-keychain ~/.ssh/id-github-ed25519, private keys are added to the SSH Agent and their passphrases are stored in the MacOS Keychain. This setup unlocks keys automatically upon user login.
  2. Ensuring Persistent Configuration Across Reboots:

    • The command ssh-add --apple-load-keychain &> /dev/null is added to your shell initialization file to maintain the SSH configuration across reboots.

Integrating SSH with VS Code Dev Containers

With this SSH setup, there’s no need for additional configuration in VS Code or the devcontainer.json file. Your Dev Container can interact seamlessly with any remote destinations requiring SSH authentication, enhancing the ease and security of your development activities.

Emphasizing OS-Agnostic Development Practices

This approach advocates for keeping Dev Containers OS-agnostic. Rather than configuring VS Code to look for SSH keys, the preferred method is configuring the operating system to make the SSH keys available to the Agent. This philosophy aligns with broader compatibility and flexibility across different operating systems.

This SSH setup in VS Code Dev Containers on MacOS not only facilitates easier access to remote services but also adheres to security best practices. It exemplifies how integrating system-level features like MacOS Keychain with development tools can streamline your workflow.

Expanded Practical Use Cases

Using Prettier for Code Formatting

Prettier is a popular code formatter that helps maintain consistent code styling across your project. Here’s how to use Prettier effectively in your Java development environment within a VS Code Dev Container:

  1. Configuring Prettier:

    • As set up in your postCreateCommand.sh, a .prettierrc.yaml file configures Prettier’s behavior, including specifying plugins like prettier-plugin-java.
  2. Ignoring Files:

    • The .prettierignore file excludes certain directories and files from being formatted, such as build directories or external libraries.
  3. Running Prettier:

    • Manually format your code by running prettier --write . in your project root. This command will format all supported files according to your Prettier configuration.
    • For automated formatting, lint-staged is configured to run Prettier on staged files before a commit is made, ensuring consistent code styling.

Crafting Effective Git Commit Messages

Commit messages are crucial for understanding the history of your project and the purpose of each change. Here’s how to write effective commit messages and how commitlint enforces these standards:

  1. Commit Message Structure:

    1
    2
    3
    4
    5
    <type>(<scope>): <subject>
    <BLANK LINE>
    <body>
    <BLANK LINE>
    <footer>
    • A conventional commit message includes a type, scope, and subject: type(scope): subject. For example, feat(database): add new query functions.
    • Optional body and footer provide additional information and issue references, respectively.
  2. Type:

    • Indicates the kind of change (e.g., feat for a new feature, fix for a bug fix).

      Using the right type in your commit messages is crucial for conveying the nature of the changes made. Here’s an overview of common types and their intended uses:

  • build:

    • Changes that affect the build system or external dependencies (example scopes: gulp, broccoli, npm).
  • chore:

    • Routine tasks or maintenance that don’t modify either the source code or test files.
  • ci:

    • Changes to your CI configuration files and scripts (examples: Travis, Circle, BrowserStack, SauceLabs).
  • docs:

    • Documentation-only changes, such as updates to the README, API docs, etc.
  • feat:

    • Introducing new features or enhancements to existing ones.
  • fix:

    • Bug fixes, correcting unexpected behavior in the code.
  • perf:

    • Performance improvements, optimizations that improve efficiency.
  • refactor:

    • Code changes that neither fix a bug nor add a feature but improve the codebase (like improving code readability).
  • revert:

    • Reverting a previous commit. The message should indicate which commit is being reverted.
  • style:

    • Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc).
  • test:

    • Adding or correcting tests. Includes all changes that affect testing only.

Example Usage:

  • Feature Addition: feat(auth): add oauth login support
  • Bug Fix: fix(api): resolve endpoint routing issue
  • Documentation Update: docs: update README with usage instructions
  • Performance Improvement: perf(database): optimize query indexing
  • Code Refactoring: refactor: restructure user service for clarity
  • Style Correction: style: align code formatting with Prettier standards
  • Adding Tests: test: add unit tests for user controller
  1. Scope (optional):

    • Specifies the part of the codebase affected (e.g., database, UI).
  2. Subject:

    • A brief description of the change in imperative mood (e.g., add, not adds or added).
  3. Body (optional):

    • Provides a more detailed explanation of the change.
  4. Footer (optional):

    • References issues affected by the change (e.g., Closes #123).

Example of a Well-Formed Commit Message:

1
2
3
4
5
6
feat(authentication): implement token-based authentication

- Add JWT support for secure user authentication.
- Update login and registration logic to use tokens.

Closes #456, Refs #789

In this example:

  • Type: feat (new feature)
  • Scope: authentication
  • Subject: implement token-based authentication
  • Body: Detailed explanation of what was added and how.
  • Footer: Indicates related issues.

Enforcing Standards with commitlint

Commitlint checks if your commit messages follow the conventional format. It’s configured in your Dev Container to run automatically with Husky’s commit-msg hook. If a commit message doesn’t meet the standard, commitlint will prevent the commit, prompting you to follow the project’s commit conventions.

By integrating Prettier and commitlint in your Dev Container setup, you ensure that your project maintains high standards in code quality and commit message clarity, enhancing readability and maintainability of your codebase.

Adding launch.json for Enhanced Java Debugging in VS Code

A crucial aspect of developing in VS Code is setting up efficient debugging configurations. This is where the .vscode/launch.json file comes into play, especially for Java applications. It allows you to define various debugging scenarios, making your development process more efficient and tailored to your specific project needs.

Understanding launch.json in VS Code

The launch.json file is a configuration file that specifies how VS Code should launch and debug your application. It defines various debugging profiles, each tailored to different aspects or parts of your application.

Configuring launch.json for Java

Here’s how you can set up your launch.json for a Java project:

  1. Navigate to Your Project’s .vscode Directory: This is where your configuration files for VS Code reside.
  2. Create or Modify the launch.json File: If it doesn’t exist, create a new file named launch.json.
  3. Configure Debugging Profiles:
    • Each entry in the configurations array represents a different debugging scenario.
    • Commonly used attributes for Java debugging include:
      • type: Specifies the language of the debugger.
      • name: A user-friendly name for the debugging profile.
      • request: Type of request, typically launch for starting the application.
      • mainClass: The main class to be executed.
      • projectName: The name of the project, useful in multi-project workspaces.
      • env: Environment variables necessary for your application.

Example launch.json for Java

Here’s an example configuration suitable for a Java project:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
{
"version": "0.2.0",
"configurations": [
{
"type": "java",
"name": "Current File",
"request": "launch",
"mainClass": "${file}"
},
{
"type": "java",
"name": "AiApplication",
"request": "launch",
"mainClass": "com.lama.ai.AiApplication",
"projectName": "hephaestus",
"env": {
"spring.profiles.active": "dev-env,dev"
}
}
]
}

In this configuration:

  • The first profile "Current File" is set to debug the currently opened Java file.
  • The second profile "AiApplication" is configured to launch a specific application (AiApplication), with environment variables set for Spring profiles.

Benefits of Using launch.json in Java Development

  • Flexibility: Easily switch between different parts of your application for debugging.
  • Customization: Tailor debugging settings to the needs of different components or environments in your application.
  • Efficiency: Speeds up the debugging process by pre-defining the necessary configurations.

Adding a launch.json file to your VS Code Java project significantly enhances your debugging capabilities, making your development process more streamlined and efficient.

For more information on debugging configurations in VS Code, refer to the official VS Code documentation on debugging.

Integrating a launch.json file into your Java development setup in VS Code Dev Containers is a step forward in optimizing your development workflow. It allows you to tailor your debugging process to the specific needs of your project, thereby enhancing productivity and efficiency.

References

The following resources provide additional insights and guidance on the topics covered in this article. They offer a deeper understanding of best practices, tools, and methodologies that can enhance your development workflow:

  1. Conventional Commits:

  2. Git Commit Message Writing:

  3. Angular’s Commit Message Guidelines:

  4. Commit Message and Changelog Writing Guide:

  5. Git Commit Templates in IntelliJ:

  6. SSH Setup for Dev Containers on MacOS:

  7. Husky: Git Hooks Tool:

    • husky - Official documentation for Husky, a tool for managing Git hooks in your project.
  8. Development Containers:

These resources serve as valuable references for deepening your understanding and enhancing your skills in key areas of modern software development.