Skip to content

Commit 8ec4c61

Browse files
committed
fix: Handle empty 'exclude' field in appmap.yml
This commit resolves a NullPointerException that occurred when the `exclude` field within a package definition in `appmap.yml` was present but empty (e.g., `exclude:`). The Jackson YAML parser would deserialize this as `null`, leading to a crash when its length was accessed. The fix involves two parts: 1. Modifying `AppMapConfig.java` to add a null check in the stream reduction logic for `p.exclude`, treating a null array as having a length of zero. 2. Initializing the `exclude` field as an empty array in the `AppMapPackage` constructor using `@JsonCreator`, ensuring it's never null during deserialization. A new regression test case, `loadEmptyExcludeField`, has been added to `AppMapConfigTest.java` to verify that an empty `exclude` field is now handled correctly and does not cause a crash. The test ensures that the `exclude` array is non-null and has a length of zero, confirming the intended behavior.
1 parent 0f86c84 commit 8ec4c61

File tree

3 files changed

+26
-2
lines changed

3 files changed

+26
-2
lines changed

agent/src/main/java/com/appland/appmap/config/AppMapConfig.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ static AppMapConfig load(Path configFile, boolean mustExist) {
145145

146146
int count = singleton.packages.length;
147147
count = Arrays.stream(singleton.packages).map(p -> p.exclude).reduce(count,
148-
(acc, e) -> acc += e.length, Integer::sum);
148+
(acc, e) -> acc += e == null ? 0 : e.length, Integer::sum);
149149

150150
int pattern_threshold = Properties.PatternThreshold;
151151
if (count > pattern_threshold) {

agent/src/main/java/com/appland/appmap/config/AppMapPackage.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,17 @@ public class AppMapPackage {
2121
public boolean shallow = false;
2222
public Boolean allMethods = true;
2323

24+
@JsonCreator
25+
public AppMapPackage(@JsonProperty("path") String path,
26+
@JsonProperty("exclude") String[] exclude,
27+
@JsonProperty("shallow") Boolean shallow,
28+
@JsonProperty("allMethods") Boolean allMethods) {
29+
this.path = path;
30+
this.exclude = exclude == null ? new String[] {} : exclude;
31+
this.shallow = shallow != null && shallow;
32+
this.allMethods = allMethods == null ? true : allMethods;
33+
}
34+
2435
public static class LabelConfig {
2536

2637
private Pattern className = null;

agent/src/test/java/com/appland/appmap/config/AppMapConfigTest.java

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,19 @@ public void loadPackagesKeyWithScalarValue() throws Exception {
118118
String actualErr = tapSystemErr(() -> AppMapConfig.load(configFile, false));
119119
assertTrue(actualErr.contains("AppMap: encountered syntax error in appmap.yml"));
120120
}
121-
}
122121

122+
@Test
123+
public void loadEmptyExcludeField() throws Exception {
124+
Path configFile = tmpdir.resolve("appmap.yml");
125+
final String contents = "name: test\npackages:\n- path: com.example\n exclude:\n";
126+
Files.write(configFile, contents.getBytes());
127+
128+
AppMapConfig config = AppMapConfig.load(configFile, false);
129+
assertNotNull(config);
130+
assertEquals(1, config.packages.length);
131+
assertEquals("com.example", config.packages[0].path);
132+
assertNotNull(config.packages[0].exclude);
133+
assertEquals(0, config.packages[0].exclude.length);
134+
}
135+
}
123136

0 commit comments

Comments
 (0)