From ea291e748138cfab84aeb0229ca6677c91b7c5f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20Soko=C5=82owski?= Date: Sun, 17 Sep 2023 10:07:44 +0200 Subject: [PATCH 1/2] fix spring 6 pointcuts, after migration from javax to jakarta --- .../spring/HandleInternalInvokerPointCut.java | 8 +++++++- .../frameworks/spring/HandlerInterceptorPointCut.java | 10 +++++++++- .../frameworks/spring/SpringDispatcherPointCut.java | 7 ++++++- .../spring/SpringExceptionHandlerPointCut.java | 8 +++++++- 4 files changed, 29 insertions(+), 4 deletions(-) diff --git a/newrelic-agent/src/main/java/com/newrelic/agent/instrumentation/pointcuts/frameworks/spring/HandleInternalInvokerPointCut.java b/newrelic-agent/src/main/java/com/newrelic/agent/instrumentation/pointcuts/frameworks/spring/HandleInternalInvokerPointCut.java index 9ae987e3af..858b611b30 100644 --- a/newrelic-agent/src/main/java/com/newrelic/agent/instrumentation/pointcuts/frameworks/spring/HandleInternalInvokerPointCut.java +++ b/newrelic-agent/src/main/java/com/newrelic/agent/instrumentation/pointcuts/frameworks/spring/HandleInternalInvokerPointCut.java @@ -32,7 +32,13 @@ public HandleInternalInvokerPointCut(PointCutClassTransformer classTransformer) "(Ljavax/servlet/http/HttpServletRequest;Ljavax/servlet/http/HttpServletResponse;Lorg/springframework/web/method/HandlerMethod;)Lorg/springframework/web/servlet/ModelAndView;"), createExactMethodMatcher( "invokeHandlerMethod", - "(Ljavax/servlet/http/HttpServletRequest;Ljavax/servlet/http/HttpServletResponse;Lorg/springframework/web/method/HandlerMethod;)Lorg/springframework/web/servlet/ModelAndView;"))); + "(Ljavax/servlet/http/HttpServletRequest;Ljavax/servlet/http/HttpServletResponse;Lorg/springframework/web/method/HandlerMethod;)Lorg/springframework/web/servlet/ModelAndView;"), + createExactMethodMatcher( + "invokeHandleMethod", + "(Ljakarta/servlet/http/HttpServletRequest;Ljakarta/servlet/http/HttpServletResponse;Lorg/springframework/web/method/HandlerMethod;)Lorg/springframework/web/servlet/ModelAndView;"), + createExactMethodMatcher( + "invokeHandlerMethod", + "(Ljakarta/servlet/http/HttpServletRequest;Ljakarta/servlet/http/HttpServletResponse;Lorg/springframework/web/method/HandlerMethod;)Lorg/springframework/web/servlet/ModelAndView;"))); } @Override diff --git a/newrelic-agent/src/main/java/com/newrelic/agent/instrumentation/pointcuts/frameworks/spring/HandlerInterceptorPointCut.java b/newrelic-agent/src/main/java/com/newrelic/agent/instrumentation/pointcuts/frameworks/spring/HandlerInterceptorPointCut.java index 04244fb29c..dfc33d7431 100644 --- a/newrelic-agent/src/main/java/com/newrelic/agent/instrumentation/pointcuts/frameworks/spring/HandlerInterceptorPointCut.java +++ b/newrelic-agent/src/main/java/com/newrelic/agent/instrumentation/pointcuts/frameworks/spring/HandlerInterceptorPointCut.java @@ -33,7 +33,15 @@ public HandlerInterceptorPointCut(PointCutClassTransformer classTransformer) { "(Ljavax/servlet/http/HttpServletRequest;Ljavax/servlet/http/HttpServletResponse;Ljava/lang/Object;Lorg/springframework/web/servlet/ModelAndView;)V"), new ExactMethodMatcher( "afterCompletion", - "(Ljavax/servlet/http/HttpServletRequest;Ljavax/servlet/http/HttpServletResponse;Ljava/lang/Object;Ljava/lang/Exception;)V"))); + "(Ljavax/servlet/http/HttpServletRequest;Ljavax/servlet/http/HttpServletResponse;Ljava/lang/Object;Ljava/lang/Exception;)V"), + new ExactMethodMatcher("preHandle", + "(Ljakarta/servlet/http/HttpServletRequest;Ljakarta/servlet/http/HttpServletResponse;Ljava/lang/Object;)Z"), + new ExactMethodMatcher( + "postHandle", + "(Ljakarta/servlet/http/HttpServletRequest;Ljakarta/servlet/http/HttpServletResponse;Ljava/lang/Object;Lorg/springframework/web/servlet/ModelAndView;)V"), + new ExactMethodMatcher( + "afterCompletion", + "(Ljakarta/servlet/http/HttpServletRequest;Ljakarta/servlet/http/HttpServletResponse;Ljava/lang/Object;Ljava/lang/Exception;)V"))); } @Override diff --git a/newrelic-agent/src/main/java/com/newrelic/agent/instrumentation/pointcuts/frameworks/spring/SpringDispatcherPointCut.java b/newrelic-agent/src/main/java/com/newrelic/agent/instrumentation/pointcuts/frameworks/spring/SpringDispatcherPointCut.java index 1aef29e38a..e6ded68d7a 100644 --- a/newrelic-agent/src/main/java/com/newrelic/agent/instrumentation/pointcuts/frameworks/spring/SpringDispatcherPointCut.java +++ b/newrelic-agent/src/main/java/com/newrelic/agent/instrumentation/pointcuts/frameworks/spring/SpringDispatcherPointCut.java @@ -40,7 +40,12 @@ public SpringDispatcherPointCut(PointCutClassTransformer classTransformer) { RENDER_METHOD_NAME, "(Lorg/springframework/web/servlet/ModelAndView;Ljavax/servlet/http/HttpServletRequest;Ljavax/servlet/http/HttpServletResponse;)V"), new ExactMethodMatcher("doDispatch", - "(Ljavax/servlet/http/HttpServletRequest;Ljavax/servlet/http/HttpServletResponse;)V"))); + "(Ljavax/servlet/http/HttpServletRequest;Ljavax/servlet/http/HttpServletResponse;)V"), + new ExactMethodMatcher( + RENDER_METHOD_NAME, + "(Lorg/springframework/web/servlet/ModelAndView;Ljakarta/servlet/http/HttpServletRequest;Ljakarta/servlet/http/HttpServletResponse;)V"), + new ExactMethodMatcher("doDispatch", + "(Ljakarta/servlet/http/HttpServletRequest;Ljakarta/servlet/http/HttpServletResponse;)V"))); } @Override diff --git a/newrelic-agent/src/main/java/com/newrelic/agent/instrumentation/pointcuts/frameworks/spring/SpringExceptionHandlerPointCut.java b/newrelic-agent/src/main/java/com/newrelic/agent/instrumentation/pointcuts/frameworks/spring/SpringExceptionHandlerPointCut.java index 22a0ff5d1d..dae707e452 100644 --- a/newrelic-agent/src/main/java/com/newrelic/agent/instrumentation/pointcuts/frameworks/spring/SpringExceptionHandlerPointCut.java +++ b/newrelic-agent/src/main/java/com/newrelic/agent/instrumentation/pointcuts/frameworks/spring/SpringExceptionHandlerPointCut.java @@ -30,7 +30,13 @@ public SpringExceptionHandlerPointCut(PointCutClassTransformer classTransformer) "(Ljavax/servlet/http/HttpServletRequest;Ljavax/servlet/http/HttpServletResponse;Ljava/lang/Object;Ljava/lang/Exception;)Lorg/springframework/web/servlet/ModelAndView;"), new ExactMethodMatcher( "triggerAfterCompletion", - "(Lorg/springframework/web/servlet/HandlerExecutionChain;ILjavax/servlet/http/HttpServletRequest;Ljavax/servlet/http/HttpServletResponse;Ljava/lang/Exception;)V"))); + "(Lorg/springframework/web/servlet/HandlerExecutionChain;ILjavax/servlet/http/HttpServletRequest;Ljavax/servlet/http/HttpServletResponse;Ljava/lang/Exception;)V"), + new ExactMethodMatcher( + PROCESS_HANDLER_EXCEPTION_METHOD_NAME, + "(Ljakarta/servlet/http/HttpServletRequest;Ljakarta/servlet/http/HttpServletResponse;Ljava/lang/Object;Ljava/lang/Exception;)Lorg/springframework/web/servlet/ModelAndView;"), + new ExactMethodMatcher( + "triggerAfterCompletion", + "(Lorg/springframework/web/servlet/HandlerExecutionChain;ILjakarta/servlet/http/HttpServletRequest;Ljakarta/servlet/http/HttpServletResponse;Ljava/lang/Exception;)V"))); } @Override From f9f613209a81549b3ed8be86aefb2c342e1c4958 Mon Sep 17 00:00:00 2001 From: Jerry Duffy Date: Wed, 11 Oct 2023 13:03:05 -0400 Subject: [PATCH 2/2] Revert spring advice exception handling --- .../tomcat10/TomcatServletRequestListener.java | 11 +---------- .../frameworks/spring/SpringDispatcherPointCut.java | 2 +- 2 files changed, 2 insertions(+), 11 deletions(-) diff --git a/instrumentation/tomcat-10/src/main/java/com/nr/agent/instrumentation/tomcat10/TomcatServletRequestListener.java b/instrumentation/tomcat-10/src/main/java/com/nr/agent/instrumentation/tomcat10/TomcatServletRequestListener.java index 35fb47a70e..8b23a564e0 100644 --- a/instrumentation/tomcat-10/src/main/java/com/nr/agent/instrumentation/tomcat10/TomcatServletRequestListener.java +++ b/instrumentation/tomcat-10/src/main/java/com/nr/agent/instrumentation/tomcat10/TomcatServletRequestListener.java @@ -22,7 +22,6 @@ public final class TomcatServletRequestListener implements ServletRequestListener { private static final String SERVLET_EXCEPTION_ATTRIBUTE_NAME = "jakarta.servlet.error.exception"; - private static final String SPRING6_SERVLET_EXCEPTION_ATTRIBUTE_NAME = "org.springframework.web.servlet.DispatcherServlet.EXCEPTION"; private static final String REQUEST_FIELD = "request"; private final Field requestField; @@ -45,7 +44,7 @@ private Field getRequestField() { @CatchAndLog @Override public void requestDestroyed(ServletRequestEvent sre) { - Throwable exception = retrieveExceptionFromServlet(sre); + Throwable exception =(Throwable) sre.getServletRequest().getAttribute(SERVLET_EXCEPTION_ATTRIBUTE_NAME); if (exception != null) { AgentBridge.privateApi.reportException(exception); } @@ -98,12 +97,4 @@ private Request_Weaved getRequest(HttpServletRequest httpServletRequest) { } return null; } - - private Throwable retrieveExceptionFromServlet(ServletRequestEvent sre) { - //As of Spring 6, when controller advice is used for controller exception handling, the caught exception is - //now stored in the servlet attribute map with the "org.springframework.web.servlet.DispatcherServlet.EXCEPTION" key. - return (Throwable) (sre.getServletRequest().getAttribute(SERVLET_EXCEPTION_ATTRIBUTE_NAME) != null ? - sre.getServletRequest().getAttribute(SERVLET_EXCEPTION_ATTRIBUTE_NAME) : - sre.getServletRequest().getAttribute(SPRING6_SERVLET_EXCEPTION_ATTRIBUTE_NAME)); - } } \ No newline at end of file diff --git a/newrelic-agent/src/main/java/com/newrelic/agent/instrumentation/pointcuts/frameworks/spring/SpringDispatcherPointCut.java b/newrelic-agent/src/main/java/com/newrelic/agent/instrumentation/pointcuts/frameworks/spring/SpringDispatcherPointCut.java index e6ded68d7a..7ed8c0c15d 100644 --- a/newrelic-agent/src/main/java/com/newrelic/agent/instrumentation/pointcuts/frameworks/spring/SpringDispatcherPointCut.java +++ b/newrelic-agent/src/main/java/com/newrelic/agent/instrumentation/pointcuts/frameworks/spring/SpringDispatcherPointCut.java @@ -50,7 +50,7 @@ public SpringDispatcherPointCut(PointCutClassTransformer classTransformer) { @Override public Tracer doGetTracer(Transaction transaction, ClassMethodSignature sig, Object dispatcher, Object[] args) { - if (RENDER_METHOD_NAME == sig.getMethodName()) { + if (RENDER_METHOD_NAME.equals(sig.getMethodName())) { StringBuilder metricName = new StringBuilder("SpringView"); if (canSetTransactionName(transaction)) { try {