Skip to content

Commit 9d1c5b6

Browse files
committed
Create default CLAUDE file
1 parent 26a9d2f commit 9d1c5b6

1 file changed

Lines changed: 175 additions & 0 deletions

File tree

CLAUDE.md

Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
# CLAUDE.md
2+
3+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4+
5+
## Project Overview
6+
7+
This is the New Relic Java Agent, a bytecode instrumentation agent that monitors Java applications at runtime. The agent attaches via the `-javaagent` JVM flag, uses ASM (version 9.9.1) for bytecode manipulation, and employs a "weaver" pattern to insert monitoring code into target classes as they are loaded by the JVM classloader.
8+
9+
The agent captures transactions, traces, metrics, errors, and logs from 440+ supported frameworks and libraries, sending telemetry data to the New Relic platform.
10+
11+
The product optimizes for:
12+
- safety and stability above all else (should never crash the JVM being monitored)
13+
- minimal impact on CPU and memory resources of the JVM being monitored
14+
- backwards compatibility targeting the Java 8 runtime
15+
- collection of application profiling data that is useful and accurate
16+
- clarity over cleverness
17+
- accessible object-oriented design
18+
19+
Avoid over-engineering. If a simpler solution exists, use it.
20+
21+
## Critical Constraints
22+
23+
These rules are non-negotiable:
24+
25+
- **Java 8 language level** for all production code (no newer language features)
26+
- **Do NOT use lambda expressions in weaver instrumentation modules** — the weaver's bytecode rewriting cannot reliably transform lambdas due to `invokedynamic` bootstrap methods and classloader isolation; use anonymous classes instead
27+
- **Do NOT change public APIs** without explicit instructions
28+
- **Do NOT change weaver code** without explicit instructions
29+
- **Preserve backward compatibility** for all shared components
30+
- **Flag major architectural changes** before implementing — don't just do it
31+
- **Instrumentation modules must be self-contained** — dependencies must be shaded
32+
- **New dependencies require shading and licensing** — only add if they provide significant value and always ask for permission first
33+
34+
## Tech Stack
35+
36+
- Gradle for build and dependency management
37+
- JUnit + Mockito for tests
38+
- ASM 9.9.1 for bytecode manipulation
39+
- Caffeine for high-performance caching
40+
- Apache `HttpClient` for data transport to the New Relic backend
41+
- Shadow Gradle plugin for relocating packages of project dependencies
42+
- Spotbugs for static code analysis
43+
- Jacoco for code coverage
44+
45+
## Key File Paths
46+
47+
| Entry Point | Path |
48+
|-----------------------|-----------------------------------------------------------------------------------|
49+
| Agent bootstrap | `newrelic-agent/src/main/java/com/newrelic/bootstrap/BootstrapAgent.java` |
50+
| Configuration | `newrelic-agent/src/main/java/com/newrelic/agent/config/AgentConfigImpl.java` |
51+
| Service registry | `newrelic-agent/src/main/java/com/newrelic/agent/service/ServiceManagerImpl.java` |
52+
| Weave engine | `newrelic-weaver/src/main/java/com/newrelic/weave/ClassWeave.java` |
53+
| Weave manifest cache | `gradle/script/cache_weave_attributes.gradle.kts` |
54+
| Code style definition | `dev-tools/code-style/java-agent-code-style.xml` |
55+
56+
## Architecture
57+
58+
The agent uses Java's `Instrumentation` API (JSR 163) with two entry points in `BootstrapAgent`:
59+
60+
```
61+
premain(String agentArgs, Instrumentation inst) ← normal startup via -javaagent
62+
agentmain(String agentArgs, Instrumentation inst) ← dynamic attach
63+
```
64+
65+
### Core Modules
66+
67+
| Module | Purpose |
68+
|--------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------|
69+
| `newrelic-agent` | Main agent implementation; ServiceManager, configuration, harvest cycle, data transport. Built as a shadow JAR with all dependencies relocated. |
70+
| `newrelic-weaver` | Bytecode weaving engine using ASM. Matches weave classes to target classes and applies transformations at class-load time. |
71+
| `newrelic-weaver-api` | Annotations for authoring weave classes (`@Weave`, `@WeaveAllImplementations`, `@NewField`, `@WeaveWithAnnotation`). |
72+
| `newrelic-api` | Public API for custom instrumentation (`@Trace`, `NewRelic.getAgent()`, custom events/metrics). Ships with no-op implementations. |
73+
| `agent-bridge` | Runtime bridge between instrumentation modules and agent core. Provides `AgentBridge` static facade with volatile references swapped in when agent loads. |
74+
| `agent-bridge-datastore` | Datastore-specific bridge interfaces (connection URL parsing, vendor detection, instance metrics). |
75+
| `agent-interfaces` | Internal agent interfaces shared across modules. |
76+
| `agent-model` | Shared data models (metric names, error data, custom insight events). |
77+
| `infinite-tracing` | Infinite Tracing via gRPC streaming to trace observer. |
78+
79+
### Instrumentation Modules (`instrumentation/`)
80+
81+
443+ modules, each targeting a specific framework/version (e.g., `spring-webmvc-6.0.0`, `kafka-clients-3.6.0`). Each module contains:
82+
- **Weave classes** (`@Weave`) — Code injected into target classes
83+
- **Utility classes** — Helpers available to woven code
84+
- **SkipIfPresent classes** — Conditions for when the module should not apply
85+
86+
Additional modules: Scala support (`newrelic-scala-api`, `newrelic-scala3-api`, Cats/ZIO/Monix integrations), build infrastructure (`buildSrc`, `instrumentation-build`), and test utilities (`functional_test`, `instrumentation-test`).
87+
88+
### Key Architectural Patterns
89+
90+
- **Classloader isolation** — Agent code on bootstrap and `JVMAgentClassLoader` classloaders, instrumentation in separate classloaders. `agent-bridge` classes are visible at runtime to instrumentation but follow a different compile-time dependency path.
91+
- **Manifest-based weave attributes** — Cached in JAR manifests to avoid scanning every class (see `cache_weave_attributes.gradle.kts`)
92+
- **Service lifecycle**`ServiceManager`/`ServiceFactory` manage all agent services
93+
- **Configuration-driven** — Extensive YAML-based configuration for selective features
94+
95+
## Coding Conventions
96+
97+
- Format code using `./gradlew googleJavaFormat` (verify with `./gradlew verifyGoogleJavaFormat`)
98+
- Use descriptive names; avoid acronyms where possible
99+
- Comments only when intent is non-obvious
100+
- No dead code or commented-out blocks in commits
101+
- Error handling must be explicit — no silent catches
102+
- Error messages must include what happened AND, if possible, what to do next
103+
- **Wide version compatibility** — instrumentation code may look overcomplicated for compatibility reasons; read all comments before changing
104+
105+
## Common Pitfalls
106+
107+
- **Don't `clean` unnecessarily** — The shadow JAR build for `newrelic-agent` is slow. Only use `clean` when switching branches or fixing stale class issues. For iterative development, `./gradlew :module:test` without `clean` is much faster.
108+
- **Instrumentation tests need the agent JAR** — Functional tests require `newrelic-agent/build/newrelicJar/newrelic.jar` to exist. Build it first with `./gradlew jar` if missing.
109+
- **Module-scoped tasks** — Always scope Gradle tasks to the module you're working on (e.g., `./gradlew :newrelic-agent:test`, `./gradlew :instrumentation:spring-webmvc-6.0.0:test`) rather than running repo-wide.
110+
- **Java version for newer modules** — If an instrumentation module targets Java 11+/17+, you must pass `-Ptest11` or `-Ptest17` to gradle or the instrumentation won't apply and tests will fail even though they appear to run.
111+
- **Docker for Testcontainers** — Some instrumentation tests require Docker. If tests fail with connection errors, check Docker is running.
112+
113+
## Testing and Quality
114+
115+
Before considering any task complete:
116+
1. Run `./gradlew :module:verifyGoogleJavaFormat` on modified modules
117+
2. Run `./gradlew :module:googleJavaFormat` to fix formatting if needed
118+
3. Run relevant tests for modified logic
119+
120+
Testing rules:
121+
- Unit tests for all reusable logic
122+
- Empty state, null state, and error state must all be handled
123+
124+
## File Placement
125+
126+
- Feature-specific logic that won't be reused → co-locate with the feature
127+
- Do not create a new abstraction for a one-off use case
128+
- Prefer editing an existing component over creating a near-duplicate
129+
130+
## Commands
131+
132+
### Build
133+
134+
JDK 8 is required (`JAVA_HOME` must point to JDK 8). Configure JDK paths in `~/.gradle/gradle.properties`:
135+
```
136+
jdk8=/path/to/jdk8
137+
jdk17=/path/to/jdk17
138+
```
139+
140+
Verify environment: `./gradlew --version` (should show JVM 1.8.x)
141+
142+
- Build agent jar only: `./gradlew clean jar --parallel`
143+
- Build agent with all checks: `./gradlew clean build --parallel`
144+
145+
**Artifacts:**
146+
- Agent: `newrelic-agent/build/newrelicJar/newrelic.jar`
147+
- API: `newrelic-api/build/libs/newrelic-api-*.jar`
148+
149+
### Code Analysis
150+
151+
- Run Spotbugs: `./gradlew :module:spotbugsMain`
152+
153+
### Tests
154+
155+
#### Unit Tests
156+
157+
- All unit tests: `./gradlew -PnoInstrumentation test --continue --parallel`
158+
- Single module: `./gradlew -PnoInstrumentation :newrelic-weaver:test --parallel`
159+
- Single test: `./gradlew -PnoInstrumentation :newrelic-weaver:test --tests "com.newrelic.weave.LineNumberWeaveTest.testRemoveWeaveLineNumbers" --parallel`
160+
- With specific JDK: add `-Ptest17`
161+
- Include Scala: add `-PincludeScala`
162+
163+
#### Functional Tests
164+
165+
Require the agent JAR to be built first (`./gradlew jar`).
166+
167+
- All: `./gradlew functional_test:test --continue --parallel`
168+
- Single: `./gradlew functional_test:test --tests test.newrelic.test.agent.AgentTest --parallel`
169+
170+
#### Instrumentation Tests
171+
172+
- Single module: `./gradlew :instrumentation:akka-http-core-10.0.11:test --parallel`
173+
- Single test: `./gradlew :instrumentation:vertx-web-3.2.0:test --tests com.nr.vertx.instrumentation.RoutingTest --parallel`
174+
- Scala module: `./gradlew -PincludeScala :instrumentation:sttp-2.13_2.2.3:test --parallel`
175+
- Java 17+ module: `./gradlew -Ptest17 :instrumentation:module-name:test --parallel`

0 commit comments

Comments
 (0)