cant advice the javax.servlet.http.HttpServlet and acquired the request`s header
I want to advice the HttpServletRequest and to acquired the header
when I advice on Class javax.servlet.http.HttpServlet, method service(HttpServletRequest req, HttpServletResponse resp) ,cant advice the method.
for example:
new AgentBuilder.Default(byteBuddy) .ignore(nameStartsWith("net.bytebuddy.") .or(nameStartsWith("org.slf4j.")) .or(nameStartsWith("org.apache.logging.")) .or(nameStartsWith("org.groovy.")) .or(nameContains("javassist")) .or(nameContains(".asm.")) .or(nameStartsWith("sun.reflect")) .or(ElementMatchers.isSynthetic())) // 拦截 .type(ElementMatchers.named(RPC_INVOKER_TRANSFORMER) .or(ElementMatchers.named(RPC_PRODUCER_OPER_TRANSFORMER)) .or(ElementMatchers.named(HTTP_NIO_CLIENT_TRANSFORMER)) .or(ElementMatchers.named(HTTP_CLIENT_TRANSFORMER)) .or(ElementMatchers.named("javax.servlet.http.HttpServlet")) .or(ElementMatchers.nameStartsWith(IOT_SERVICE_PREFIX_TRANSFORMER))) // 设置Transform .transform(new Transformer()) .with(AgentBuilder.RedefinitionStrategy.RETRANSFORMATION) .installOn(inst);
And my transForm is blow: ` public class Transformer implements AgentBuilder.Transformer {
@Override
public DynamicType.Builder<?> transform(DynamicType.Builder<?> builder, TypeDescription typeDescription, ClassLoader classLoader, JavaModule module) {
//RPC客户端调用拦截
try {
if (typeDescription.getTypeName().startsWith("com.huawei.")
&& !HttpAgentUtil.checkRpcRestSchemaAnn(typeDescription) || "javax.servlet.http.HttpServlet".equals(typeDescription.getTypeName())) {
//Http服务端调用拦截,需要去除通过CSE @RestSchema注解定义的RPC接口(和Http定义类似)
System.out.println("Transformer " + typeDescription);
//只对有RequestMapping/PostMapping/GetMapping/DeleteMapping/PutMapping注解的函数进行拦截
DynamicType.Builder<?> builder1 = builder.visit(Advice.to(HttpServerInvInterceptor.class).on(
ElementMatchers.named("service").and(ElementMatchers.takesArgument(0,ElementMatchers.named("javax.servlet.http.HttpServletRequest")))
));
return builder1;
}
} catch (Throwable e) {
System.err.println("error " + e.getMessage());
}
return builder;
}
} ` and my HttpServerInvInterceptor is below :
@Advice.OnMethodEnter public static void enter(@Advice.Origin("#t.#m") String signature, @Advice.AllArguments Object[] args, @Advice.Origin("#t") String className, @Advice.Origin("#m") String methodName) { try { if (args[0] instanceof HttpServletRequest) { HttpServletRequest request = (HttpServletRequest) args[0]; String sp = request.getHeader("sp"); System.out.println("sp: " + sp); } AgentUtils.logInfo("===start Enter " + signature + "==="); System.out.println("Im coming"); setHttpServerMethodLogStartTime(System.currentTimeMillis()); AgentUtils.logInfo("get the method start time"); AgentUtils.logInfo("===end Enter " + signature + "==="); } catch (Throwable e) { AgentUtils.logWarn("execute " + signature + " Enter Exception:" + ExceptionUtil.getBriefExceptionStackTrace(e)); destroyHttpServerMethodLogStartTime(); } }
and then , i cant acquired the HttpServletRequest.
Excuse me, where is this configuration processing wrong?
Did you try registering a listener? It would show you any types being transformed or that fail. I recommend to also set disableClassFormatChanges.
when the project start, i can see the log : FlowListener: javax.servlet.http.HttpServlet FlowListener: javax.servlet.http.HttpServlet
but when i send the http request ,my Listener cant serch the log, so, i guess my TransForm only advice once time, and after my project started, my transform cant advice the HttpServlet.
listener as below: ` public class FlowListener implements AgentBuilder.Listener {
@Override
public void onDiscovery(String s, ClassLoader classLoader, JavaModule javaModule, boolean b) {
System.out.println("FlowListener: " + s);
}
@Override
public void onTransformation(TypeDescription typeDescription, ClassLoader classLoader, JavaModule javaModule, boolean b, DynamicType dynamicType) {
System.out.println("FlowListener: " + typeDescription.getTypeName());
}
@Override
public void onIgnored(TypeDescription typeDescription, ClassLoader classLoader, JavaModule javaModule, boolean b) {
System.out.println("FlowListener: " + typeDescription.getTypeName());
}
@Override
public void onError(String s, ClassLoader classLoader, JavaModule javaModule, boolean b, Throwable throwable) {
System.out.println("FlowListener: " + s);
}
@Override
public void onComplete(String s, ClassLoader classLoader, JavaModule javaModule, boolean b) {
System.out.println("FlowListener: " + s);
}
} `
any other suggestions? thanks
Could you use Byte Buddy's print writing listener or change yours to showcase if this was a successful or a failed transformation? Maybe it was even ignored. I recommend using Byte Buddy's builtin listener, it is quite detailed and even has a factory for writing to the output stream.
Try this way while instantiating the Agent:
.type(isSubTypeOf(new TypeDescription.Latent("javax.servlet.GenericServlet", Modifier.PUBLIC | Modifier.ABSTRACT, TypeDescription.Generic.OBJECT))) .transform( new AgentBuilder.Transformer.ForAdvice() .include(ExecuteAgent.class.getClassLoader()) .advice( named("service") .and(takesArgument(0, named("javax.servlet.ServletRequest"))) .and(takesArgument(1, named("javax.servlet.ServletResponse"))) , "com.your.advice.yourAdvice" ) )
and have appropriate code in your advice:
@Advice.OnMethodEnter public static void enter(//@Advice.This Object obj, @Advice.Argument(value = 0) ServletRequest request, @Advice.Argument(value = 1) ServletResponse response, //@Advice.AllArguments Object[] allArguments, //@Advice.Origin("#t") String className, @Advice.Origin("#m") String methodName) {
Hopefully this helps you.