From a405796dd21078af0bba776641d330b5ae0bc6ff Mon Sep 17 00:00:00 2001 From: Asish Kumar Date: Thu, 30 Apr 2026 03:19:31 +0530 Subject: [PATCH 1/7] docs: document Java dedup agent setup Signed-off-by: Asish Kumar --- .../config/vocabularies/Base/accept.txt | 4 + .../keploy-cloud/deduplication.md | 82 ++++++++++-------- .../server/sdk-installation/java.md | 85 ++++++++++--------- 3 files changed, 95 insertions(+), 76 deletions(-) diff --git a/vale_styles/config/vocabularies/Base/accept.txt b/vale_styles/config/vocabularies/Base/accept.txt index 9acf69b28..c35e1219e 100644 --- a/vale_styles/config/vocabularies/Base/accept.txt +++ b/vale_styles/config/vocabularies/Base/accept.txt @@ -20,10 +20,12 @@ Deduplication distros dockerfile Docusaurus +Dropwizard expected_string Functionize GitHub gjson +Gradle graphql Hacktoberfest HAProxy @@ -40,6 +42,7 @@ Idempotency JaCoCo Jacoco JBehave +Jersey JMeter json_contains json_equal @@ -68,6 +71,7 @@ Redis [Rr]epo Reqnroll SDK +servlet signin Spotify status_code diff --git a/versioned_docs/version-4.0.0/keploy-cloud/deduplication.md b/versioned_docs/version-4.0.0/keploy-cloud/deduplication.md index 1bbfd6a97..0d245a47e 100644 --- a/versioned_docs/version-4.0.0/keploy-cloud/deduplication.md +++ b/versioned_docs/version-4.0.0/keploy-cloud/deduplication.md @@ -121,47 +121,53 @@ keploy dedup --rm #### 1. Pre-requisite -Add the Keploy Java SDK to your application: +Copy the Keploy Java agent jar during your build. Do not add it as an application dependency, and do not import Keploy classes from application code. ```xml - - io.keploy - keploy-sdk - 2.0.0 - -``` - -For Spring Boot 2 or other `javax.servlet` applications, register the Keploy middleware in your main class: - -```java -import io.keploy.servlet.KeployMiddleware; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.context.annotation.Import; - -@SpringBootApplication -@Import(KeployMiddleware.class) -public class App { -} -``` - -For Spring Boot 3, Jakarta EE applications, other frameworks, or custom launchers, start the agent during application startup: - -```java -import io.keploy.dedup.KeployDedupAgent; - -KeployDedupAgent.start(); -``` - -Java dynamic deduplication uses JaCoCo runtime coverage. The SDK reads coverage in-process via JaCoCo's runtime API (`org.jacoco.agent.rt.RT.getAgent()`), so attaching the JaCoCo Java agent is enough: no TCP server flags, no `--pass-through-ports`. - -```bash -java -javaagent:/path/to/org.jacoco.agent-runtime.jar -jar target/app.jar + + org.apache.maven.plugins + maven-dependency-plugin + 3.6.1 + + + copy-keploy-java-agent + package + + copy + + + + + io.keploy + keploy-sdk + 2.0.1 + ${project.build.directory} + keploy-sdk.jar + + + + + + +``` + +Java dynamic deduplication uses JaCoCo runtime coverage. Attach the Keploy Java agent to start the dedup control socket, and attach the JaCoCo Java agent to provide coverage data. In the common path there are no TCP server flags and no `--pass-through-ports`. + +The Java agent is framework-agnostic. It can be attached to Spring Boot apps, Dropwizard/Jersey apps, plain executable jars, classpath-based apps, servlet/WAR-style archives, and other JVM frameworks as long as the application JVM also runs the JaCoCo agent. + +```bash +java \ + -javaagent:target/keploy-sdk.jar \ + -javaagent:/path/to/org.jacoco.agent-runtime.jar \ + -jar target/app.jar ``` If the in-process API is unavailable for some reason (for example, an isolated class loader), the SDK transparently falls back to JaCoCo's TCP server mode. To force the fallback, launch JaCoCo in `tcpserver` mode and tell Keploy to leave that port alone: ```bash -java -javaagent:/path/to/org.jacoco.agent-runtime.jar=address=127.0.0.1,port=36320,output=tcpserver \ +java \ + -javaagent:target/keploy-sdk.jar \ + -javaagent:/path/to/org.jacoco.agent-runtime.jar=address=127.0.0.1,port=36320,output=tcpserver \ -jar target/app.jar ``` @@ -175,13 +181,14 @@ Build the application before running Keploy so the Java class files are availabl mvn clean package -DskipTests ``` -By default, the SDK scans `target/classes`, `build/classes/java/main`, and runtime classpath jars. For custom layouts or restricted Docker images, set `KEPLOY_JAVA_CLASS_DIRS` to the class directories or jars that should be analyzed. +By default, the SDK scans Maven `target/classes`, Gradle `build/classes/java/main`, executable jars, Spring Boot `BOOT-INF/classes`, servlet `WEB-INF/classes`, and runtime classpath archives. For custom layouts or restricted Docker images, set `KEPLOY_JAVA_CLASS_DIRS` to the class directories or archives that should be analyzed. #### 3. Dockerfile Configuration (Important for Docker Users) When you use Docker or Docker Compose, make sure the final runtime image contains: - the runnable application jar, +- the Keploy Java agent jar, - the JaCoCo runtime agent jar, - the compiled classes or the fat jar that contains the application classes. @@ -189,6 +196,7 @@ For example: ```dockerfile COPY target/app.jar /app/app.jar +COPY target/keploy-sdk.jar /app/keploy-sdk.jar COPY target/classes /app/target/classes COPY jacocoagent.jar /app/jacocoagent.jar ``` @@ -196,7 +204,7 @@ COPY jacocoagent.jar /app/jacocoagent.jar Then run the app with the JaCoCo agent attached: ```bash -java -javaagent:/app/jacocoagent.jar -jar /app/app.jar +java -javaagent:/app/keploy-sdk.jar -javaagent:/app/jacocoagent.jar -jar /app/app.jar ``` Keploy and the Java SDK exchange per-test coverage signals over `/tmp/coverage_control.sock` and `/tmp/coverage_data.sock`. For Docker and Docker Compose, Keploy injects a shared `keploy-sockets-vol:/tmp` mount into the application container and the Keploy agent container so both processes see the same socket paths. @@ -214,7 +222,7 @@ keploy test -c "docker compose up" --container-name containerName --dedup --lang For Native, run: ```bash -keploy test -c "java -javaagent:/path/to/org.jacoco.agent-runtime.jar -jar target/app.jar" --dedup --language java +keploy test -c "java -javaagent:target/keploy-sdk.jar -javaagent:/path/to/org.jacoco.agent-runtime.jar -jar target/app.jar" --dedup --language java ``` If the SDK falls back to the JaCoCo TCP server, also pass `--pass-through-ports ` so Keploy does not try to mock the coverage-control connection. diff --git a/versioned_docs/version-4.0.0/server/sdk-installation/java.md b/versioned_docs/version-4.0.0/server/sdk-installation/java.md index 7a75d1ce0..f9ecfa2c9 100644 --- a/versioned_docs/version-4.0.0/server/sdk-installation/java.md +++ b/versioned_docs/version-4.0.0/server/sdk-installation/java.md @@ -1,8 +1,8 @@ --- id: java -title: Java SDK for Dynamic Deduplication +title: Java Agent for Dynamic Deduplication sidebar_label: Java -description: "Configure the Keploy Java SDK for Enterprise dynamic deduplication with in-process JaCoCo coverage." +description: "Configure the Keploy Java agent for Enterprise dynamic deduplication with in-process JaCoCo coverage." tags: - java - coverage @@ -12,6 +12,7 @@ keywords: - JaCoCo - Maven - Spring Boot + - WAR - dynamic deduplication --- @@ -19,59 +20,63 @@ import ProductTier from '@site/src/components/ProductTier'; -The Java SDK is used for Enterprise dynamic deduplication during replay/test mode. It collects per-testcase Java coverage and sends it to Keploy Enterprise so duplicate testcases can be identified. +The Keploy Java SDK is used as a Java agent for Enterprise dynamic deduplication during replay/test mode. It collects per-testcase Java coverage and sends it to Keploy Enterprise so duplicate testcases can be identified. -The Java SDK does not record API traffic or mock dependencies. Record your Keploy tests separately, commit the generated test fixtures when you use them in CI, and run Java dedup during `keploy test --dedup`. +The Java agent does not record API traffic or mock dependencies. Record your Keploy tests separately, commit the generated test fixtures when you use them in CI, and run Java dedup during `keploy test --dedup`. + +Because the SDK is a Java agent, it is framework-agnostic. It can be attached to Spring Boot apps, Dropwizard/Jersey apps, plain executable jars, classpath-based apps, servlet/WAR-style archives, and other JVM frameworks as long as the application JVM also runs the JaCoCo agent. ## Requirements - Java 8, 17, or 21 -- `io.keploy:keploy-sdk` +- `io.keploy:keploy-sdk` version with Java-agent support - JaCoCo Java agent attached to the application JVM - Keploy Enterprise with dynamic deduplication enabled -## Add the SDK +## Copy the Keploy Java Agent -Add the Keploy Java SDK dependency: +Copy the Keploy Java agent jar during your build. Do not add it under ``, and do not import Keploy classes from your application code. ```xml - - io.keploy - keploy-sdk - 2.0.0 - -``` - -## Start the Dedup Agent - -For Spring Boot 2 or other `javax.servlet` applications, import the middleware: - -```java -import io.keploy.servlet.KeployMiddleware; -import org.springframework.context.annotation.Import; - -@Import(KeployMiddleware.class) -public class Application { -} + + org.apache.maven.plugins + maven-dependency-plugin + 3.6.1 + + + copy-keploy-java-agent + package + + copy + + + + + io.keploy + keploy-sdk + 2.0.1 + ${project.build.directory} + keploy-sdk.jar + + + + + + ``` -For Spring Boot 3, Jakarta EE applications, other frameworks, or custom launchers, start the agent during application startup: +## Run with the Keploy and JaCoCo Java Agents -```java -import io.keploy.dedup.KeployDedupAgent; - -KeployDedupAgent.start(); -``` - -## Run with the JaCoCo Java Agent - -The SDK reads coverage in-process via JaCoCo's runtime API (`org.jacoco.agent.rt.RT.getAgent()`), so attaching the JaCoCo agent is enough: no TCP server flags, no port choice. +The SDK reads coverage in-process via JaCoCo's runtime API (`org.jacoco.agent.rt.RT.getAgent()`), so attach both agents in the application JVM: the Keploy agent starts the dedup control socket, and the JaCoCo agent provides runtime coverage. ```bash -java -javaagent:/path/to/jacocoagent.jar -jar target/app.jar +java \ + -javaagent:target/keploy-sdk.jar \ + -javaagent:/path/to/jacocoagent.jar \ + -jar target/app.jar ``` -If your compiled application classes are not under `target/classes` or `build/classes/java/main`, set `KEPLOY_JAVA_CLASS_DIRS`: +The SDK automatically looks for application classes in Maven `target/classes`, Gradle `build/classes/java/main`, executable jars, Spring Boot `BOOT-INF/classes`, servlet `WEB-INF/classes`, and the runtime classpath. If your compiled application classes live somewhere else, set `KEPLOY_JAVA_CLASS_DIRS` to the class directory or archive that should be analyzed: ```bash export KEPLOY_JAVA_CLASS_DIRS=/absolute/path/to/target/classes @@ -80,7 +85,9 @@ export KEPLOY_JAVA_CLASS_DIRS=/absolute/path/to/target/classes If the in-process API is unavailable in your environment, the SDK transparently falls back to JaCoCo's TCP server mode. To use the fallback explicitly, launch JaCoCo in `tcpserver` mode and configure `KEPLOY_JACOCO_HOST` / `KEPLOY_JACOCO_PORT` (defaults: `127.0.0.1:36320`): ```bash -java -javaagent:/path/to/jacocoagent.jar=address=127.0.0.1,port=36320,output=tcpserver \ +java \ + -javaagent:target/keploy-sdk.jar \ + -javaagent:/path/to/jacocoagent.jar=address=127.0.0.1,port=36320,output=tcpserver \ -jar target/app.jar ``` @@ -90,7 +97,7 @@ Run Keploy in test mode with dynamic deduplication enabled: ```bash keploy test \ - -c "java -javaagent:/path/to/jacocoagent.jar -jar target/app.jar" \ + -c "java -javaagent:target/keploy-sdk.jar -javaagent:/path/to/jacocoagent.jar -jar target/app.jar" \ --dedup \ --language java ``` From d43ff0c2516f57ecbe9310b1543e2fdeeb9c0245 Mon Sep 17 00:00:00 2001 From: Asish Kumar Date: Thu, 30 Apr 2026 15:21:52 +0530 Subject: [PATCH 2/7] docs: use java dedup agent 2.0.0 Signed-off-by: Asish Kumar --- versioned_docs/version-4.0.0/keploy-cloud/deduplication.md | 2 +- versioned_docs/version-4.0.0/running-keploy/keploy-karaf.md | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/versioned_docs/version-4.0.0/keploy-cloud/deduplication.md b/versioned_docs/version-4.0.0/keploy-cloud/deduplication.md index 0d245a47e..236cfac9c 100644 --- a/versioned_docs/version-4.0.0/keploy-cloud/deduplication.md +++ b/versioned_docs/version-4.0.0/keploy-cloud/deduplication.md @@ -140,7 +140,7 @@ Copy the Keploy Java agent jar during your build. Do not add it as an applicatio io.keploy keploy-sdk - 2.0.1 + 2.0.0 ${project.build.directory} keploy-sdk.jar diff --git a/versioned_docs/version-4.0.0/running-keploy/keploy-karaf.md b/versioned_docs/version-4.0.0/running-keploy/keploy-karaf.md index a5316791a..843c5d9f2 100644 --- a/versioned_docs/version-4.0.0/running-keploy/keploy-karaf.md +++ b/versioned_docs/version-4.0.0/running-keploy/keploy-karaf.md @@ -35,13 +35,13 @@ curl --silent -O -L https://keploy.io/ent/install.sh && source install.sh Use `wget` to download the necessary JAR files: -- [io.keploy.agent-2.0.1.jar](https://keploy-enterprise.s3.us-west-2.amazonaws.com/agent-jars/io.keploy.agent-2.0.1.jar) +- [io.keploy.agent-2.0.0.jar](https://keploy-enterprise.s3.us-west-2.amazonaws.com/agent-jars/io.keploy.agent-2.0.0.jar) - [org.jacoco.agent-0.8.12-runtime.jar](https://keploy-enterprise.s3.us-west-2.amazonaws.com/agent-jars/org.jacoco.agent-0.8.12-runtime.jar) Run the following commands to download the files: ```bash -wget https://keploy-enterprise.s3.us-west-2.amazonaws.com/agent-jars/io.keploy.agent-2.0.1.jar +wget https://keploy-enterprise.s3.us-west-2.amazonaws.com/agent-jars/io.keploy.agent-2.0.0.jar wget https://keploy-enterprise.s3.us-west-2.amazonaws.com/agent-jars/org.jacoco.agent-0.8.12-runtime.jar ``` @@ -54,7 +54,7 @@ wget https://keploy-enterprise.s3.us-west-2.amazonaws.com/agent-jars/org.jacoco. 3. Add the paths of the downloaded agents under the `JAVA_OPTS` section. For example: ```bash - export JAVA_OPTS="-javaagent:/path/to/io.keploy.agent-2.0.1.jar" + export JAVA_OPTS="-javaagent:/path/to/io.keploy.agent-2.0.0.jar" export JAVA_OPTS="$JAVA_OPTS -javaagent:/path/to/org.jacoco.agent-0.8.12-runtime.jar=address=*,port=36320,destfile=jacoco-it.exec,output=tcpserver" ``` From 1e3006a4cd104edf9610e879925d519fd180b64d Mon Sep 17 00:00:00 2001 From: Asish Kumar Date: Thu, 30 Apr 2026 16:28:48 +0530 Subject: [PATCH 3/7] docs: use Java agent 2.0.2 Signed-off-by: Asish Kumar --- versioned_docs/version-4.0.0/keploy-cloud/deduplication.md | 2 +- versioned_docs/version-4.0.0/running-keploy/keploy-karaf.md | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/versioned_docs/version-4.0.0/keploy-cloud/deduplication.md b/versioned_docs/version-4.0.0/keploy-cloud/deduplication.md index 236cfac9c..6b7809ea6 100644 --- a/versioned_docs/version-4.0.0/keploy-cloud/deduplication.md +++ b/versioned_docs/version-4.0.0/keploy-cloud/deduplication.md @@ -140,7 +140,7 @@ Copy the Keploy Java agent jar during your build. Do not add it as an applicatio io.keploy keploy-sdk - 2.0.0 + 2.0.2 ${project.build.directory} keploy-sdk.jar diff --git a/versioned_docs/version-4.0.0/running-keploy/keploy-karaf.md b/versioned_docs/version-4.0.0/running-keploy/keploy-karaf.md index 843c5d9f2..8df01ecf4 100644 --- a/versioned_docs/version-4.0.0/running-keploy/keploy-karaf.md +++ b/versioned_docs/version-4.0.0/running-keploy/keploy-karaf.md @@ -35,13 +35,13 @@ curl --silent -O -L https://keploy.io/ent/install.sh && source install.sh Use `wget` to download the necessary JAR files: -- [io.keploy.agent-2.0.0.jar](https://keploy-enterprise.s3.us-west-2.amazonaws.com/agent-jars/io.keploy.agent-2.0.0.jar) +- [io.keploy.agent-2.0.2.jar](https://keploy-enterprise.s3.us-west-2.amazonaws.com/agent-jars/io.keploy.agent-2.0.2.jar) - [org.jacoco.agent-0.8.12-runtime.jar](https://keploy-enterprise.s3.us-west-2.amazonaws.com/agent-jars/org.jacoco.agent-0.8.12-runtime.jar) Run the following commands to download the files: ```bash -wget https://keploy-enterprise.s3.us-west-2.amazonaws.com/agent-jars/io.keploy.agent-2.0.0.jar +wget https://keploy-enterprise.s3.us-west-2.amazonaws.com/agent-jars/io.keploy.agent-2.0.2.jar wget https://keploy-enterprise.s3.us-west-2.amazonaws.com/agent-jars/org.jacoco.agent-0.8.12-runtime.jar ``` @@ -54,7 +54,7 @@ wget https://keploy-enterprise.s3.us-west-2.amazonaws.com/agent-jars/org.jacoco. 3. Add the paths of the downloaded agents under the `JAVA_OPTS` section. For example: ```bash - export JAVA_OPTS="-javaagent:/path/to/io.keploy.agent-2.0.0.jar" + export JAVA_OPTS="-javaagent:/path/to/io.keploy.agent-2.0.2.jar" export JAVA_OPTS="$JAVA_OPTS -javaagent:/path/to/org.jacoco.agent-0.8.12-runtime.jar=address=*,port=36320,destfile=jacoco-it.exec,output=tcpserver" ``` From dc486ae0dfdfcbe932edaedb92b5171cdcd9cff4 Mon Sep 17 00:00:00 2001 From: Asish Kumar Date: Thu, 30 Apr 2026 23:26:33 +0530 Subject: [PATCH 4/7] docs: use Java agent 2.0.6 Latest io.keploy:keploy-sdk release on Maven Central with the shaded dedup agent jar. Signed-off-by: Asish Kumar --- versioned_docs/version-4.0.0/keploy-cloud/deduplication.md | 2 +- versioned_docs/version-4.0.0/server/sdk-installation/java.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/versioned_docs/version-4.0.0/keploy-cloud/deduplication.md b/versioned_docs/version-4.0.0/keploy-cloud/deduplication.md index 6b7809ea6..3484a56d1 100644 --- a/versioned_docs/version-4.0.0/keploy-cloud/deduplication.md +++ b/versioned_docs/version-4.0.0/keploy-cloud/deduplication.md @@ -140,7 +140,7 @@ Copy the Keploy Java agent jar during your build. Do not add it as an applicatio io.keploy keploy-sdk - 2.0.2 + 2.0.6 ${project.build.directory} keploy-sdk.jar diff --git a/versioned_docs/version-4.0.0/server/sdk-installation/java.md b/versioned_docs/version-4.0.0/server/sdk-installation/java.md index f9ecfa2c9..634e9f81e 100644 --- a/versioned_docs/version-4.0.0/server/sdk-installation/java.md +++ b/versioned_docs/version-4.0.0/server/sdk-installation/java.md @@ -54,7 +54,7 @@ Copy the Keploy Java agent jar during your build. Do not add it under ` io.keploy keploy-sdk - 2.0.1 + 2.0.6 ${project.build.directory} keploy-sdk.jar From b5f0a2ec835648d810e7628e24751457181a25be Mon Sep 17 00:00:00 2001 From: Asish Kumar Date: Fri, 1 May 2026 03:18:31 +0530 Subject: [PATCH 5/7] docs(java-dedup): trim power-user material, add JaCoCo copy snippet MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reading the Java dedup docs end-to-end as a fresh user, several sections were noise: - TCP-fallback prose + KEPLOY_JACOCO_HOST/PORT + keploy.jacoco.* JVM properties + --pass-through-ports note. The SDK transparently falls back when the in-process JaCoCo runtime API is unavailable (rare); making the user think about it on page 1 of the setup is unhelpful. Removed entirely; the fallback path still works, it's just no longer in the user's face. - /tmp/coverage_control.sock and /tmp/coverage_data.sock paths exposed in the main flow. Internal protocol detail; users don't need to know the socket names to attach -javaagent. - "Hardened Docker runs are validated with non-root user, read-only root filesystem, dropped capabilities, no-new-privileges, ..." paragraph — that's the CI test matrix bragging, not user instruction. Trimmed to one sentence: "restricted containers work as long as /tmp stays writable." Also fixed two real gaps a user actually hits: - How to obtain jacocoagent.jar. Both docs said "attach -javaagent: /path/to/jacocoagent.jar" but never told the user where to get the file. Added a maven-dependency-plugin next to the existing keploy-sdk copy block that pulls org.jacoco:org.jacoco.agent:0.8.12:jar:runtime to target/jacocoagent.jar. - JaCoCo version pin (0.8.12) is now explicit in Requirements + the maven snippet, so users on older versions know what we test against. - One-line description of what dedupData.yaml and duplicates.yaml contain, instead of just naming them. Net diff: deduplication.md -11 lines, java.md -10 lines, both denser and easier to follow. Signed-off-by: Asish Kumar --- .../keploy-cloud/deduplication.md | 85 ++++++++----------- .../server/sdk-installation/java.md | 75 +++++++--------- 2 files changed, 70 insertions(+), 90 deletions(-) diff --git a/versioned_docs/version-4.0.0/keploy-cloud/deduplication.md b/versioned_docs/version-4.0.0/keploy-cloud/deduplication.md index 3484a56d1..ed88a85b7 100644 --- a/versioned_docs/version-4.0.0/keploy-cloud/deduplication.md +++ b/versioned_docs/version-4.0.0/keploy-cloud/deduplication.md @@ -121,7 +121,9 @@ keploy dedup --rm #### 1. Pre-requisite -Copy the Keploy Java agent jar during your build. Do not add it as an application dependency, and do not import Keploy classes from application code. +Java dynamic deduplication uses JaCoCo runtime coverage. Attach the Keploy Java agent to emit per-test coverage signals, and attach the JaCoCo runtime agent so the SDK can read the coverage data. The Java agent is framework-agnostic — Spring Boot, Dropwizard/Jersey, plain executable jars, classpath-based apps, servlet/WAR archives, etc. + +Copy both jars into `target/` during your Maven build (do not add the Keploy SDK as an application dependency, and do not import Keploy classes from your code). Tested with JaCoCo `0.8.12`. ```xml @@ -132,9 +134,7 @@ Copy the Keploy Java agent jar during your build. Do not add it as an applicatio copy-keploy-java-agent package - - copy - + copy @@ -147,32 +147,37 @@ Copy the Keploy Java agent jar during your build. Do not add it as an applicatio + + copy-jacoco-agent + package + copy + + + + org.jacoco + org.jacoco.agent + 0.8.12 + runtime + jar + ${project.build.directory} + jacocoagent.jar + + + + ``` -Java dynamic deduplication uses JaCoCo runtime coverage. Attach the Keploy Java agent to start the dedup control socket, and attach the JaCoCo Java agent to provide coverage data. In the common path there are no TCP server flags and no `--pass-through-ports`. - -The Java agent is framework-agnostic. It can be attached to Spring Boot apps, Dropwizard/Jersey apps, plain executable jars, classpath-based apps, servlet/WAR-style archives, and other JVM frameworks as long as the application JVM also runs the JaCoCo agent. +Run the app with both agents attached: ```bash java \ -javaagent:target/keploy-sdk.jar \ - -javaagent:/path/to/org.jacoco.agent-runtime.jar \ + -javaagent:target/jacocoagent.jar \ -jar target/app.jar ``` -If the in-process API is unavailable for some reason (for example, an isolated class loader), the SDK transparently falls back to JaCoCo's TCP server mode. To force the fallback, launch JaCoCo in `tcpserver` mode and tell Keploy to leave that port alone: - -```bash -java \ - -javaagent:target/keploy-sdk.jar \ - -javaagent:/path/to/org.jacoco.agent-runtime.jar=address=127.0.0.1,port=36320,output=tcpserver \ - -jar target/app.jar -``` - -The default JaCoCo endpoint for the fallback is `127.0.0.1:36320`. You can override it with `KEPLOY_JACOCO_HOST` and `KEPLOY_JACOCO_PORT`, or with the JVM properties `keploy.jacoco.host` and `keploy.jacoco.port`. When using the fallback, add the JaCoCo port to `--pass-through-ports` so coverage-control traffic is not mocked. - #### 2. Build Configuration Build the application before running Keploy so the Java class files are available for coverage analysis: @@ -185,31 +190,21 @@ By default, the SDK scans Maven `target/classes`, Gradle `build/classes/java/mai #### 3. Dockerfile Configuration (Important for Docker Users) -When you use Docker or Docker Compose, make sure the final runtime image contains: - -- the runnable application jar, -- the Keploy Java agent jar, -- the JaCoCo runtime agent jar, -- the compiled classes or the fat jar that contains the application classes. - -For example: +When you use Docker or Docker Compose, copy four artifacts into the runtime image and attach both agents in the entrypoint: ```dockerfile -COPY target/app.jar /app/app.jar -COPY target/keploy-sdk.jar /app/keploy-sdk.jar -COPY target/classes /app/target/classes -COPY jacocoagent.jar /app/jacocoagent.jar -``` - -Then run the app with the JaCoCo agent attached: +COPY target/app.jar /app/app.jar +COPY target/keploy-sdk.jar /app/keploy-sdk.jar +COPY target/jacocoagent.jar /app/jacocoagent.jar +COPY target/classes /app/target/classes -```bash -java -javaagent:/app/keploy-sdk.jar -javaagent:/app/jacocoagent.jar -jar /app/app.jar +ENTRYPOINT ["java", \ + "-javaagent:/app/keploy-sdk.jar", \ + "-javaagent:/app/jacocoagent.jar", \ + "-jar", "/app/app.jar"] ``` -Keploy and the Java SDK exchange per-test coverage signals over `/tmp/coverage_control.sock` and `/tmp/coverage_data.sock`. For Docker and Docker Compose, Keploy injects a shared `keploy-sockets-vol:/tmp` mount into the application container and the Keploy agent container so both processes see the same socket paths. - -For hardened Docker runs, the Java dedup sample is validated with a non-root runtime user, a read-only root filesystem, dropped Linux capabilities, `no-new-privileges`, and Keploy's shared `/tmp` named volume for the Keploy control/data sockets and JaCoCo output. Do not add a conflicting `/tmp` bind mount or `tmpfs`; Keploy requires the injected shared `/tmp` volume to reach the Java SDK control socket. +Keploy injects a shared `keploy-sockets-vol:/tmp` mount into both the application container and the Keploy agent container at replay time so the dedup sockets are visible on both sides. Keep `/tmp` writable in the container; do not add a conflicting `/tmp` bind mount or `tmpfs`. Restricted containers (non-root user, read-only root filesystem, dropped capabilities) work as long as `/tmp` stays writable. #### 4. Run Deduplication @@ -222,22 +217,16 @@ keploy test -c "docker compose up" --container-name containerName --dedup --lang For Native, run: ```bash -keploy test -c "java -javaagent:target/keploy-sdk.jar -javaagent:/path/to/org.jacoco.agent-runtime.jar -jar target/app.jar" --dedup --language java +keploy test -c "java -javaagent:target/keploy-sdk.jar -javaagent:target/jacocoagent.jar -jar target/app.jar" --dedup --language java ``` -If the SDK falls back to the JaCoCo TCP server, also pass `--pass-through-ports ` so Keploy does not try to mock the coverage-control connection. - -This will generate a `dedupData.yaml` file. - -After this, run: +This produces `dedupData.yaml` — a per-testcase coverage map (`testSetID/testCaseID` → executed lines per source file) Keploy uses to compute redundancy. ```bash keploy dedup ``` -This command will create a `duplicates.yaml` file containing the test cases that dynamic deduplication marked as redundant. - -To apply the dynamic deduplication cleanup to the local Keploy test set, run: +This reads `dedupData.yaml` and writes `duplicates.yaml`, listing the testcases that dedup marked redundant (grouped by test-set). To remove those testcases from the local Keploy test set: ```bash keploy dedup --rm diff --git a/versioned_docs/version-4.0.0/server/sdk-installation/java.md b/versioned_docs/version-4.0.0/server/sdk-installation/java.md index 634e9f81e..079c96b2b 100644 --- a/versioned_docs/version-4.0.0/server/sdk-installation/java.md +++ b/versioned_docs/version-4.0.0/server/sdk-installation/java.md @@ -29,13 +29,13 @@ Because the SDK is a Java agent, it is framework-agnostic. It can be attached to ## Requirements - Java 8, 17, or 21 -- `io.keploy:keploy-sdk` version with Java-agent support -- JaCoCo Java agent attached to the application JVM +- `io.keploy:keploy-sdk` `2.0.6` (or newer with Java-agent support) +- JaCoCo runtime agent (tested with `0.8.12`) - Keploy Enterprise with dynamic deduplication enabled -## Copy the Keploy Java Agent +## Copy the Keploy SDK and JaCoCo Agents -Copy the Keploy Java agent jar during your build. Do not add it under ``, and do not import Keploy classes from your application code. +Both jars are runtime agents — copy them into `target/` at build time. Do not add the Keploy SDK under `` and do not import Keploy classes from your code. ```xml @@ -46,9 +46,7 @@ Copy the Keploy Java agent jar during your build. Do not add it under ` copy-keploy-java-agent package - - copy - + copy @@ -61,71 +59,64 @@ Copy the Keploy Java agent jar during your build. Do not add it under ` + + copy-jacoco-agent + package + copy + + + + org.jacoco + org.jacoco.agent + 0.8.12 + runtime + jar + ${project.build.directory} + jacocoagent.jar + + + + ``` -## Run with the Keploy and JaCoCo Java Agents +## Run with Both Agents -The SDK reads coverage in-process via JaCoCo's runtime API (`org.jacoco.agent.rt.RT.getAgent()`), so attach both agents in the application JVM: the Keploy agent starts the dedup control socket, and the JaCoCo agent provides runtime coverage. +Attach both agents in the application JVM. The Keploy agent reads coverage in-process via JaCoCo's runtime API, so order doesn't matter as long as both are present: ```bash java \ -javaagent:target/keploy-sdk.jar \ - -javaagent:/path/to/jacocoagent.jar \ + -javaagent:target/jacocoagent.jar \ -jar target/app.jar ``` -The SDK automatically looks for application classes in Maven `target/classes`, Gradle `build/classes/java/main`, executable jars, Spring Boot `BOOT-INF/classes`, servlet `WEB-INF/classes`, and the runtime classpath. If your compiled application classes live somewhere else, set `KEPLOY_JAVA_CLASS_DIRS` to the class directory or archive that should be analyzed: +The SDK auto-detects application classes from Maven `target/classes`, Gradle `build/classes/java/main`, executable jars, Spring Boot `BOOT-INF/classes`, servlet `WEB-INF/classes`, and the runtime classpath. For custom layouts, point it at the right directory or archive: ```bash export KEPLOY_JAVA_CLASS_DIRS=/absolute/path/to/target/classes ``` -If the in-process API is unavailable in your environment, the SDK transparently falls back to JaCoCo's TCP server mode. To use the fallback explicitly, launch JaCoCo in `tcpserver` mode and configure `KEPLOY_JACOCO_HOST` / `KEPLOY_JACOCO_PORT` (defaults: `127.0.0.1:36320`): - -```bash -java \ - -javaagent:target/keploy-sdk.jar \ - -javaagent:/path/to/jacocoagent.jar=address=127.0.0.1,port=36320,output=tcpserver \ - -jar target/app.jar -``` - ## Replay with Dedup -Run Keploy in test mode with dynamic deduplication enabled: - ```bash keploy test \ - -c "java -javaagent:target/keploy-sdk.jar -javaagent:/path/to/jacocoagent.jar -jar target/app.jar" \ + -c "java -javaagent:target/keploy-sdk.jar -javaagent:target/jacocoagent.jar -jar target/app.jar" \ --dedup \ --language java ``` -If you are using the JaCoCo TCP fallback, also pass `--pass-through-ports ` so Keploy does not try to mock the coverage-control connection. - -After replay, run: +This produces `dedupData.yaml` (per-testcase coverage map). Then: ```bash -keploy dedup +keploy dedup # writes duplicates.yaml grouping the redundant testcases per test-set +keploy dedup --rm # removes the redundant testcases from the local Keploy test set ``` -To apply the dynamic deduplication cleanup: - -```bash -keploy dedup --rm -``` - -## Docker and Restricted Docker - -Java dedup uses two Unix sockets shared between Keploy Enterprise and the Java process: - -- `/tmp/coverage_control.sock` -- `/tmp/coverage_data.sock` - -For Docker or Docker Compose runs, Keploy injects a shared `keploy-sockets-vol:/tmp` mount into the application container and the Keploy agent container so both processes use the same socket paths. Do not add a conflicting `/tmp` bind mount or `tmpfs`; keep `/tmp` writable even when the root filesystem is read-only. +## Docker -For restricted containers, the application can run as a non-root user with dropped capabilities and `no-new-privileges` as long as the injected `/tmp` volume is shared and writable. If the SDK falls back to JaCoCo TCP mode, the JaCoCo TCP port must also be reachable from the Java process. +Keploy injects a shared `keploy-sockets-vol:/tmp` mount into the application container and the Keploy agent container at replay time — that's how the dedup sockets are visible on both sides. Keep `/tmp` writable; do not add a conflicting `/tmp` bind mount or `tmpfs`. Restricted containers (non-root user, read-only root filesystem, dropped capabilities) work as long as `/tmp` stays writable. ## CI Guidance From 9cfe442abbeeeb2cfc2caefe8f8b78fd512b02f8 Mon Sep 17 00:00:00 2001 From: Asish Kumar Date: Fri, 1 May 2026 03:37:47 +0530 Subject: [PATCH 6/7] docs(java-dedup): remove redundant JaCoCo version note Remove the extra JaCoCo version note from the dynamic dedup docs now that the tested version is already covered in requirements and the Maven copy snippet. Also avoid spaced em dashes in the updated Java dedup docs and accept Karaf as a Vale vocabulary term so the changed docs lint cleanly. Signed-off-by: Asish Kumar --- vale_styles/config/vocabularies/Base/accept.txt | 1 + versioned_docs/version-4.0.0/keploy-cloud/deduplication.md | 6 +++--- .../version-4.0.0/server/sdk-installation/java.md | 4 ++-- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/vale_styles/config/vocabularies/Base/accept.txt b/vale_styles/config/vocabularies/Base/accept.txt index c35e1219e..e4d88a77f 100644 --- a/vale_styles/config/vocabularies/Base/accept.txt +++ b/vale_styles/config/vocabularies/Base/accept.txt @@ -48,6 +48,7 @@ json_contains json_equal json_path JUnit +[Kk]araf kubectl kubernetes test-gen diff --git a/versioned_docs/version-4.0.0/keploy-cloud/deduplication.md b/versioned_docs/version-4.0.0/keploy-cloud/deduplication.md index ed88a85b7..32dd4fa69 100644 --- a/versioned_docs/version-4.0.0/keploy-cloud/deduplication.md +++ b/versioned_docs/version-4.0.0/keploy-cloud/deduplication.md @@ -121,9 +121,9 @@ keploy dedup --rm #### 1. Pre-requisite -Java dynamic deduplication uses JaCoCo runtime coverage. Attach the Keploy Java agent to emit per-test coverage signals, and attach the JaCoCo runtime agent so the SDK can read the coverage data. The Java agent is framework-agnostic — Spring Boot, Dropwizard/Jersey, plain executable jars, classpath-based apps, servlet/WAR archives, etc. +Java dynamic deduplication uses JaCoCo runtime coverage. Attach the Keploy Java agent to emit per-test coverage signals, and attach the JaCoCo runtime agent so the SDK can read the coverage data. The Java agent is framework-agnostic across Spring Boot, Dropwizard/Jersey, plain executable jars, classpath-based apps, servlet/WAR archives, etc. -Copy both jars into `target/` during your Maven build (do not add the Keploy SDK as an application dependency, and do not import Keploy classes from your code). Tested with JaCoCo `0.8.12`. +Copy both jars into `target/` during your Maven build (do not add the Keploy SDK as an application dependency, and do not import Keploy classes from your code). ```xml @@ -220,7 +220,7 @@ For Native, run: keploy test -c "java -javaagent:target/keploy-sdk.jar -javaagent:target/jacocoagent.jar -jar target/app.jar" --dedup --language java ``` -This produces `dedupData.yaml` — a per-testcase coverage map (`testSetID/testCaseID` → executed lines per source file) Keploy uses to compute redundancy. +This produces `dedupData.yaml`, a per-testcase coverage map (`testSetID/testCaseID` to executed lines per source file) Keploy uses to compute redundancy. ```bash keploy dedup diff --git a/versioned_docs/version-4.0.0/server/sdk-installation/java.md b/versioned_docs/version-4.0.0/server/sdk-installation/java.md index 079c96b2b..58d7ddbf5 100644 --- a/versioned_docs/version-4.0.0/server/sdk-installation/java.md +++ b/versioned_docs/version-4.0.0/server/sdk-installation/java.md @@ -35,7 +35,7 @@ Because the SDK is a Java agent, it is framework-agnostic. It can be attached to ## Copy the Keploy SDK and JaCoCo Agents -Both jars are runtime agents — copy them into `target/` at build time. Do not add the Keploy SDK under `` and do not import Keploy classes from your code. +Both jars are runtime agents. Copy them into `target/` at build time. Do not add the Keploy SDK under `` and do not import Keploy classes from your code. ```xml @@ -116,7 +116,7 @@ keploy dedup --rm # removes the redundant testcases from the local Keploy test ## Docker -Keploy injects a shared `keploy-sockets-vol:/tmp` mount into the application container and the Keploy agent container at replay time — that's how the dedup sockets are visible on both sides. Keep `/tmp` writable; do not add a conflicting `/tmp` bind mount or `tmpfs`. Restricted containers (non-root user, read-only root filesystem, dropped capabilities) work as long as `/tmp` stays writable. +Keploy injects a shared `keploy-sockets-vol:/tmp` mount into the application container and the Keploy agent container at replay time, so the dedup sockets are visible on both sides. Keep `/tmp` writable; do not add a conflicting `/tmp` bind mount or `tmpfs`. Restricted containers (non-root user, read-only root filesystem, dropped capabilities) work as long as `/tmp` stays writable. ## CI Guidance From 9cdc1b719beb5d3f73d48d9778ac321192f3a68b Mon Sep 17 00:00:00 2001 From: Asish Kumar Date: Fri, 1 May 2026 04:40:12 +0530 Subject: [PATCH 7/7] docs(java-dedup): document Docker class roots Signed-off-by: Asish Kumar --- versioned_docs/version-4.0.0/keploy-cloud/deduplication.md | 6 ++++-- .../version-4.0.0/server/sdk-installation/java.md | 7 +++++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/versioned_docs/version-4.0.0/keploy-cloud/deduplication.md b/versioned_docs/version-4.0.0/keploy-cloud/deduplication.md index 32dd4fa69..ca24a0321 100644 --- a/versioned_docs/version-4.0.0/keploy-cloud/deduplication.md +++ b/versioned_docs/version-4.0.0/keploy-cloud/deduplication.md @@ -186,7 +186,7 @@ Build the application before running Keploy so the Java class files are availabl mvn clean package -DskipTests ``` -By default, the SDK scans Maven `target/classes`, Gradle `build/classes/java/main`, executable jars, Spring Boot `BOOT-INF/classes`, servlet `WEB-INF/classes`, and runtime classpath archives. For custom layouts or restricted Docker images, set `KEPLOY_JAVA_CLASS_DIRS` to the class directories or archives that should be analyzed. +By default, the SDK scans Maven `target/classes`, Gradle `build/classes/java/main`, executable jars, Spring Boot `BOOT-INF/classes`, servlet `WEB-INF/classes`, and runtime classpath archives. For custom layouts or restricted Docker images, set `KEPLOY_JAVA_CLASS_DIRS` to the class directories or archives that should be analyzed. For shaded or uber-jar Docker images, copy the compiled application classes into the image and point `KEPLOY_JAVA_CLASS_DIRS` at that directory so dependency classes do not participate in dedup signatures. #### 3. Dockerfile Configuration (Important for Docker Users) @@ -196,7 +196,9 @@ When you use Docker or Docker Compose, copy four artifacts into the runtime imag COPY target/app.jar /app/app.jar COPY target/keploy-sdk.jar /app/keploy-sdk.jar COPY target/jacocoagent.jar /app/jacocoagent.jar -COPY target/classes /app/target/classes +COPY target/classes /app/classes + +ENV KEPLOY_JAVA_CLASS_DIRS=/app/classes ENTRYPOINT ["java", \ "-javaagent:/app/keploy-sdk.jar", \ diff --git a/versioned_docs/version-4.0.0/server/sdk-installation/java.md b/versioned_docs/version-4.0.0/server/sdk-installation/java.md index 58d7ddbf5..d7da4884f 100644 --- a/versioned_docs/version-4.0.0/server/sdk-installation/java.md +++ b/versioned_docs/version-4.0.0/server/sdk-installation/java.md @@ -118,6 +118,13 @@ keploy dedup --rm # removes the redundant testcases from the local Keploy test Keploy injects a shared `keploy-sockets-vol:/tmp` mount into the application container and the Keploy agent container at replay time, so the dedup sockets are visible on both sides. Keep `/tmp` writable; do not add a conflicting `/tmp` bind mount or `tmpfs`. Restricted containers (non-root user, read-only root filesystem, dropped capabilities) work as long as `/tmp` stays writable. +For shaded or uber-jar images, also copy the compiled application classes into the runtime image and set `KEPLOY_JAVA_CLASS_DIRS` so dependency classes do not participate in dedup signatures: + +```dockerfile +COPY target/classes /app/classes +ENV KEPLOY_JAVA_CLASS_DIRS=/app/classes +``` + ## CI Guidance CI should run replay/test mode against checked-in Keploy test fixtures. Do not record Java dedup fixtures in the pipeline unless you intentionally want to refresh them.