1
1
/*
2
- * Copyright 2002-2021 the original author or authors.
2
+ * Copyright 2002-2023 the original author or authors.
3
3
*
4
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
5
* you may not use this file except in compliance with the License.
21
21
import java .util .Map ;
22
22
import java .util .concurrent .ConcurrentHashMap ;
23
23
24
+ import org .apache .commons .logging .LogFactory ;
25
+
24
26
import org .springframework .core .DecoratingClassLoader ;
25
27
import org .springframework .core .OverridingClassLoader ;
26
28
import org .springframework .core .SmartClassLoader ;
@@ -45,15 +47,26 @@ class ContextTypeMatchClassLoader extends DecoratingClassLoader implements Smart
45
47
}
46
48
47
49
48
- private static Method findLoadedClassMethod ;
50
+ @ Nullable
51
+ private static final Method findLoadedClassMethod ;
49
52
50
53
static {
54
+ // Try to enable findLoadedClass optimization which allows us to selectively
55
+ // override classes that have not been loaded yet. If not accessible, we will
56
+ // always override requested classes, even when the classes have been loaded
57
+ // by the parent ClassLoader already and cannot be transformed anymore anyway.
58
+ Method method = null ;
51
59
try {
52
- findLoadedClassMethod = ClassLoader .class .getDeclaredMethod ("findLoadedClass" , String .class );
60
+ method = ClassLoader .class .getDeclaredMethod ("findLoadedClass" , String .class );
61
+ ReflectionUtils .makeAccessible (method );
53
62
}
54
- catch (NoSuchMethodException ex ) {
55
- throw new IllegalStateException ("Invalid [java.lang.ClassLoader] class: no 'findLoadedClass' method defined!" );
63
+ catch (Throwable ex ) {
64
+ // Typically a JDK 9+ InaccessibleObjectException...
65
+ // Avoid through JVM startup with --add-opens=java.base/java.lang=ALL-UNNAMED
66
+ LogFactory .getLog (ContextTypeMatchClassLoader .class ).debug (
67
+ "ClassLoader.findLoadedClass not accessible -> will always override requested class" , ex );
56
68
}
69
+ findLoadedClassMethod = method ;
57
70
}
58
71
59
72
@@ -96,13 +109,14 @@ protected boolean isEligibleForOverriding(String className) {
96
109
if (isExcluded (className ) || ContextTypeMatchClassLoader .this .isExcluded (className )) {
97
110
return false ;
98
111
}
99
- ReflectionUtils .makeAccessible (findLoadedClassMethod );
100
- ClassLoader parent = getParent ();
101
- while (parent != null ) {
102
- if (ReflectionUtils .invokeMethod (findLoadedClassMethod , parent , className ) != null ) {
103
- return false ;
112
+ if (findLoadedClassMethod != null ) {
113
+ ClassLoader parent = getParent ();
114
+ while (parent != null ) {
115
+ if (ReflectionUtils .invokeMethod (findLoadedClassMethod , parent , className ) != null ) {
116
+ return false ;
117
+ }
118
+ parent = parent .getParent ();
104
119
}
105
- parent = parent .getParent ();
106
120
}
107
121
return true ;
108
122
}
0 commit comments