Skip to content

Commit 48a8a61

Browse files
fix(java-dedup): drop JaCoCo TCP server requirement
- Update Dockerfile entrypoint to load jacocoagent.jar without output=tcpserver, address, or port options. The Java SDK now reads coverage in-process via JaCoCo's runtime API. - Rewrite README to cover dedup mode for native, Docker, and restricted Docker without --pass-through-ports. Signed-off-by: Asish Kumar <officialasishkumar@gmail.com>
1 parent 4212b87 commit 48a8a61

2 files changed

Lines changed: 50 additions & 14 deletions

File tree

java-dedup/Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,4 @@ COPY --chown=10001:10001 target/classes /app/target/classes
1313
ENV KEPLOY_JAVA_CLASS_DIRS=/app/target/classes
1414
EXPOSE 8080
1515
USER 10001:10001
16-
ENTRYPOINT ["java", "-javaagent:/app/jacocoagent.jar=address=127.0.0.1,port=36320,destfile=/tmp/jacoco-keploy.exec,output=tcpserver", "-jar", "/app/app.jar"]
16+
ENTRYPOINT ["java", "-javaagent:/app/jacocoagent.jar", "-jar", "/app/app.jar"]

java-dedup/README.md

Lines changed: 49 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,84 @@
11
# Java Dynamic Deduplication Sample
22

3-
This sample is a Spring Boot application used by Keploy CI to validate Java dynamic deduplication in native and Docker runs. It mirrors the Go dedup sample by exposing a broad set of endpoints and committing 1000 replay fixtures across four testsets.
3+
A Spring Boot application used by Keploy CI to validate Java dynamic deduplication in native and Docker runs. It mirrors the Go dedup sample by exposing a broad set of endpoints and committing 1000 replay fixtures across four testsets.
44

55
CI does not record this sample. The `keploy/` directory is checked in so the pipeline only builds the app and runs replay with `--dedup`.
66

7-
Build the application after installing the Java SDK locally:
7+
## How dedup works for Java
8+
9+
Keploy's dynamic dedup engine asks the application for per-test code coverage between every replayed test, then skips future tests whose coverage signature it has already seen. The Java SDK (`io.keploy.dedup.KeployDedupAgent`, bundled in the app via the `keploy-sdk` dependency) handles that coverage exchange.
10+
11+
The SDK reads coverage **in-process** through JaCoCo's runtime API (`org.jacoco.agent.rt.RT.getAgent().getExecutionData(...)`). All you have to do is attach the JaCoCo Java agent — no TCP server, no port choice, no `--pass-through-ports`:
12+
13+
```
14+
-javaagent:target/jacocoagent.jar
15+
```
16+
17+
The SDK still falls back to JaCoCo's TCP server mode if the in-process API is unavailable for some reason, which is why the `KEPLOY_JACOCO_HOST` and `KEPLOY_JACOCO_PORT` environment variables are still honoured.
18+
19+
## Build
820

921
```bash
1022
mvn -B -DskipTests package
1123
```
1224

13-
Run it natively with JaCoCo TCP server mode:
25+
This produces `target/java-dedup-0.0.1-SNAPSHOT.jar` and copies `target/jacocoagent.jar` next to it.
26+
27+
## Native run
28+
29+
Start the app with the JaCoCo agent attached:
1430

1531
```bash
16-
java -javaagent:target/jacocoagent.jar=address=127.0.0.1,port=36320,destfile=target/jacoco-keploy.exec,output=tcpserver \
32+
java -javaagent:target/jacocoagent.jar \
1733
-jar target/java-dedup-0.0.1-SNAPSHOT.jar
1834
```
1935

36+
Replay with dynamic dedup:
37+
38+
```bash
39+
keploy test \
40+
-c "java -javaagent:target/jacocoagent.jar -jar target/java-dedup-0.0.1-SNAPSHOT.jar" \
41+
--dedup --language java --delay 20
42+
```
43+
2044
To regenerate the committed fixtures locally, record high-volume traffic against the running app:
2145

2246
```bash
2347
./run_random_1000.sh
2448
```
2549

26-
When replaying with dynamic deduplication, pass the JaCoCo port through Keploy so the SDK can talk to the local JaCoCo TCP server:
50+
## Docker run
51+
52+
Build the JAR first, then build the image. The Dockerfile already wires the JaCoCo agent into the entrypoint:
2753

2854
```bash
29-
keploy test \
30-
-c "java -javaagent:target/jacocoagent.jar=address=127.0.0.1,port=36320,destfile=target/jacoco-keploy.exec,output=tcpserver -jar target/java-dedup-0.0.1-SNAPSHOT.jar" \
31-
--dedup --pass-through-ports 36320
55+
mvn -B -DskipTests package
56+
docker compose build
3257
```
3358

34-
Run it with Docker Compose after the Maven package step has created `target/java-dedup-0.0.1-SNAPSHOT.jar`:
59+
Run with Keploy in dedup mode:
3560

3661
```bash
37-
docker compose build
38-
docker compose up
62+
keploy test \
63+
-c "docker compose up" \
64+
--container-name "dedup-java" \
65+
--dedup --language java --delay 20
3966
```
4067

4168
The Compose file supports `JAVA_DEDUP_IMAGE`, `JAVA_DEDUP_CONTAINER_NAME`, and `JAVA_DEDUP_HOST_PORT` so CI can isolate repeated replay runs without recording new tests.
4269

43-
The Compose app bind-mounts host `/tmp` into the container so Keploy and the Java SDK use the same Unix socket paths for `/tmp/coverage_control.sock` and `/tmp/coverage_data.sock`. The image runs as a non-root user. For a more restricted container run with a read-only root filesystem, dropped capabilities, `no-new-privileges`, and writable host `/tmp` bind-mounted for Keploy's Unix sockets:
70+
The Compose app bind-mounts host `/tmp` into the container so Keploy and the Java SDK use the same Unix socket paths for `/tmp/coverage_control.sock` and `/tmp/coverage_data.sock`.
71+
72+
### Restricted Docker
73+
74+
For a more restricted container — read-only root filesystem, dropped capabilities, and `no-new-privileges` — overlay the restricted compose file:
4475

4576
```bash
4677
docker compose -f docker-compose.yml -f docker-compose.restricted.yml build
47-
docker compose -f docker-compose.yml -f docker-compose.restricted.yml up
78+
keploy test \
79+
-c "docker compose -f docker-compose.yml -f docker-compose.restricted.yml up" \
80+
--container-name "dedup-java" \
81+
--dedup --language java --delay 20
4882
```
83+
84+
Host `/tmp` is still bind-mounted so the SDK and Keploy share the dedup Unix sockets.

0 commit comments

Comments
 (0)