|
22 | 22 | import java.io.Reader;
|
23 | 23 | import java.io.StringReader;
|
24 | 24 | import java.io.Writer;
|
| 25 | +import java.lang.reflect.Field; |
25 | 26 | import java.util.Deque;
|
26 | 27 | import java.util.LinkedList;
|
27 | 28 | import java.util.List;
|
|
60 | 61 | @InstantiationStrategy(ComponentInstantiationStrategy.PER_LOOKUP)
|
61 | 62 | public class InternalVelocityEngine implements VelocityEngine
|
62 | 63 | {
|
| 64 | + /** |
| 65 | + * The field that stores the introspection cache. This field is accessed once here as it causes several exceptions |
| 66 | + * to be thrown internally until the field is found, which is expensive. |
| 67 | + */ |
| 68 | + private static final Field INTROSPECTION_CACHE_FIELD = |
| 69 | + FieldUtils.getField(VelocityContext.class, "introspectionCache", true); |
| 70 | + |
63 | 71 | private static final String ECONTEXT_TEMPLATES = "velocity.templates";
|
64 | 72 |
|
65 | 73 | private class TemplateEntry
|
@@ -245,8 +253,14 @@ private void cleanIntrospectionCache(Context context)
|
245 | 253 | {
|
246 | 254 | if (context != null) {
|
247 | 255 | try {
|
248 |
| - Map introspectionCache = (Map) FieldUtils.readField(context, "introspectionCache", true); |
249 |
| - introspectionCache.clear(); |
| 256 | + if (INTROSPECTION_CACHE_FIELD != null) { |
| 257 | + Map<?, ?> introspectionCache = (Map<?, ?>) INTROSPECTION_CACHE_FIELD.get(context); |
| 258 | + introspectionCache.clear(); |
| 259 | + } else { |
| 260 | + this.logger.warn( |
| 261 | + "Failed to clean the Velocity context introspection cache because the introspection cache " |
| 262 | + + "field could not be found."); |
| 263 | + } |
250 | 264 | } catch (IllegalAccessException e) {
|
251 | 265 | this.logger.warn("Failed to clean the Velocity context introspection cache. Root error: [{}]",
|
252 | 266 | ExceptionUtils.getRootCauseMessage(e));
|
|
0 commit comments