in feline/src/main/java/com/spotify/feline/Feline.java [195:237]
static {
final Instrumentation instrumentation = ByteBuddyAgent.install();
try {
BytecodeUtils.injectBootstrapClasses(
instrumentation, Feline.class.getName().replace('.', '/') + "Runtime");
} catch (IOException e) {
throw new RuntimeException("Failed to inject Feline runtime", e);
}
new AgentBuilder.Default()
.with(new ThreadLocalCircularityLock())
.with(AgentBuilder.RedefinitionStrategy.RETRANSFORMATION)
.with(AgentBuilder.TypeStrategy.Default.DECORATE)
.with(AgentBuilder.InitializationStrategy.NoOp.INSTANCE)
// note: for debugging, it may help to remove .withErrorsOnly()
.with(AgentBuilder.Listener.StreamWriting.toSystemError().withErrorsOnly())
// Do not ignore JDK classes
.ignore(ElementMatchers.nameStartsWith("com.intellij.rt."))
// instrument CompletableFuture
.type(ElementMatchers.is(CompletableFuture.class))
.transform(FelineTransformer.forCompletableFuture())
.asTerminalTransformation()
// instrument all subtypes of Future, except for CompletableFuture (as the above
// transformation is terminal)
.type(ElementMatchers.isSubTypeOf(Future.class))
.transform(FelineTransformer.forFuture())
.asTerminalTransformation()
// Instrument allowed/disallowed methods
.type(allowancesTransformer)
.transform(allowancesTransformer)
.asTerminalTransformation()
// instrument ThreadLocal
.type(ElementMatchers.isSubTypeOf(ThreadLocal.class))
.transform(FelineThreadLocalTransformer.forThreadLocal())
.asTerminalTransformation()
.installOn(instrumentation);
}