~ubuntu-branches/ubuntu/oneiric/tomcat6/oneiric

« back to all changes in this revision

Viewing changes to java/org/apache/catalina/loader/WebappClassLoader.java

  • Committer: Bazaar Package Importer
  • Author(s): Thierry Carrez
  • Date: 2010-07-20 14:36:48 UTC
  • mfrom: (2.2.17 sid)
  • Revision ID: james.westby@ubuntu.com-20100720143648-23y81x6cq1kv1z00
Tags: 6.0.28-2
* Add debconf questions for user, group and Java options.
* Use ucf to install /etc/default/tomcat6 from a template
* Drop CATALINA_BASE and CATALINA_HOME from /etc/default/tomcat6 since we
  shouldn't encourage users to change those anyway

Show diffs side-by-side

added added

removed removed

Lines of Context:
70
70
import org.apache.catalina.util.StringManager;
71
71
import org.apache.jasper.servlet.JasperLoader;
72
72
import org.apache.naming.JndiPermission;
 
73
import org.apache.naming.resources.ProxyDirContext;
73
74
import org.apache.naming.resources.Resource;
74
75
import org.apache.naming.resources.ResourceAttributes;
75
76
import org.apache.tomcat.util.IntrospectionUtils;
109
110
 *
110
111
 * @author Remy Maucherat
111
112
 * @author Craig R. McClanahan
112
 
 * @version $Revision: 915603 $ $Date: 2010-02-24 01:07:06 +0100 (Mi, 24. Feb 2010) $
 
113
 * @version $Id: WebappClassLoader.java 958934 2010-06-29 11:34:48Z markt $
113
114
 */
114
115
public class WebappClassLoader
115
116
    extends URLClassLoader
426
427
    protected boolean hasExternalRepositories = false;
427
428
 
428
429
    /**
 
430
     * Search external repositories first
 
431
     */
 
432
    protected boolean searchExternalFirst = false;
 
433
 
 
434
    /**
429
435
     * need conversion for properties files
430
436
     */
431
437
    protected boolean needConvert = false;
444
450
     * instability. As such, enabling this should be viewed as an option of last
445
451
     * resort in a development environment and is not recommended in a
446
452
     * production environment. If not specified, the default value of
447
 
     * <code>false</code> will be used. Note that instances of
448
 
     * java.util.TimerThread will always be terminate since a safe method exists
449
 
     * to do so.
 
453
     * <code>false</code> will be used.
450
454
     */
451
455
    private boolean clearReferencesStopThreads = false;
452
456
 
453
457
    /**
 
458
     * Should Tomcat attempt to terminate any {@link java.util.TimerThread}s
 
459
     * that have been started by the web application? If not specified, the
 
460
     * default value of <code>false</code> will be used.
 
461
     */
 
462
    private boolean clearReferencesStopTimerThreads = false;
 
463
 
 
464
    /**
 
465
     * Should Tomcat attempt to clear any ThreadLocal objects that are instances
 
466
     * of classes loaded by this class loader. Failure to remove any such
 
467
     * objects will result in a memory leak on web application stop, undeploy or
 
468
     * reload. It is disabled by default since the clearing of the ThreadLocal
 
469
     * objects is not performed in a thread-safe manner.
 
470
     */
 
471
    private boolean clearReferencesThreadLocals = false;
 
472
    
 
473
    /**
454
474
     * Should Tomcat call {@link org.apache.juli.logging.LogFactory#release()}
455
475
     * when the class loader is stopped? If not specified, the default value
456
476
     * of <code>true</code> is used. Changing the default setting is likely to
458
478
     */
459
479
    private boolean clearReferencesLogFactoryRelease = true;
460
480
 
 
481
    
 
482
    /**
 
483
     * Name of associated context used with logging and JMX to associate with
 
484
     * the right web application. Particularly useful for the clear references
 
485
     * messages. Defaults to unknown but if standard Tomcat components are used
 
486
     * it will be updated during initialisation from the resources.
 
487
     */
 
488
    private String contextName = "unknown";
 
489
 
 
490
 
461
491
    // ------------------------------------------------------------- Properties
462
492
 
463
493
 
478
508
 
479
509
        this.resources = resources;
480
510
 
 
511
        if (resources instanceof ProxyDirContext) {
 
512
            contextName = ((ProxyDirContext) resources).getContextName();
 
513
        }
 
514
    }
 
515
 
 
516
 
 
517
    /**
 
518
     * Return the context name for this class loader.
 
519
     */
 
520
    public String getContextName() {
 
521
 
 
522
        return (this.contextName);
 
523
 
481
524
    }
482
525
 
483
526
 
518
561
        this.antiJARLocking = antiJARLocking;
519
562
    }
520
563
 
521
 
    
 
564
    /**
 
565
     * @return Returns the searchExternalFirst.
 
566
     */
 
567
    public boolean getSearchExternalFirst() {
 
568
        return searchExternalFirst;
 
569
    }
 
570
 
 
571
    /**
 
572
     * @param searchExternalFirst Whether external repositories should be searched first
 
573
     */
 
574
    public void setSearchExternalFirst(boolean searchExternalFirst) {
 
575
        this.searchExternalFirst = searchExternalFirst;
 
576
    }
 
577
 
 
578
 
522
579
    /**
523
580
     * If there is a Java SecurityManager create a read FilePermission
524
581
     * or JndiPermission for the file directory path.
643
700
 
644
701
 
645
702
     /**
 
703
      * Return the clearReferencesStopTimerThreads flag for this Context.
 
704
      */
 
705
     public boolean getClearReferencesStopTimerThreads() {
 
706
         return (this.clearReferencesStopTimerThreads);
 
707
     }
 
708
 
 
709
 
 
710
     /**
 
711
      * Set the clearReferencesStopTimerThreads feature for this Context.
 
712
      *
 
713
      * @param clearReferencesStopTimerThreads The new flag value
 
714
      */
 
715
     public void setClearReferencesStopTimerThreads(
 
716
             boolean clearReferencesStopTimerThreads) {
 
717
         this.clearReferencesStopTimerThreads = clearReferencesStopTimerThreads;
 
718
     }
 
719
 
 
720
 
 
721
     /**
646
722
      * Return the clearReferencesLogFactoryRelease flag for this Context.
647
723
      */
648
724
     public boolean getClearReferencesLogFactoryRelease() {
662
738
     }
663
739
 
664
740
 
 
741
     /**
 
742
      * Return the clearReferencesThreadLocals flag for this Context.
 
743
      */
 
744
     public boolean getClearReferencesThreadLocals() {
 
745
         return (this.clearReferencesThreadLocals);
 
746
     }
 
747
 
 
748
 
 
749
     /**
 
750
      * Set the clearReferencesThreadLocals feature for this Context.
 
751
      *
 
752
      * @param clearReferencesThreadLocals The new flag value
 
753
      */
 
754
     public void setClearReferencesThreadLocals(
 
755
             boolean clearReferencesThreadLocals) {
 
756
         this.clearReferencesThreadLocals = clearReferencesThreadLocals;
 
757
     }
 
758
 
 
759
 
665
760
    // ------------------------------------------------------- Reloader Methods
666
761
 
667
762
 
932
1027
    public String toString() {
933
1028
 
934
1029
        StringBuffer sb = new StringBuffer("WebappClassLoader\r\n");
 
1030
        sb.append("  context: ");
 
1031
        sb.append(contextName);
 
1032
        sb.append("\r\n");
935
1033
        sb.append("  delegate: ");
936
1034
        sb.append(delegate);
937
1035
        sb.append("\r\n");
1006
1104
        try {
1007
1105
            if (log.isTraceEnabled())
1008
1106
                log.trace("      findClassInternal(" + name + ")");
1009
 
            try {
1010
 
                clazz = findClassInternal(name);
1011
 
            } catch(ClassNotFoundException cnfe) {
1012
 
                if (!hasExternalRepositories) {
1013
 
                    throw cnfe;
1014
 
                }
1015
 
            } catch(AccessControlException ace) {
1016
 
                log.warn("WebappClassLoader.findClassInternal(" + name
1017
 
                        + ") security exception: " + ace.getMessage(), ace);
1018
 
                throw new ClassNotFoundException(name, ace);
1019
 
            } catch (RuntimeException e) {
1020
 
                if (log.isTraceEnabled())
1021
 
                    log.trace("      -->RuntimeException Rethrown", e);
1022
 
                throw e;
1023
 
            }
1024
 
            if ((clazz == null) && hasExternalRepositories) {
 
1107
            if (hasExternalRepositories && searchExternalFirst) {
 
1108
                try {
 
1109
                    clazz = super.findClass(name);
 
1110
                } catch(ClassNotFoundException cnfe) {
 
1111
                    // Ignore - will search internal repositories next
 
1112
                } catch(AccessControlException ace) {
 
1113
                    log.warn("WebappClassLoader.findClassInternal(" + name
 
1114
                            + ") security exception: " + ace.getMessage(), ace);
 
1115
                    throw new ClassNotFoundException(name, ace);
 
1116
                } catch (RuntimeException e) {
 
1117
                    if (log.isTraceEnabled())
 
1118
                        log.trace("      -->RuntimeException Rethrown", e);
 
1119
                    throw e;
 
1120
                }
 
1121
            }
 
1122
            if ((clazz == null)) {
 
1123
                try {
 
1124
                    clazz = findClassInternal(name);
 
1125
                } catch(ClassNotFoundException cnfe) {
 
1126
                    if (!hasExternalRepositories || searchExternalFirst) {
 
1127
                        throw cnfe;
 
1128
                    }
 
1129
                } catch(AccessControlException ace) {
 
1130
                    log.warn("WebappClassLoader.findClassInternal(" + name
 
1131
                            + ") security exception: " + ace.getMessage(), ace);
 
1132
                    throw new ClassNotFoundException(name, ace);
 
1133
                } catch (RuntimeException e) {
 
1134
                    if (log.isTraceEnabled())
 
1135
                        log.trace("      -->RuntimeException Rethrown", e);
 
1136
                    throw e;
 
1137
                }
 
1138
            }
 
1139
            if ((clazz == null) && hasExternalRepositories && !searchExternalFirst) {
1025
1140
                try {
1026
1141
                    clazz = super.findClass(name);
1027
1142
                } catch(AccessControlException ace) {
1078
1193
 
1079
1194
        URL url = null;
1080
1195
 
1081
 
        ResourceEntry entry = (ResourceEntry) resourceEntries.get(name);
1082
 
        if (entry == null) {
1083
 
            if (securityManager != null) {
1084
 
                PrivilegedAction<ResourceEntry> dp =
1085
 
                    new PrivilegedFindResourceByName(name, name);
1086
 
                entry = AccessController.doPrivileged(dp);
1087
 
            } else {
1088
 
                entry = findResourceInternal(name, name);
1089
 
            }
1090
 
        }
1091
 
        if (entry != null) {
1092
 
            url = entry.source;
1093
 
        }
1094
 
 
1095
 
        if ((url == null) && hasExternalRepositories)
 
1196
        if (hasExternalRepositories && searchExternalFirst)
 
1197
            url = super.findResource(name);
 
1198
 
 
1199
        if (url == null) {
 
1200
            ResourceEntry entry = (ResourceEntry) resourceEntries.get(name);
 
1201
            if (entry == null) {
 
1202
                if (securityManager != null) {
 
1203
                    PrivilegedAction<ResourceEntry> dp =
 
1204
                        new PrivilegedFindResourceByName(name, name);
 
1205
                    entry = AccessController.doPrivileged(dp);
 
1206
                } else {
 
1207
                    entry = findResourceInternal(name, name);
 
1208
                }
 
1209
            }
 
1210
            if (entry != null) {
 
1211
                url = entry.source;
 
1212
            }
 
1213
        }
 
1214
 
 
1215
        if ((url == null) && hasExternalRepositories && !searchExternalFirst)
1096
1216
            url = super.findResource(name);
1097
1217
 
1098
1218
        if (log.isDebugEnabled()) {
1127
1247
 
1128
1248
        int i;
1129
1249
 
 
1250
        // Adding the results of a call to the superclass
 
1251
        if (hasExternalRepositories && searchExternalFirst) {
 
1252
 
 
1253
            Enumeration<URL> otherResourcePaths = super.findResources(name);
 
1254
 
 
1255
            while (otherResourcePaths.hasMoreElements()) {
 
1256
                result.addElement(otherResourcePaths.nextElement());
 
1257
            }
 
1258
 
 
1259
        }
1130
1260
        // Looking at the repositories
1131
1261
        for (i = 0; i < repositoriesLength; i++) {
1132
1262
            try {
1162
1292
        }
1163
1293
 
1164
1294
        // Adding the results of a call to the superclass
1165
 
        if (hasExternalRepositories) {
 
1295
        if (hasExternalRepositories && !searchExternalFirst) {
1166
1296
 
1167
1297
            Enumeration otherResourcePaths = super.findResources(name);
1168
1298
 
1655
1785
        // Clearing references should be done before setting started to
1656
1786
        // false, due to possible side effects
1657
1787
        clearReferences();
1658
 
 
 
1788
        
1659
1789
        started = false;
1660
1790
        
1661
1791
        int length = files.length;
1819
1949
            List<String> driverNames = (List<String>) obj.getClass().getMethod(
1820
1950
                    "clearJdbcDriverRegistrations").invoke(obj);
1821
1951
            for (String name : driverNames) {
1822
 
                log.error(sm.getString("webappClassLoader.clearJbdc", name));
 
1952
                log.error(sm.getString("webappClassLoader.clearJbdc",
 
1953
                        contextName, name));
1823
1954
            }
1824
1955
        } catch (Exception e) {
1825
1956
            // So many things to go wrong above...
1826
 
            log.warn(sm.getString("webappClassLoader.jdbcRemoveFailed"), e);
 
1957
            log.warn(sm.getString(
 
1958
                    "webappClassLoader.jdbcRemoveFailed", contextName), e);
1827
1959
        } finally {
1828
1960
            if (is != null) {
1829
1961
                try {
1830
1962
                    is.close();
1831
1963
                } catch (IOException ioe) {
1832
1964
                    log.warn(sm.getString(
1833
 
                            "webappClassLoader.jdbcRemoveStreamError"), ioe);
 
1965
                            "webappClassLoader.jdbcRemoveStreamError",
 
1966
                            contextName), ioe);
1834
1967
                }
1835
1968
            }
1836
1969
        }
1987
2120
                        continue;
1988
2121
                    }
1989
2122
                   
1990
 
                    // TimerThread is not normally visible
 
2123
                    // TimerThread can be stopped safely so treat separately
1991
2124
                    if (thread.getClass().getName().equals(
1992
 
                            "java.util.TimerThread")) {
 
2125
                            "java.util.TimerThread") &&
 
2126
                            clearReferencesStopTimerThreads) {
1993
2127
                        clearReferencesStopTimerThread(thread);
1994
2128
                        continue;
1995
2129
                    }
1996
2130
 
1997
 
                    log.error(sm.getString("webappClassLoader.warnThread",
1998
 
                            thread.getName()));
 
2131
                    if (isRequestThread(thread)) {
 
2132
                        log.error(sm.getString("webappClassLoader.warnRequestThread",
 
2133
                                contextName, thread.getName()));
 
2134
                    } else {
 
2135
                        log.error(sm.getString("webappClassLoader.warnThread",
 
2136
                                contextName, thread.getName()));
 
2137
                    }
1999
2138
                    
2000
2139
                    // Don't try an stop the threads unless explicitly
2001
2140
                    // configured to do so
2025
2164
                    } catch (SecurityException e) {
2026
2165
                        log.warn(sm.getString(
2027
2166
                                "webappClassLoader.stopThreadFail",
2028
 
                                thread.getName()), e);
 
2167
                                thread.getName(), contextName), e);
2029
2168
                    } catch (NoSuchFieldException e) {
2030
2169
                        log.warn(sm.getString(
2031
2170
                                "webappClassLoader.stopThreadFail",
2032
 
                                thread.getName()), e);
 
2171
                                thread.getName(), contextName), e);
2033
2172
                    } catch (IllegalArgumentException e) {
2034
2173
                        log.warn(sm.getString(
2035
2174
                                "webappClassLoader.stopThreadFail",
2036
 
                                thread.getName()), e);
 
2175
                                thread.getName(), contextName), e);
2037
2176
                    } catch (IllegalAccessException e) {
2038
2177
                        log.warn(sm.getString(
2039
2178
                                "webappClassLoader.stopThreadFail",
2040
 
                                thread.getName()), e);
 
2179
                                thread.getName(), contextName), e);
2041
2180
                    }
2042
2181
 
2043
2182
                    // This method is deprecated and for good reason. This is
2051
2190
    }
2052
2191
 
2053
2192
    
 
2193
    /*
 
2194
     * Look at a threads stack trace to see if it is a request thread or not. It
 
2195
     * isn't perfect, but it should be good-enough for most cases.
 
2196
     */
 
2197
    private boolean isRequestThread(Thread thread) {
 
2198
        
 
2199
        StackTraceElement[] elements = thread.getStackTrace();
 
2200
        
 
2201
        if (elements == null || elements.length == 0) {
 
2202
            // Must have stopped already. Too late to ignore it. Assume not a
 
2203
            // request processing thread.
 
2204
            return false;
 
2205
        }
 
2206
        
 
2207
        // Step through the methods in reverse order looking for calls to any
 
2208
        // CoyoteAdapter method. All request threads will have this unless
 
2209
        // Tomcat has been heavily modified - in which case there isn't much we
 
2210
        // can do.
 
2211
        for (int i = 0; i < elements.length; i++) {
 
2212
            StackTraceElement element = elements[elements.length - (i+1)];
 
2213
            if ("org.apache.catalina.connector.CoyoteAdapter".equals(
 
2214
                    element.getClassName())) {
 
2215
                return true;
 
2216
            }
 
2217
        }
 
2218
        return false;
 
2219
    }
 
2220
    
 
2221
    
2054
2222
    private void clearReferencesStopTimerThread(Thread thread) {
2055
2223
        
2056
2224
        // Need to get references to:
2077
2245
            }
2078
2246
            
2079
2247
            log.error(sm.getString("webappClassLoader.warnTimerThread",
2080
 
                    thread.getName()));
 
2248
                    contextName, thread.getName()));
2081
2249
 
2082
2250
        } catch (NoSuchFieldException e) {
2083
2251
            log.warn(sm.getString(
2084
2252
                    "webappClassLoader.stopTimerThreadFail",
2085
 
                    thread.getName()), e);
 
2253
                    thread.getName(), contextName), e);
2086
2254
        } catch (IllegalAccessException e) {
2087
2255
            log.warn(sm.getString(
2088
2256
                    "webappClassLoader.stopTimerThreadFail",
2089
 
                    thread.getName()), e);
 
2257
                    thread.getName(), contextName), e);
2090
2258
        } catch (NoSuchMethodException e) {
2091
2259
            log.warn(sm.getString(
2092
2260
                    "webappClassLoader.stopTimerThreadFail",
2093
 
                    thread.getName()), e);
 
2261
                    thread.getName(), contextName), e);
2094
2262
        } catch (InvocationTargetException e) {
2095
2263
            log.warn(sm.getString(
2096
2264
                    "webappClassLoader.stopTimerThreadFail",
2097
 
                    thread.getName()), e);
 
2265
                    thread.getName(), contextName), e);
2098
2266
        }
2099
2267
    }
2100
2268
 
2130
2298
                }
2131
2299
            }
2132
2300
        } catch (SecurityException e) {
2133
 
            log.warn(sm.getString("webappClassLoader.clearThreadLocalFail"), e);
 
2301
            log.warn(sm.getString("webappClassLoader.clearThreadLocalFail",
 
2302
                    contextName), e);
2134
2303
        } catch (NoSuchFieldException e) {
2135
 
            log.warn(sm.getString("webappClassLoader.clearThreadLocalFail"), e);
 
2304
            log.warn(sm.getString("webappClassLoader.clearThreadLocalFail",
 
2305
                    contextName), e);
2136
2306
        } catch (ClassNotFoundException e) {
2137
 
            log.warn(sm.getString("webappClassLoader.clearThreadLocalFail"), e);
 
2307
            log.warn(sm.getString("webappClassLoader.clearThreadLocalFail",
 
2308
                    contextName), e);
2138
2309
        } catch (IllegalArgumentException e) {
2139
 
            log.warn(sm.getString("webappClassLoader.clearThreadLocalFail"), e);
 
2310
            log.warn(sm.getString("webappClassLoader.clearThreadLocalFail",
 
2311
                    contextName), e);
2140
2312
        } catch (IllegalAccessException e) {
2141
 
            log.warn(sm.getString("webappClassLoader.clearThreadLocalFail"), e);
 
2313
            log.warn(sm.getString("webappClassLoader.clearThreadLocalFail",
 
2314
                    contextName), e);
2142
2315
        } catch (NoSuchMethodException e) {
2143
 
            log.warn(sm.getString("webappClassLoader.clearThreadLocalFail"), e);
 
2316
            log.warn(sm.getString("webappClassLoader.clearThreadLocalFail",
 
2317
                    contextName), e);
2144
2318
        } catch (InvocationTargetException e) {
2145
 
            log.warn(sm.getString("webappClassLoader.clearThreadLocalFail"), e);
 
2319
            log.warn(sm.getString("webappClassLoader.clearThreadLocalFail",
 
2320
                    contextName), e);
2146
2321
        }       
2147
2322
    }
2148
2323
 
2182
2357
                            remove = true;
2183
2358
                        }
2184
2359
                        if (remove) {
2185
 
                            Object[] args = new Object[4];
 
2360
                            Object[] args = new Object[5];
 
2361
                            args[0] = contextName;
2186
2362
                            if (key != null) {
2187
 
                                args[0] = key.getClass().getCanonicalName();
2188
 
                                args[1] = key.toString();
 
2363
                                args[1] = key.getClass().getCanonicalName();
 
2364
                                args[2] = key.toString();
2189
2365
                            }
2190
2366
                            if (value != null) {
2191
 
                                args[2] = value.getClass().getCanonicalName();
2192
 
                                args[3] = value.toString();
 
2367
                                args[3] = value.getClass().getCanonicalName();
 
2368
                                args[4] = value.toString();
2193
2369
                            }
2194
2370
                            if (value == null) {
2195
2371
                                if (log.isDebugEnabled()) {
2196
2372
                                    log.debug(sm.getString(
2197
2373
                                            "webappClassLoader.clearThreadLocalDebug",
2198
2374
                                            args));
 
2375
                                    if (clearReferencesThreadLocals) {
 
2376
                                        log.debug(sm.getString(
 
2377
                                                "webappClassLoader.clearThreadLocalDebugClear"));
 
2378
                                    }
2199
2379
                                }
2200
2380
                            } else {
2201
2381
                                log.error(sm.getString(
2202
2382
                                        "webappClassLoader.clearThreadLocal",
2203
2383
                                        args));
 
2384
                                if (clearReferencesThreadLocals) {
 
2385
                                    log.info(sm.getString(
 
2386
                                            "webappClassLoader.clearThreadLocalClear"));
 
2387
                                }
2204
2388
                            }
2205
 
                            if (key == null) {
2206
 
                              staleEntriesCount++;
2207
 
                            } else {
2208
 
                              mapRemove.invoke(map, key);
 
2389
                            if (clearReferencesThreadLocals) {
 
2390
                                if (key == null) {
 
2391
                                  staleEntriesCount++;
 
2392
                                } else {
 
2393
                                  mapRemove.invoke(map, key);
 
2394
                                }
2209
2395
                            }
2210
2396
                        }
2211
2397
                    }
2301
2487
                }
2302
2488
            }
2303
2489
        } catch (ClassNotFoundException e) {
2304
 
            log.info(sm.getString("webappClassLoader.clearRmiInfo"), e);
 
2490
            log.info(sm.getString("webappClassLoader.clearRmiInfo",
 
2491
                    contextName), e);
2305
2492
        } catch (SecurityException e) {
2306
 
            log.warn(sm.getString("webappClassLoader.clearRmiFail"), e);
 
2493
            log.warn(sm.getString("webappClassLoader.clearRmiFail",
 
2494
                    contextName), e);
2307
2495
        } catch (NoSuchFieldException e) {
2308
 
            log.warn(sm.getString("webappClassLoader.clearRmiFail"), e);
 
2496
            log.warn(sm.getString("webappClassLoader.clearRmiFail",
 
2497
                    contextName), e);
2309
2498
        } catch (IllegalArgumentException e) {
2310
 
            log.warn(sm.getString("webappClassLoader.clearRmiFail"), e);
 
2499
            log.warn(sm.getString("webappClassLoader.clearRmiFail",
 
2500
                    contextName), e);
2311
2501
        } catch (IllegalAccessException e) {
2312
 
            log.warn(sm.getString("webappClassLoader.clearRmiFail"), e);
 
2502
            log.warn(sm.getString("webappClassLoader.clearRmiFail",
 
2503
                    contextName), e);
2313
2504
        }
2314
2505
    }
2315
2506
    
2373
2564
            if (countRemoved > 0 && log.isDebugEnabled()) {
2374
2565
                log.debug(sm.getString(
2375
2566
                        "webappClassLoader.clearReferencesResourceBundlesCount",
2376
 
                        Integer.valueOf(countRemoved)));
 
2567
                        Integer.valueOf(countRemoved), contextName));
2377
2568
            }
2378
2569
        } catch (SecurityException e) {
2379
2570
            log.error(sm.getString(
2380
 
                    "webappClassLoader.clearReferencesResourceBundlesFail"), e);
 
2571
                    "webappClassLoader.clearReferencesResourceBundlesFail",
 
2572
                    contextName), e);
2381
2573
        } catch (NoSuchFieldException e) {
2382
2574
            if (System.getProperty("java.vendor").startsWith("Sun")) {
2383
2575
                log.error(sm.getString(
2384
 
                "webappClassLoader.clearReferencesResourceBundlesFail"), e);
 
2576
                "webappClassLoader.clearReferencesResourceBundlesFail",
 
2577
                contextName), e);
2385
2578
            } else {
2386
2579
                log.debug(sm.getString(
2387
 
                "webappClassLoader.clearReferencesResourceBundlesFail"), e);
 
2580
                "webappClassLoader.clearReferencesResourceBundlesFail",
 
2581
                contextName), e);
2388
2582
            }
2389
2583
        } catch (IllegalArgumentException e) {
2390
2584
            log.error(sm.getString(
2391
 
                    "webappClassLoader.clearReferencesResourceBundlesFail"), e);
 
2585
                    "webappClassLoader.clearReferencesResourceBundlesFail",
 
2586
                    contextName), e);
2392
2587
        } catch (IllegalAccessException e) {
2393
2588
            log.error(sm.getString(
2394
 
                    "webappClassLoader.clearReferencesResourceBundlesFail"), e);
 
2589
                    "webappClassLoader.clearReferencesResourceBundlesFail",
 
2590
                    contextName), e);
2395
2591
        }
2396
2592
    }
2397
2593
 
3070
3266
 
3071
3267
 
3072
3268
}
3073