Simplifying Java Development with VS Code DevContainer and Google Cloud Workstations

Developers often face challenges in setting up consistent and reliable environments across teams. With the rapid pace of technological advancement, tools like VS Code DevContainer and Google Cloud Workstations have become invaluable in standardizing development setups. This guide walks you through creating a robust Java development environment tailored to modern needs.

All configurations and scripts mentioned in this post are available in the Java Development Environment Template repository. Feel free to explore and adapt it to your needs.

✨ Key Features

  • Java 21 (Liberica JDK)
  • VS Code DevContainer support
  • Google Cloud Workstations integration
  • Git hooks for automated code formatting
  • Pre-configured development tools
  • Ready-to-use development setup

Table of Contents

Using VS Code DevContainer

Prerequisites

Quick Start

  1. Copy the .devcontainer directory
  2. Ensure Docker Desktop is running
  3. Open the project directory in VS Code
  4. VS Code will detect the .devcontainer directory and prompt to reopen the project in container
  5. Click “Reopen in Container” in the bottom-right corner or click the green button “><” in the bottom-left corner and select “Reopen in Container”

Additional Information

The development container provides:

  • Pre-installed Java 21 (Liberica JDK)
  • VS Code extensions for Java development

After container creation, the following setup is automatically performed:

  1. Installation of Google Java Formatter
  2. Configuration of Git Hooks

Note: Git configurations are automatically synchronized from the host machine to the container (Mac)

Using Google Cloud Workstations

Building Workstations Image

Open workstations/cloudbuild.yaml and modify the following variables:

  • _PROJECT_ID: Your GCP project ID
  • _REPOSITORY_NAME: Your Artifact Registry repository name
  • _IMAGE_NAME: Your Workstations image name
  • _IMAGE_TAG: Your Workstations image version

Then run the following commands:

1
2
3
4
export PROJECT_ID={Your GCP project ID}

cd workstations
gcloud builds submit --config=cloudbuild.yaml --project=${PROJECT_ID}

This will build and push a Docker image with pre-installed Java 21 environment to Artifact Registry.

Setting up Workstations Environment

Step 1: Create a Workstation Cluster

Navigate to Google Cloud Workstations page, select Cluster Manager, and create a Workstation Cluster.

Cluster Manager

Create Workstation Cluster

After creation is complete:

Workstation Cluster

Next, select Workstation Configurations:

Workstation Configurations

Step 2: Create Workstation Configuration

  1. Basic Information

    • Name: config-spring
    • Select your created cluster
    • Quick start: Disabled (recommended for lower costs)
  2. Labels and Tags

    • Labels: Add labels to categorize and manage resources
    • Tags: Add tags to categorize and manage resources

Basic Information

  1. Machine Configuration
    • Series: Choose based on your needs:
      • N2: Recommended for development
      • E2: Cost-optimized general purpose workloads
      • T2D: AMD-based alternative with good price/performance ratio
    • Machine type: Select based on your development requirements:
      • n2-standard-2 (2 vCPU, 8 GB memory): Light development
      • n2-standard-4 (4 vCPU, 16 GB memory): Standard development
      • n2-standard-8 (8 vCPU, 32 GB memory): Heavy development
    • Zones: asia-east1-a and asia-east1-c
    • Auto-sleep: After 2 hours of inactivity (recommended for cost savings)

Note: Cost estimate for n2-standard-4 (asia-east1)

  • Hourly rate: $0.224904
  • Daily usage: 9 hours
  • Monthly working days: 20 days
  • Monthly cost estimate: $0.224904 × 9 × 20 = ~$40.48

Cost saving tips:

  1. Use Auto-sleep feature
  2. Stop workstation when not in use

Machine Settings

  1. Environment Settings
    • Container image: Custom container image
    • Container image URL: asia-east1-docker.pkg.dev/${PROJECT_ID}/${REPOSITORY_NAME}/${IMAGE_NAME}:${IMAGE_TAG}
    • Service account: Compute Engine default service account
    • Storage: Create new empty persistent disk
    • Disk type: Balanced

Environment Settings

  1. Access Control
    • Users and permissions: Users can create workstations through the console
    • Add authorized users or groups as needed
    • Keep Advanced options as default

Users and Permissions

Click CREATE to complete the configuration:

Workstation Configurations

Step 3: Create a Workstation

Navigate to the Workstations page:

Workstations

Click CREATE WORKSTATION and configure the following:

Create Workstation

Configure the following settings:

  • Name: (e.g., w-samzhucn480th9v)
  • Display Name: (e.g., sam)
  • Configuration: Select your created configuration (e.g., config-spring)

Create Workstation

After creation, your workstation will appear:

your Workstation

Using Your Workstation

Start your workstation and click the Launch button to access it:

Launch Workstation

The environment comes pre-configured with Java 21, Google Java Format tool, and predefined extensions:

Workstation Environment

Gemini Code Assistant

You can also enable Gemini Code Assistant to help with development:

Gemini Code Assistant

Your development environment is now ready for Java development with all necessary tools and extensions installed.

Quick Install Git Hooks

Run the following command to install Git Hooks. This will automatically configure the pre-commit hook for Java code formatting:

1
curl -fsSL https://raw.githubusercontent.com/samzhu/java-dev-env-template/main/workstations/install-java-format-hooks.sh | bash

Creating a Spring Boot Project

Spring Boot CLI is pre-installed in the environment for quick project creation.

1
2
3
4
5
mkdir workspace && cd workspace

spring init --java-version=21 --dependencies=web,actuator sample-app.zip

unzip sample-app.zip -d sample-app

After extraction, open the sample-app directory in VS Code to start developing your Spring Boot application.

Additional Spring CLI Commands

Use spring init --list to view all available options:

  • Dependencies: View all supported dependencies
  • Java versions: Check supported Java versions
  • Project types: See available project types
  • Packaging options: JAR or WAR
  • Language options: Java, Kotlin, or Groovy

You can type spring help to get more details spring help init.

Common usage examples:

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
# Create a Gradle project with Java
spring init --type=gradle-project \
--java-version=21 \
--dependencies=web,data-jpa \
my-gradle-app.zip

# Create a project with custom name and description
spring init --name=MyApp \
--description="My Spring Boot Application" \
--package=com.example.myapp \
custom-app.zip

# Common Spring Boot Dependencies
spring init --type=gradle-project \
--language=java \
--boot-version=3.4.1 \
--packaging=jar \
--java-version=21 \
--groupId=com.example \
--artifactId=demo \
--name=demo \
--description="Demo project for Spring Boot" \
--package-name=com.example.demo \
--dependencies=devtools,lombok,configuration-processor,docker-compose,web,oauth2-client,postgresql,data-jpa,batch,validation,actuator,sbom-cyclone-dx,otlp-metrics,cloud-resilience4j,cloud-feign,prometheus,distributed-tracing,testcontainers \
demo.zip

Common Dependencies Explained

  • web: Web application development with Spring MVC and embedded Tomcat
  • devtools: Development tools including automatic restart and live reload
  • lombok: Annotation-based code generator to reduce boilerplate
  • configuration-processor: Metadata generation for custom configuration properties
  • docker-compose: Integration with Docker Compose for container orchestration
  • oauth2-client: OAuth 2.0 client support for authentication
  • postgresql: PostgreSQL JDBC driver and database connectivity
  • data-jpa: JPA data persistence with Hibernate
  • batch: Batch processing framework for enterprise applications
  • validation: Bean validation using Hibernate Validator
  • actuator: Production-ready features for monitoring and management
  • sbom-cyclone-dx: CycloneDX SBOM format for software supply chain security
  • otlp-metrics: OpenTelemetry protocol support for metrics export
  • cloud-resilience4j: Circuit breaker and fault tolerance patterns
  • cloud-feign: Declarative REST client with Netflix Feign
  • prometheus: Prometheus metrics collection and monitoring
  • distributed-tracing: Distributed tracing with OpenTelemetry
  • testcontainers: Container-based integration testing framework