Integration recipes
Complete installation first. Keep your application's existing dependency and compiler configuration; add the plugins under <build><plugins>. Run mvn verify and inspect target/cryptocensus/cbom.json.
JaCoCo and custom JVM options
Give Census its own property and use Surefire's @{...} late binding so both agents survive initialization. Define empty properties to keep profiles that disable either preparer usable. The same final argLine must reach every forked test execution.
<properties>
<argLine></argLine>
<censusArgLine></censusArgLine>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.15</version>
<executions>
<execution><goals><goal>prepare-agent</goal></goals></execution>
<execution>
<id>coverage-report</id><phase>verify</phase>
<goals><goal>report</goal></goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>com.developmentsprint</groupId>
<artifactId>census-maven-plugin</artifactId>
<version>0.1.0</version>
<configuration><propertyName>censusArgLine</propertyName></configuration>
<executions>
<execution><goals><goal>prepare-agent</goal><goal>check</goal></goals></execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.5.4</version>
<configuration>
<argLine>@{argLine} @{censusArgLine} -Xmx1g</argLine>
</configuration>
</plugin>
</plugins>
</build>Census and JaCoCo evidence should both appear: target/cryptocensus/cbom.json and target/site/jacoco/index.html. -DargLine=... overrides the project property JaCoCo modifies; put custom JVM flags in the POM. Surefire documents the reason for late property evaluation.
Failsafe
Bind Failsafe before Census in the plugin list so its verification runs first. Census preparation in initialize covers both Surefire and Failsafe; its single check at verify merges their per-JVM reports. With the JaCoCo recipe, give Failsafe the same composed argLine.
<properties><censusArgLine></censusArgLine></properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>3.5.4</version>
<configuration><argLine>@{censusArgLine}</argLine></configuration>
<executions>
<execution><goals><goal>integration-test</goal><goal>verify</goal></goals></execution>
</executions>
</plugin>
<plugin>
<groupId>com.developmentsprint</groupId>
<artifactId>census-maven-plugin</artifactId>
<version>0.1.0</version>
<configuration><propertyName>censusArgLine</propertyName></configuration>
<executions>
<execution><goals><goal>prepare-agent</goal><goal>check</goal></goals></execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.5.4</version>
<configuration><argLine>@{censusArgLine}</argLine></configuration>
</plugin>
</plugins>
</build>Name integration tests *IT.java and unit tests *Test.java, then run mvn verify, not mvn integration-test. Re-running prepare-agent before Failsafe in the same Maven build reuses the run directory. One execution's evidence cannot prove another execution attached; verify each custom execution's configuration.
Multiple Maven modules
Put the README plugin under the parent POM's <build><plugins> to inherit both executions into every module. A parent with packaging pom and no tests skips missing-data failure when no compiled tests exist. Each child writes its own target/cryptocensus/cbom.json; run the parent with:
mvn -T 2 verifyKeep the default per-module destinations. check merges JVM reports for one project; it is not a reactor-wide aggregate goal. Publish all child reports as separate CI artifacts. A plugin declaration only inside <pluginManagement> supplies defaults but does not activate the plugin; add it under each participating child's <plugins> if opting in that way. Shared output filenames can overwrite each other's merged reports even though unique input run directories remain separate.
CI scanning and downloadable CBOMs
This repository's CI workflow includes a Maven plugin dogfood / runtime CBOM job. It installs the plugin and agent from the current checkout, then uses the plugin to scan the demo's payments tests in a separate Maven invocation. The tests exercise signing, encryption and checksums; the normal conformance matrix independently runs the full test suite.
Open the GitHub Actions run summary and download crypto-census-cbom from Artifacts. It contains the selected sealed revision's evidence.json runtime cryptographic inventory and manifest.json. crypto-census-cbom-jvm-reports contains the exact run descriptor and available individual JVM reports for diagnosis. Both artifacts have a 14-day retention period.
Reproduce the basic scan from the repository root with JDK 17:
./mvnw -B -ntp -pl census-maven-plugin -am clean install -DskipTests -DskipITs -Dinvoker.skip=true
./mvnw -B -ntp -pl census-demo clean verifyOnly the bootstrap skips tests; the second command runs the demo tests with Census attached and writes census-demo/target/cryptocensus/cbom.json. Cleaning the demo before scanning prevents an old report from appearing as current evidence. This basic invocation uses check; the CI job additionally supplies a fresh census.runId and runs independent finalization and enforcement steps.
The workflow runs report even when the producer fails, seals available current-run evidence, uploads it when finalization succeeds, and runs enforce independently. It keeps the original Maven failure status. For example, a quantum-vulnerable threshold rejects the demo's observed findings without suppressing evidence archival. A test failure before check can still leave JVM reports for report to finalize; a missing or corrupted run fails finalization, and abrupt JVM termination may leave no reports. See CI finalization for the exact identity, manifest, and policy requirements, or the CI guide for the workflow walkthrough.
This inventory covers cryptography observed in the demo workload. It is not a dependency SBOM or a scan of every path in the tool's own implementation. Uploading a workflow artifact also does not deliver it to an enterprise security platform.
Standalone container
Copy your acquired shaded agent to census-agent.jar, place your runnable application at app.jar, and create this Dockerfile. Choose and pin an approved JRE image for your deployment; this example's base tag is illustrative and does not add a conformance row.
FROM eclipse-temurin:25-jre
WORKDIR /app
COPY app.jar census-agent.jar ./
ENTRYPOINT ["java", "-javaagent:/app/census-agent.jar=dir=/reports,app=example", "-jar", "/app/app.jar"]On a POSIX host, use the current user's UID/GID and a private writable report mount. The exec-form entry point makes Java receive the termination signal. Substitute an unused container name if needed.
mkdir -m 700 reports
docker build -t census-example .
docker run -d --name census-example \
--user "$(id -u):$(id -g)" \
--mount "type=bind,src=$(pwd)/reports,dst=/reports" \
census-example
# Exercise the application's endpoints or workload before stopping it.
docker stop --timeout 60 census-example
docker logs census-example
ls -l reports
docker rm census-exampleDo not use --rm if evidence is kept only inside a container. A bind mount survives removal; otherwise copy the report out of the stopped container before removing it. A timeout that forces a kill can lose the report.
Open Liberty
For the verified Liberty image, copy the agent to /opt/census/census-agent.jar. Append this line to /opt/ol/wlp/usr/servers/defaultServer/jvm.options (preserve existing options):
-javaagent:/opt/census/census-agent.jar=output=/tmp/cryptocensus-cbom.json,app=open-libertyDeploy your WAR into the server's dropins directory and exercise it. The repository provides a fully executable, pinned container example in AppServerIT; run it with the required-Docker command. For an operator-owned running container named census-liberty, stop and collect before removal:
docker stop --timeout 60 census-liberty
docker logs census-liberty
docker cp census-liberty:/tmp/cryptocensus-cbom.json ./liberty-cbom.json
docker rm census-libertyThe built-in /tmp destination is private to the container and writable by the server user. For persistent shared storage, use dir=/reports with a mount owned by the image's runtime UID/GID; verify write and rename access as that user. Never broaden permissions to world-writable to fix a mount mismatch.
WildFly
For the verified WildFly image, copy the agent to /opt/census/census-agent.jar, then append to the server's existing JAVA_OPTS in its environment or standalone.conf. If supplying JAVA_OPTS replaces the image's defaults, retain those defaults; the conformance test uses:
-Djava.net.preferIPv4Stack=true -Djboss.modules.system.pkgs=org.jboss.byteman -Djava.awt.headless=true -javaagent:/opt/census/census-agent.jar=output=/tmp/cryptocensus-cbom.json,app=wildflyDeploy the WAR into /opt/jboss/wildfly/standalone/deployments, exercise it, and use the same stop/copy/remove sequence with your WildFly container name. The pinned executable test demonstrates both deployments, graceful shutdown, and health assertions. Preserve other agents and server-specific JVM flags when composing options.