byte-buddy: Simple java agent doesn't work

Hi!

I’m trying to replace javassist with ByteBuddy, but it’s not that intuitive 😦

You can see it here: https://github.com/bsideup/javaagent-boilerplate/tree/bytebuddy/src/main/java

If you have Docker installed, you can run it with ./gradlew test to see it in action.

Basically, I just want to add 1 method call on the argument, so I do:

public static void premain(String args, Instrumentation instrumentation) {
    new AgentBuilder.Default()
            .type(named("spark.webserver.JettyHandler"))
            .transform((builder, typeDescription, classLoader) ->
                    builder
                            .method(named("doHandle"))
                            .intercept(
                                    MethodDelegation.to(JettyHandlerInterceptor.class)
                                            .andThen(SuperMethodCall.INSTANCE)
                            )
            )
            .installOn(instrumentation);
}

Where JettyHandlerInterceptor looks like this:

import net.bytebuddy.implementation.bind.annotation.AllArguments;

import javax.servlet.http.HttpServletResponse;

public class JettyHandlerInterceptor {

    public static void doHandle(@AllArguments Object[] args) {
        System.out.println("!!!!!!!!!!!");
        System.out.println("!!!!!!!!!!!");
        ((HttpServletResponse) args[3]).setHeader("X-My-Super-Header", "header value");
    }
}

But it fails at runtime with:

java.lang.NoClassDefFoundError: javax/servlet/http/HttpServletResponse
at spark.webserver.JettyHandlerInterceptor.doHandle(JettyHandlerInterceptor.java:12)

What I’m doing wrong?

Thanks!

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Reactions: 1
  • Comments: 17 (8 by maintainers)

Commits related to this issue

Most upvoted comments

Just FYI, I finally found some time to add an out-of-the-box API for this pattern, see #220.

You can now use the advice that you wanted by:

builder = builder.transform(new AgentBuilder.Transformation.ForAdvice()
  .include(getClass().getClassLoader()) // must be able to see "pkg.JettyHandlerAdvice"
  .advice(named("doHandle"), "pkg.JettyHandlerAdvice"));

Let me know if you are still trying this out and have any questions.