DEV Community

Cover image for Building vtracer: Day 1 – My First Java Agent Adventure with Java 21
Abhi
Abhi

Posted on

Building vtracer: Day 1 – My First Java Agent Adventure with Java 21

Hey Dev.to community! πŸ‘‹

I'm Abhishek, a Java enthusiast diving deep into the JVM internals. I'm building vtracer – a low-overhead JVM agent for runtime tracing and virtual thread pinning detection.

This is Day 1 of my journey. Today, I built the foundation: a simple Java agent that loads and prints a message.

Let's dive in!

Why Java Agents? The Magic Behind the JVM

Java agents are powerful tools that let you instrument code at runtime using the Instrumentation API. They can modify bytecode, add logging, monitor performance, or even implement AOP – all without changing the original code.

Agents load in two ways:

  • Static: -javaagent at startup
  • Dynamic: Attach to running JVM

Today, we focused on static attach – the basics.

Step-by-Step: My First Premain Agent

  1. Maven Project Setup

    Created a simple Maven project with Java 21.

  2. pom.xml with Agent Manifest

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-jar-plugin</artifactId>
            <configuration>
                <archive>
                    <manifestEntries>
                        <Premain-Class>com.example.vtracer.Agent</Premain-Class>
                        <Can-Redefine-Classes>true</Can-Redefine-Classes>
                        <Can-Retransform-Classes>true</Can-Retransform-Classes>
                    </manifestEntries>
                </archive>
            </configuration>
        </plugin>
    </plugins>
</build>
Enter fullscreen mode Exit fullscreen mode
  1. Agent Class
package com.example.vtracer;

import java.lang.instrument.Instrumentation;

public class Agent {
    public static void premain(String agentArgs, Instrumentation inst) {
        System.out.println("[vtracer] Agent loaded successfully via premain");
        System.out.println("[vtracer] Instrumentation: " + inst);
        System.out.println("[vtracer] Ready for instrumentation – Day 1 complete!");
    }
}
Enter fullscreen mode Exit fullscreen mode
  1. Build & Run
mvn clean package
java -javaagent:target/vtracer-1.0.jar TestApp
Enter fullscreen mode Exit fullscreen mode

Output:

[vtracer] Agent loaded successfully via premain
[vtracer] Instrumentation instance: sun.instrument.InstrumentationImpl@...
[vtracer] Ready for instrumentation – Day 1 complete!
Test app running...
Test app finished
Enter fullscreen mode Exit fullscreen mode

What I Learned Today

  • premain runs before main
  • Manifest entries are mandatory
  • Instrumentation object gives power to transform classes

This is just the beginning – next, ByteBuddy for method timing!

What's Next?

Day 2: Method entry/exit timing with ByteBuddy.

Follow my journey on GitHub: https://github.com/abhishek-mule/vtracer

Star ⭐ if you're excited about JVM internals!

java #jvm #java21 #agents #bytecode

Thanks for reading! Let's build cool stuff together. πŸš€

β€” Abhishek Mule

(Comment below if you're building something similar!)

Top comments (0)