58
58
import hudson .security .ACLContext ;
59
59
import hudson .security .Permission ;
60
60
import hudson .security .PermissionScope ;
61
+ import hudson .util .CachingClassLoader ;
61
62
import hudson .util .CyclicGraphDetector ;
62
63
import hudson .util .CyclicGraphDetector .CycleDetectedException ;
63
- import hudson .util .DelegatingClassLoader ;
64
64
import hudson .util .ExistenceCheckingClassLoader ;
65
65
import hudson .util .FormValidation ;
66
66
import hudson .util .PersistedList ;
108
108
import java .util .Locale ;
109
109
import java .util .Map ;
110
110
import java .util .Objects ;
111
- import java .util .Optional ;
112
111
import java .util .ServiceLoader ;
113
112
import java .util .Set ;
114
113
import java .util .TreeMap ;
115
114
import java .util .UUID ;
116
115
import java .util .concurrent .ConcurrentHashMap ;
117
- import java .util .concurrent .ConcurrentMap ;
118
116
import java .util .concurrent .CopyOnWriteArrayList ;
119
117
import java .util .concurrent .Future ;
120
118
import java .util .function .Supplier ;
@@ -2402,12 +2400,9 @@ public <T> T of(String key, Class<T> type, Supplier<T> func) {
2402
2400
/**
2403
2401
* {@link ClassLoader} that can see all plugins.
2404
2402
*/
2405
- public static final class UberClassLoader extends DelegatingClassLoader {
2403
+ public static final class UberClassLoader extends CachingClassLoader {
2406
2404
private final List <PluginWrapper > activePlugins ;
2407
2405
2408
- /** Cache of loaded, or known to be unloadable, classes. */
2409
- private final ConcurrentMap <String , Optional <Class <?>>> loaded = new ConcurrentHashMap <>();
2410
-
2411
2406
/**
2412
2407
* The servlet container's {@link ClassLoader} (the parent of Jenkins core) is
2413
2408
* parallel-capable and maintains its own growing {@link Map} of {@link
@@ -2426,29 +2421,29 @@ public UberClassLoader(List<PluginWrapper> activePlugins) {
2426
2421
}
2427
2422
2428
2423
@ Override
2429
- protected Class <?> findClass (String name ) throws ClassNotFoundException {
2424
+ protected Class <?> loadClass (String name , boolean resolve ) throws ClassNotFoundException {
2430
2425
for (String namePrefixToSkip : CLASS_PREFIXES_TO_SKIP ) {
2431
2426
if (name .startsWith (namePrefixToSkip )) {
2432
2427
throw new ClassNotFoundException ("ignoring " + name );
2433
2428
}
2434
2429
}
2435
- return loaded . computeIfAbsent (name , this :: computeValue ). orElseThrow (() -> new ClassNotFoundException ( name ) );
2430
+ return super . loadClass (name , resolve );
2436
2431
}
2437
2432
2438
- private Optional <Class <?>> computeValue (String name ) {
2433
+ @ Override
2434
+ protected Class <?> findClass (String name ) throws ClassNotFoundException {
2439
2435
for (PluginWrapper p : activePlugins ) {
2440
2436
try {
2441
2437
if (FAST_LOOKUP ) {
2442
- return Optional . of ( ClassLoaderReflectionToolkit .loadClass (p .classLoader , name ) );
2438
+ return ClassLoaderReflectionToolkit .loadClass (p .classLoader , name );
2443
2439
} else {
2444
- return Optional . of ( p .classLoader .loadClass (name ) );
2440
+ return p .classLoader .loadClass (name );
2445
2441
}
2446
2442
} catch (ClassNotFoundException e ) {
2447
2443
// Not found. Try the next class loader.
2448
2444
}
2449
2445
}
2450
- // Not found in any of the class loaders. Delegate.
2451
- return Optional .empty ();
2446
+ throw new ClassNotFoundException (name );
2452
2447
}
2453
2448
2454
2449
@ Override
@@ -2480,10 +2475,6 @@ protected Enumeration<URL> findResources(String name) throws IOException {
2480
2475
return Collections .enumeration (resources );
2481
2476
}
2482
2477
2483
- void clearCacheMisses () {
2484
- loaded .values ().removeIf (Optional ::isEmpty );
2485
- }
2486
-
2487
2478
@ Override
2488
2479
public String toString () {
2489
2480
// only for debugging purpose
0 commit comments