11package com .datadog .debugger .util ;
22
33import java .lang .instrument .Instrumentation ;
4+ import java .lang .reflect .Method ;
5+ import java .util .regex .Matcher ;
6+ import java .util .regex .Pattern ;
7+ import org .slf4j .Logger ;
8+ import org .slf4j .LoggerFactory ;
49
510public class SpringHelper {
11+ private static final Logger LOGGER = LoggerFactory .getLogger (SpringHelper .class );
612
713 public static boolean isSpringUsingOnlyMethodParameters (Instrumentation inst ) {
14+ try {
15+ return isSpringUsingOnlyMethodParametersSpringVersion (inst );
16+ } catch (Exception e ) {
17+ LOGGER .debug ("isSpringUsingOnlyMethodParameters failed for SpringVersion" , e );
18+ // fallback to lookup for specific class
19+ return isSpringUsingOnlyMethodParametersSpecificClass (inst );
20+ }
21+ }
22+
23+ private static boolean isSpringUsingOnlyMethodParametersSpringVersion (Instrumentation inst ) {
24+ try {
25+ // scan for getting an already loaded class and get the classloader
26+ ClassLoader springClassLoader = null ;
27+ for (Class <?> clazz : inst .getAllLoadedClasses ()) {
28+ if (clazz .getName ().startsWith ("org.springframework.core" )) {
29+ springClassLoader = clazz .getClassLoader ();
30+ }
31+ }
32+ if (springClassLoader == null ) {
33+ throw new IllegalStateException ("Cannot find Spring classloader" );
34+ }
35+ Class <?> springVersionClass =
36+ Class .forName ("org.springframework.core.SpringVersion" , true , springClassLoader );
37+ Method m = springVersionClass .getDeclaredMethod ("getVersion" );
38+ String version = (String ) m .invoke (null );
39+ ParsedSpringVersion springVersion = new ParsedSpringVersion (version );
40+ // if Spring version is 6.1+ only using MethodParameters
41+ return springVersion .major > 6 || (springVersion .major == 6 && springVersion .minor >= 1 );
42+ } catch (Exception e ) {
43+ throw new RuntimeException (e );
44+ }
45+ }
46+
47+ private static boolean isSpringUsingOnlyMethodParametersSpecificClass (Instrumentation inst ) {
848 for (Class <?> clazz : inst .getAllLoadedClasses ()) {
949 if ("org.springframework.web.client.RestClient" .equals (clazz .getName ())) {
1050 // If this class (coming from Spring web since version 6.1) is found loaded it means Spring
@@ -15,4 +55,23 @@ public static boolean isSpringUsingOnlyMethodParameters(Instrumentation inst) {
1555 // class not found, probably no Spring
1656 return false ;
1757 }
58+
59+ private static class ParsedSpringVersion {
60+ private static final Pattern VERSION_PATTERN = Pattern .compile ("(\\ d+)\\ .(\\ d+)\\ .(\\ d+)" );
61+
62+ final int major ;
63+ final int minor ;
64+ final int patch ;
65+
66+ public ParsedSpringVersion (String strVersion ) {
67+ Matcher matcher = VERSION_PATTERN .matcher (strVersion );
68+ if (matcher .find ()) {
69+ major = Integer .parseInt (matcher .group (1 ));
70+ minor = Integer .parseInt (matcher .group (2 ));
71+ patch = Integer .parseInt (matcher .group (3 ));
72+ } else {
73+ throw new IllegalArgumentException ("Cannot parse SpringVersion: " + strVersion );
74+ }
75+ }
76+ }
1877}
0 commit comments