Skip to content

Getting Started

Frody edited this page Sep 4, 2026 · 1 revision

Getting Started with LoomDoctor

This guide walks you through adding LoomDoctor to your Java 21+ or Spring Boot 3 application.

Prerequisites

  • Java: Version 21 or higher (LTS recommended).
  • Build Tool: Maven 3.8+ or Gradle 8+.
  • Spring Boot (optional): Version 3.2+ when using the starter.

Maven Dependency

Spring Boot 3 Applications

Add the official starter to your pom.xml:

<dependency>
    <groupId>io.github.frodygr</groupId>
    <artifactId>loomdoctor-spring-boot-starter</artifactId>
    <version>1.0.0</version>
</dependency>

Standalone Java Applications

If you are not using Spring Boot, import loomdoctor-core:

<dependency>
    <groupId>io.github.frodygr</groupId>
    <artifactId>loomdoctor-core</artifactId>
    <version>1.0.0</version>
</dependency>

Recommended JVM Flags

To enable JVM-level native pinning events when launching your application, supply:

java -Djdk.tracePinnedThreads=short -jar application.jar
  • short: Prints a truncated stack trace on pinning.
  • full: Prints complete stack traces including carrier thread details.

Basic Usage

Standalone Core

import io.github.frodygr.loomdoctor.core.LoomDoctor;
import io.github.frodygr.loomdoctor.core.metrics.LoomDiagnosticsReport;
import io.github.frodygr.loomdoctor.core.pinning.PinningEventType;

public class App {
    public static void main(String[] args) {
        LoomDoctor doctor = new LoomDoctor();

        // Simulate recording a pinning incident detected during profiling
        doctor.getPinningDetector().recordPinning(
            PinningEventType.SYNCHRONIZED_BLOCK,
            "VirtualThread[#42,pool-1-thread-2]",
            "ForkJoinPool-1-worker-3",
            125, // duration in milliseconds
            "com.example.LegacyService.fetchLegacyData(LegacyService.java:88)",
            "java.lang.Thread.sleep at com.example.LegacyService.fetchLegacyData..."
        );

        // Register a database connection pool for starvation monitoring
        doctor.getStarvationDetector().registerPool("HikariCP-Main", 10, 50);

        // Run full diagnostic report
        LoomDiagnosticsReport report = doctor.diagnose();
        System.out.println("Health: " + report.getStatus());
        System.out.println("Pinning Count: " + report.getTotalPinningCount());
        report.getRecommendations().forEach(System.out::println);
    }
}

Spring Boot 3 Integration

With loomdoctor-spring-boot-starter, the LoomDoctor bean is registered automatically.

  1. Enable the Actuator endpoint in src/main/resources/application.yml:
loomdoctor:
  enabled: true
  pinning-threshold-ms: 50
  queue-starvation-ratio: 2.0

management:
  endpoints:
    web:
      exposure:
        include: "health,info,loom-doctor"
  1. Access the diagnostic report in your browser or monitoring scripts:
curl http://localhost:8080/actuator/loom-doctor

Sample JSON response:

{
  "status": "DEGRADED",
  "totalPinningCount": 1,
  "recentPinning": [
    {
      "eventType": "SYNCHRONIZED_BLOCK",
      "virtualThreadName": "VirtualThread[#42,pool-1-thread-2]",
      "carrierThreadName": "ForkJoinPool-1-worker-3",
      "durationMs": 125,
      "location": "com.example.LegacyService.fetchLegacyData(LegacyService.java:88)",
      "timestamp": "2026-09-04T10:15:30Z"
    }
  ],
  "pools": [
    {
      "poolName": "HikariCP-Main",
      "activeConnections": 10,
      "queuedThreads": 50,
      "waitRatio": 5.0,
      "starvationAlert": true
    }
  ],
  "recommendations": [
    "Pinning Alert: 1 pinning events recorded. Replace synchronized blocks holding I/O with ReentrantLock.",
    "Connection Starvation: One or more database connection pools have excessive queued threads. Increase pool size or throttle incoming concurrent requests."
  ],
  "timestamp": "2026-09-04T10:15:31Z"
}