Java runtime instrumentation
Branch: master
Clone or download
Latest commit 01d482a Feb 14, 2019
Type Name Latest commit message Commit time
Failed to load latest commit information.
.github PR template Sep 26, 2018
docs docs: remove outdated docs Feb 14, 2019
e2e test: testing the shutdown hook's functionality Jan 29, 2019
gradle/wrapper chore: updates Jan 29, 2019
src chore: update bundled data Feb 14, 2019
.gitignore chore: move to gradle 5 Dec 5, 2018
.travis.yml chore: switch back to the java9 branch Feb 14, 2019
LICENSE chore: license Nov 7, 2018 docs: link to java-woof Jan 30, 2019 chore: rearrange and document (1 of ..) Oct 15, 2018
build.gradle.kts chore: updates Jan 29, 2019
gradlew chore: updates Jan 29, 2019
gradlew.bat chore: updates Jan 29, 2019


Getting started

The best way to get started with the agent is to run the example project, java-woof. Head over there for a getting started guide.


Build is using gradle. You can use the wrapper, if you don't have gradle:

  • ./gradlew clean build to do a full test and build.
  • ./gradlew test to just run the unit tests.
  • ./gradlew distZip to build a distribution.

Everything is a production build by default; there is no test/debug build.

The build outputs build/libs/snyk-java-runtime-agent.jar. This must be provided to your victim JVM, as explained in docs/

Currently, we only test Java 8. Java 9-11 will give weird errors about illegal reflective access.


If you have java-goof checked out in the current directory:

# build the runtime-agent
./gradlew build

# the runtime-agent reads the config file from `` next to the library
echo 'projectId=cf257fa0-37f9-4690-a3fc-a71f0417ded6' > build/libs/

# start goof, with the local runtime agent
(cd java-goof && MAVEN_OPTS="-javaagent:../build/libs/snyk-java-runtime-agent.jar" mvn tomcat7:run)

It should output something like:

...agent initialisation: loading config from: /foo/build/libs/
...agent initialisation: switching logging to /foo/build/libs/snyk-logs/agent-1.33.7.log

From then on, all logging will be in the named file. The tomcat startup should proceed as normal.

Code layout

This is a really weird project. Here are the restrictions that caused that:

  • No libraries, so we don't pollute anyone else's classpath
  • Performance optimisations everywhere; static method calls, concurrent counters, etc.
  • Paranoia about many things; load order, etc.

Architecture overview:

arch diagram

This doesn't mention a couple of critical classes:

  • UseCounter: the performance-critical store (in LandingZone) of whether something is called
  • ClassInfo: Transformer's helper for loading info about .jars.

Every class should have at least a sentence explaining what it does, in its documentation string.

Other docs

There's a number of documents, many relate to the project:

  • Monitoring introduction: An overview of how this type of monitoring works.
  • Initial thoughts: The initial analysis of the project specification.
  • Performance: A (mostly historical) review of the performance development of this tool.
  • Risks: Discusses the risks involved in this type of project, and how we specifically mitigate them.
  • Starting explains how to install the runtime-agent in different types of project.
  • Sample events beacon and metadata beacon files, that homebase is consuming.