Part 2: Development Environment Setup & Debugging

🧭 Series Navigation:

⬅️ Introduce AdventureTube Microservice Hub
⬅️ Part 1: Architecture Overview & Design Patterns
βœ… Part 2: Development Environment & Debugging (Current)
▢️ Part 3: Testing Strategies
▢️ Part 4: CI/CD Deployment with Jenkins


Fast Microservice Development: IntelliJ Setup & Debugging Mastery

Stop rebuilding Docker containers every code change – here’s how pros develop microservices

In Part 1, we explored the three-layer architecture that powers AdventureTube. Now let’s dive into the development workflow that makes working with this complex system both efficient and enjoyable. Today I’ll show you my lightning-fast development approach that eliminates the need to rebuild Docker containers for every code change.

Why Hybrid Development Beats Pure Docker

During my first two weeks of AdventureTube development, I made the classic mistake: rebuilding Docker containers for every small code change. This approach was killing my productivity and making debugging a nightmare.

Here’s what I learned: Docker is perfect for infrastructure, but terrible for active development. My solution? A hybrid approach:

  • Infrastructure Layer: Run in Docker (PostgreSQL, MongoDB, Redis)
  • Platform Layer: Run in Docker (Eureka, Config Server, Gateway)
  • Business Layer: Run locally in IntelliJ for development

This gives you the best of both worlds: production-like infrastructure with development-friendly iteration speed.

Project Structure Walkthrough

Let me show you how the AdventureTube project is organized for maximum development efficiency:

Multi-Module Maven Structure

adventuretube-microservice/
β”œβ”€β”€ auth-service/           # Authentication & JWT management
β”œβ”€β”€ member-service/         # User profile management  
β”œβ”€β”€ geospatial-service/     # Location-based features
β”œβ”€β”€ web-service/           # Frontend interface
β”œβ”€β”€ common-api/            # Shared components & DTOs
β”œβ”€β”€ config/               # Configuration files
β”‚   └── env.mac          # Development environment variables
└── docker/              # Docker Compose files
    β”œβ”€β”€ docker-compose-storages.yml
    β”œβ”€β”€ docker-compose-clouds.yml
    └── docker-compose-adventuretubes.yml

Key Configuration Files

CLAUDE.md: Development guidelines and project documentation
env.mac: Environment configuration for local development
application.yml: Service-specific configurations
pom.xml: Maven multi-module project structure

Environment Configuration Deep Dive

The secret to seamless development is proper environment configuration. Here’s how I set up the configuration hierarchy:

Configuration Sources (Priority Order)

  1. Environment Variables (Highest Priority)
  2. Config Server Properties
  3. Local application.yml (Fallback)

Development Environment Setup

My env.mac file contains all the essential configuration:

# Config Server Connection
CONFIG_SERVER_URL=http://192.168.1.105:9297

# Security Configuration  
JWT_SECRET=p1tX8G1LEA75ztxooQQ58iReDB6buWJ8wf9T+uWSyTk=

# Service Ports
AUTH_SERVICE_PORT=8010
MEMBER_SERVICE_PORT=8070
GEOSPATIAL_SERVICE_PORT=8060

# Database Connections
POSTGRES_HOST=//adventuretube.net:5432/adventuretube
MONGODB_HOST=mongodb://192.168.1.105:27017/adventuretube

# Infrastructure Services
EUREKA_SERVER_URL=http://192.168.1.105:8761/eureka
GATEWAY_URL=http://192.168.1.105:8030

Profile Management Strategy

I use different profiles for different environments:

  • default: Basic configuration
  • mac: Local development on macOS
  • pi2: QA environment on Raspberry Pi
  • prod: Production environment

Service Initialization Process

Let me walk you through exactly what happens when I start the auth-service in IntelliJ:

Step-by-Step Startup Flow

1. Spring Boot Startup

The service begins initialization with Spring Boot’s auto-configuration:

INFO: Starting AuthServiceApplication using Java 17
INFO: The following profiles are active: mac

2. Config Server Connection

Service fetches configuration from the centralized config server:

INFO: Fetching config from server at: http://192.168.1.105:9297
INFO: Located environment: name=auth-service, profiles=[mac]

3. Database Connection

HikariCP establishes the PostgreSQL connection pool:

INFO: HikariPool-1 - Starting...
INFO: HikariPool-1 - Start completed.

4. Security Configuration

JWT authentication and security filters are configured:

INFO: Initializing JWT authentication provider
INFO: RSA key pair loaded successfully

5. Service Registration

Finally, the service registers with Eureka for discovery:

INFO: Registering application AUTH-SERVICE with eureka
INFO: Renewal threshold updated to: 1

IntelliJ Debugging Setup

Here’s how I configure IntelliJ for optimal microservice debugging:

Run Configuration Setup

  1. Main Class: com.adventuretube.auth.AuthServiceApplication
  2. VM Options: -Dspring.profiles.active=mac
  3. Environment Variables: Load from env.mac file
  4. Working Directory: Project root directory

Strategic Breakpoint Placement

For maximum debugging effectiveness, I place breakpoints at these key locations:

  • JWT Token Generation: JwtUtil.generateToken()
  • Authentication Flow: Custom authentication provider
  • Database Queries: Repository method calls
  • Exception Handling: GlobalExceptionHandler methods

Hot Reload with DevTools

Spring Boot DevTools enables automatic restart when code changes:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-devtools</artifactId>
    <scope>runtime</scope>
    <optional>true</optional>
</dependency>

This means I can modify code, and the service automatically restarts without losing my debugging session or infrastructure connections.

Common Development Workflows

Adding a New Endpoint

  1. Create the controller method in IntelliJ
  2. Set breakpoint for immediate testing
  3. DevTools automatically restarts the service
  4. Test the endpoint via Swagger UI or Postman
  5. Debug and iterate without container rebuilds

Debugging Authentication Issues

  1. Place breakpoints in JwtAuthenticationFilter
  2. Monitor token validation process
  3. Inspect user details retrieval
  4. Verify role and permission assignment

Database Query Optimization

  1. Enable SQL logging in application.yml
  2. Set breakpoints in repository methods
  3. Analyze query execution plans
  4. Test performance improvements in real-time

Troubleshooting Common Issues

Config Server Connection Failures

Problem: Service can’t reach config server
Solution: Check network connectivity and config server status

# Test config server connectivity
curl http://192.168.1.105:9297/auth-service/mac

Environment Variable Resolution

Problem: Configuration not loading correctly
Solution: Verify environment variable precedence and profile activation

Database Connection Problems

Problem: Can’t connect to PostgreSQL
Solution: Check database container status and connection strings

# Check database connectivity
docker ps | grep postgres
telnet adventuretube.net 5432

Service Registration Failures

Problem: Service not appearing in Eureka dashboard
Solution: Verify Eureka server accessibility and network configuration

Development Performance Benefits

This hybrid development approach delivers massive productivity improvements:

  • ⚑ Fast Development Cycle: No Docker rebuilds for code changes
  • πŸ› Full Debugging Capabilities: Native IntelliJ debugger support
  • πŸ”„ Hot Reload: Automatic restart with DevTools
  • 🎯 Production-like Configuration: Real infrastructure services
  • πŸ“Š Real-time Monitoring: Direct access to Eureka and database

What’s Next?

Now that you have a lightning-fast development environment set up, you’re ready to ensure your microservices are rock-solid with comprehensive testing strategies.

🧭 Continue Learning My Approach:

⬅️ Introduce AdventureTube Microservice Hub
⬅️ Part 1: Architecture Overview & Design Patterns
βœ… Part 2: Development Environment & Debugging (Current)
▢️ Part 3: Testing StrategiesComprehensive testing approaches across all three layers
▢️ Part 4: CI/CD DeploymentAutomated deployment of all Docker Compose layers

In Part 3, I’ll show you my comprehensive testing strategy that covers unit tests, integration tests, API testing, and how to test microservices that depend on external infrastructure like config servers and databases.


Tags: #Microservices #SpringBoot #IntelliJ #Development #Debugging #DevTools

Categories: BACKEND(spring-microservice), Development

Leave a Comment

Your email address will not be published. Required fields are marked *