Skip to content

Commit 212ce90

Browse files
committed
fix(java-agent): resolve checkstyle violations in rollbar-java-agent
1 parent 64e7df9 commit 212ce90

6 files changed

Lines changed: 86 additions & 18 deletions

File tree

rollbar-java-agent/src/main/java/com/rollbar/agent/NetworkEventBridge.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,11 @@ public static boolean markAsRecorded(Object key) {
3737
return RECORDED.add(key);
3838
}
3939

40+
/**
41+
* Records a network telemetry event for the given key if not already recorded.
42+
*
43+
* <p>Uses the key as a deduplication token — subsequent calls with the same key are ignored.
44+
*/
4045
public static void recordNetworkEvent(Object key, String method, String url, String statusCode) {
4146
if (!markAsRecorded(key)) {
4247
return; // deduplicate re-entrant calls for the same connection
@@ -50,6 +55,11 @@ public static void recordNetworkEvent(Object key, String method, String url, Str
5055
);
5156
}
5257

58+
/**
59+
* Records a manual error telemetry event with the given message.
60+
*
61+
* <p>Called when an HTTP request fails with an I/O exception rather than a status code.
62+
*/
5363
public static void recordError(String message) {
5464
AgentTelemetryStore.getInstance().recordManualEventFor(
5565
Level.CRITICAL,

rollbar-java-agent/src/main/java/com/rollbar/agent/RollbarAgent.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,10 @@
55
import com.rollbar.agent.instrumentation.HttpURLConnectionInstrumentation;
66
import com.rollbar.agent.instrumentation.JavaHttpClientInstrumentation;
77
import com.rollbar.notifier.telemetry.TelemetryEventTracker;
8+
import java.lang.instrument.Instrumentation;
89
import net.bytebuddy.agent.builder.AgentBuilder;
910
import net.bytebuddy.matcher.ElementMatchers;
1011

11-
import java.lang.instrument.Instrumentation;
12-
1312
/**
1413
* Java agent entry point. Attach with {@code -javaagent:/path/to/rollbar-java-agent.jar}.
1514
*

rollbar-java-agent/src/main/java/com/rollbar/agent/instrumentation/ApacheHttpClient4Instrumentation.java

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,25 @@
44
import com.rollbar.agent.UrlSanitizer;
55
import com.rollbar.api.payload.data.Level;
66
import com.rollbar.api.payload.data.Source;
7+
import java.lang.instrument.Instrumentation;
78
import net.bytebuddy.agent.builder.AgentBuilder;
89
import net.bytebuddy.asm.Advice;
910
import net.bytebuddy.matcher.ElementMatchers;
1011
import org.apache.http.HttpResponse;
1112
import org.apache.http.client.methods.HttpUriRequest;
1213

13-
import java.lang.instrument.Instrumentation;
14-
14+
/**
15+
* Installs ByteBuddy advice on Apache HttpClient 4.x to capture network errors.
16+
*/
1517
public final class ApacheHttpClient4Instrumentation {
1618

1719
private ApacheHttpClient4Instrumentation() {}
1820

21+
/**
22+
* Instruments Apache HttpClient 4.x if present on the classpath.
23+
*
24+
* <p>Does nothing if {@code org.apache.http.impl.client.CloseableHttpClient} is not available.
25+
*/
1926
public static void installIfAvailable(AgentBuilder builder, Instrumentation inst) {
2027
try {
2128
Class.forName("org.apache.http.impl.client.CloseableHttpClient");
@@ -41,6 +48,12 @@ public static void installIfAvailable(AgentBuilder builder, Instrumentation inst
4148
*/
4249
public static class ExecuteAdvice {
4350

51+
/**
52+
* Fires after {@code execute()} returns or throws, recording 4xx/5xx responses as telemetry.
53+
*
54+
* <p>Apache HC 4.x runs in the application classloader, so Rollbar classes are referenced
55+
* directly without the TCCL reflection bridge needed for JDK instrumentation.
56+
*/
4457
@Advice.OnMethodExit(onThrowable = Throwable.class)
4558
public static void onExit(
4659
@Advice.Argument(0) HttpUriRequest request,
@@ -49,10 +62,12 @@ public static void onExit(
4962
) {
5063
try {
5164
if (thrown != null) {
65+
String message = thrown.getMessage() != null
66+
? thrown.getMessage() : thrown.getClass().getName();
5267
AgentTelemetryStore.getInstance().recordManualEventFor(
5368
Level.CRITICAL,
5469
Source.SERVER,
55-
"Network error: " + (thrown.getMessage() != null ? thrown.getMessage() : thrown.getClass().getName())
70+
"Network error: " + message
5671
);
5772
return;
5873
}

rollbar-java-agent/src/main/java/com/rollbar/agent/instrumentation/ApacheHttpClient5Instrumentation.java

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,26 @@
44
import com.rollbar.agent.UrlSanitizer;
55
import com.rollbar.api.payload.data.Level;
66
import com.rollbar.api.payload.data.Source;
7+
import java.lang.instrument.Instrumentation;
78
import net.bytebuddy.agent.builder.AgentBuilder;
89
import net.bytebuddy.asm.Advice;
910
import net.bytebuddy.matcher.ElementMatchers;
1011
import org.apache.hc.core5.http.ClassicHttpRequest;
1112
import org.apache.hc.core5.http.ClassicHttpResponse;
1213

13-
import java.lang.instrument.Instrumentation;
14-
14+
/**
15+
* Installs ByteBuddy advice on Apache HttpClient 5.x to capture network errors.
16+
*/
1517
public final class ApacheHttpClient5Instrumentation {
1618

1719
private ApacheHttpClient5Instrumentation() {}
1820

21+
/**
22+
* Instruments Apache HttpClient 5.x if present on the classpath.
23+
*
24+
* <p>Does nothing if {@code org.apache.hc.client5.http.impl.classic.CloseableHttpClient}
25+
* is not available.
26+
*/
1927
public static void installIfAvailable(AgentBuilder builder, Instrumentation inst) {
2028
try {
2129
Class.forName("org.apache.hc.client5.http.impl.classic.CloseableHttpClient");
@@ -41,6 +49,12 @@ public static void installIfAvailable(AgentBuilder builder, Instrumentation inst
4149
*/
4250
public static class ExecuteAdvice {
4351

52+
/**
53+
* Fires after {@code execute()} returns or throws, recording 4xx/5xx responses as telemetry.
54+
*
55+
* <p>Apache HC 5.x runs in the application classloader, so Rollbar classes are referenced
56+
* directly without the TCCL reflection bridge needed for JDK instrumentation.
57+
*/
4458
@Advice.OnMethodExit(onThrowable = Throwable.class)
4559
public static void onExit(
4660
@Advice.Argument(0) ClassicHttpRequest request,
@@ -49,10 +63,12 @@ public static void onExit(
4963
) {
5064
try {
5165
if (thrown != null) {
66+
String message = thrown.getMessage() != null
67+
? thrown.getMessage() : thrown.getClass().getName();
5268
AgentTelemetryStore.getInstance().recordManualEventFor(
5369
Level.CRITICAL,
5470
Source.SERVER,
55-
"Network error: " + (thrown.getMessage() != null ? thrown.getMessage() : thrown.getClass().getName())
71+
"Network error: " + message
5672
);
5773
return;
5874
}

rollbar-java-agent/src/main/java/com/rollbar/agent/instrumentation/HttpURLConnectionInstrumentation.java

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,22 @@
11
package com.rollbar.agent.instrumentation;
22

3+
import java.lang.instrument.Instrumentation;
34
import net.bytebuddy.agent.builder.AgentBuilder;
45
import net.bytebuddy.asm.Advice;
56
import net.bytebuddy.matcher.ElementMatchers;
67

7-
import java.lang.instrument.Instrumentation;
8-
8+
/**
9+
* Installs ByteBuddy advice on {@code java.net.HttpURLConnection} to capture network errors.
10+
*/
911
public final class HttpURLConnectionInstrumentation {
1012

1113
private HttpURLConnectionInstrumentation() {}
1214

15+
/**
16+
* Instruments {@code java.net.HttpURLConnection.getResponseCode()} to record 4xx/5xx responses.
17+
*
18+
* <p>Targets the declaring class directly to capture the method regardless of concrete subtype.
19+
*/
1320
public static void install(AgentBuilder builder, Instrumentation inst) {
1421
builder
1522
.type(ElementMatchers.named("java.net.HttpURLConnection"))
@@ -29,6 +36,12 @@ public static void install(AgentBuilder builder, Instrumentation inst) {
2936
*/
3037
public static class GetResponseCodeAdvice {
3138

39+
/**
40+
* Fires after {@code getResponseCode()} returns or throws, recording 4xx/5xx as telemetry.
41+
*
42+
* <p>Uses the connection instance as a deduplication key since {@code getResponseCode()} is
43+
* called re-entrantly up to 3 times per request internally.
44+
*/
3245
@Advice.OnMethodExit(onThrowable = Throwable.class)
3346
public static void onExit(
3447
@Advice.This Object connection,
@@ -46,7 +59,8 @@ public static void onExit(
4659
Boolean recorded = (Boolean) bridge
4760
.getMethod("markAsRecorded", Object.class).invoke(null, thrown);
4861
if (recorded) {
49-
String msg = thrown.getMessage() != null ? thrown.getMessage() : thrown.getClass().getName();
62+
String msg = thrown.getMessage() != null
63+
? thrown.getMessage() : thrown.getClass().getName();
5064
bridge.getMethod("recordError", String.class).invoke(null, msg);
5165
}
5266
return;
@@ -55,8 +69,8 @@ public static void onExit(
5569
if (statusCode >= 400) {
5670
Object url = connection.getClass().getMethod("getURL").invoke(connection);
5771
String urlStr = url != null ? url.toString() : "";
58-
String method = (String) connection.getClass().getMethod("getRequestMethod").invoke(connection);
59-
// connection instance as dedup key — same object across all re-entrant getResponseCode() calls
72+
String method = (String) connection.getClass()
73+
.getMethod("getRequestMethod").invoke(connection);
6074
bridge.getMethod("recordNetworkEvent",
6175
Object.class, String.class, String.class, String.class)
6276
.invoke(null, connection, method, urlStr, String.valueOf(statusCode));

rollbar-java-agent/src/main/java/com/rollbar/agent/instrumentation/JavaHttpClientInstrumentation.java

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,23 @@
11
package com.rollbar.agent.instrumentation;
22

3+
import java.lang.instrument.Instrumentation;
4+
import java.net.http.HttpClient;
35
import net.bytebuddy.agent.builder.AgentBuilder;
46
import net.bytebuddy.asm.Advice;
57
import net.bytebuddy.matcher.ElementMatchers;
68

7-
import java.lang.instrument.Instrumentation;
8-
import java.net.http.HttpClient;
9-
9+
/**
10+
* Installs ByteBuddy advice on {@code java.net.http.HttpClient} subtypes to capture network errors.
11+
*/
1012
public final class JavaHttpClientInstrumentation {
1113

1214
private JavaHttpClientInstrumentation() {}
1315

16+
/**
17+
* Instruments {@code java.net.http.HttpClient} subtypes if available on the current JVM.
18+
*
19+
* <p>Does nothing if {@code java.net.http.HttpClient} is not present (i.e. below Java 11).
20+
*/
1421
public static void installIfAvailable(AgentBuilder builder, Instrumentation inst) {
1522
try {
1623
Class.forName("java.net.http.HttpClient");
@@ -37,6 +44,12 @@ public static void installIfAvailable(AgentBuilder builder, Instrumentation inst
3744
*/
3845
public static class SendAdvice {
3946

47+
/**
48+
* Fires after {@code send()} returns or throws, recording 4xx/5xx responses as telemetry.
49+
*
50+
* <p>Uses the response object as a deduplication key to avoid duplicate events when both
51+
* {@code HttpClientFacade} and {@code HttpClientImpl} invoke this advice.
52+
*/
4053
@Advice.OnMethodExit(onThrowable = Throwable.class)
4154
public static void onExit(
4255
@Advice.Argument(0) Object request,
@@ -54,8 +67,9 @@ public static void onExit(
5467
Boolean recorded = (Boolean) bridge
5568
.getMethod("markAsRecorded", Object.class).invoke(null, thrown);
5669
if (recorded) {
57-
String msg = thrown.getMessage() != null ? thrown.getMessage() : thrown.getClass().getName();
58-
bridge.getMethod("recordError", String.class).invoke(null, msg);
70+
String message = thrown.getMessage() != null
71+
? thrown.getMessage() : thrown.getClass().getName();
72+
bridge.getMethod("recordError", String.class).invoke(null, message);
5973
}
6074
return;
6175
}

0 commit comments

Comments
 (0)