diff --git a/core/src/main/java/com/opensymphony/xwork2/ognl/OgnlDefaultCache.java b/core/src/main/java/com/opensymphony/xwork2/ognl/OgnlDefaultCache.java index a32736da6..43b24bb18 100644 --- a/core/src/main/java/com/opensymphony/xwork2/ognl/OgnlDefaultCache.java +++ b/core/src/main/java/com/opensymphony/xwork2/ognl/OgnlDefaultCache.java @@ -30,10 +30,10 @@ import java.util.concurrent.atomic.AtomicInteger; public class OgnlDefaultCache implements OgnlCache { private final ConcurrentHashMap ognlCache; - private final AtomicInteger cacheEvictionLimit = new AtomicInteger(25000); + private final AtomicInteger cacheEvictionLimit = new AtomicInteger(); public OgnlDefaultCache(int evictionLimit, int initialCapacity, float loadFactor) { - this.cacheEvictionLimit.set(evictionLimit); + cacheEvictionLimit.set(evictionLimit); ognlCache = new ConcurrentHashMap<>(initialCapacity, loadFactor); } diff --git a/core/src/main/java/com/opensymphony/xwork2/ognl/OgnlLRUCache.java b/core/src/main/java/com/opensymphony/xwork2/ognl/OgnlLRUCache.java index 93ab56d36..81286af34 100644 --- a/core/src/main/java/com/opensymphony/xwork2/ognl/OgnlLRUCache.java +++ b/core/src/main/java/com/opensymphony/xwork2/ognl/OgnlLRUCache.java @@ -36,15 +36,15 @@ import java.util.concurrent.atomic.AtomicInteger; public class OgnlLRUCache implements OgnlCache { private final Map ognlLRUCache; - private final AtomicInteger cacheEvictionLimit = new AtomicInteger(2500); + private final AtomicInteger cacheEvictionLimit = new AtomicInteger(); public OgnlLRUCache(int evictionLimit, int initialCapacity, float loadFactor) { - this.cacheEvictionLimit.set(evictionLimit); + cacheEvictionLimit.set(evictionLimit); // Access-order mode selected (order mode true in LinkedHashMap constructor). ognlLRUCache = Collections.synchronizedMap (new LinkedHashMap(initialCapacity, loadFactor, true) { @Override protected boolean removeEldestEntry(Map.Entry eldest) { - return (this.size() > cacheEvictionLimit.get()); + return size() > cacheEvictionLimit.get(); } }); } diff --git a/core/src/main/java/com/opensymphony/xwork2/ognl/OgnlUtil.java b/core/src/main/java/com/opensymphony/xwork2/ognl/OgnlUtil.java index 4bddad63a..16c80d99d 100644 --- a/core/src/main/java/com/opensymphony/xwork2/ognl/OgnlUtil.java +++ b/core/src/main/java/com/opensymphony/xwork2/ognl/OgnlUtil.java @@ -673,9 +673,15 @@ public class OgnlUtil { * note if exclusions AND inclusions are supplied and not null nothing will get copied. * @param editable the class (or interface) to restrict property setting to */ - public void copy(final Object from, final Object to, final Map context, Collection exclusions, Collection inclusions, Class editable) { + public void copy(final Object from, + final Object to, + final Map context, + Collection exclusions, + Collection inclusions, + Class editable) { if (from == null || to == null) { - LOG.warn("Attempting to copy from or to a null source. This is illegal and is bein skipped. This may be due to an error in an OGNL expression, action chaining, or some other event."); + LOG.warn( + "Skipping attempt to copy from, or to, a null source.", new RuntimeException()); return; } @@ -689,8 +695,7 @@ public class OgnlUtil { fromPds = getPropertyDescriptors(from); if (editable != null) { toPds = getPropertyDescriptors(editable); - } - else { + } else { toPds = getPropertyDescriptors(to); } } catch (IntrospectionException e) { @@ -705,29 +710,31 @@ public class OgnlUtil { } for (PropertyDescriptor fromPd : fromPds) { - if (fromPd.getReadMethod() != null) { - boolean copy = true; - if (exclusions != null && exclusions.contains(fromPd.getName())) { - copy = false; - } else if (inclusions != null && !inclusions.contains(fromPd.getName())) { - copy = false; - } - - if (copy) { - PropertyDescriptor toPd = toPdHash.get(fromPd.getName()); - if ((toPd != null) && (toPd.getWriteMethod() != null)) { - try { - Object value = ognlGet(fromPd.getName(), contextFrom, from, null, context, this::checkEnableEvalExpression); - ognlSet(fromPd.getName(), contextTo, to, value, context); - } catch (OgnlException e) { - LOG.debug("Got OGNL exception", e); - } - } - - } - + if (fromPd.getReadMethod() == null) { + continue; } + if (exclusions != null && exclusions.contains(fromPd.getName()) || + inclusions != null && !inclusions.contains(fromPd.getName())) { + continue; + } + + PropertyDescriptor toPd = toPdHash.get(fromPd.getName()); + if (toPd == null || toPd.getWriteMethod() == null) { + continue; + } + + try { + Object value = ognlGet(fromPd.getName(), + contextFrom, + from, + null, + context, + this::checkEnableEvalExpression); + ognlSet(fromPd.getName(), contextTo, to, value, context); + } catch (OgnlException e) { + LOG.debug("Got OGNL exception", e); + } } } @@ -746,7 +753,7 @@ public class OgnlUtil { } /** - * Get's the java beans property descriptors for the given source. + * Gets the java beans property descriptors for the given source. * * @param source the source object. * @return property descriptors. diff --git a/core/src/main/resources/org/apache/struts2/default.properties b/core/src/main/resources/org/apache/struts2/default.properties index 56bc714de..60257465b 100644 --- a/core/src/main/resources/org/apache/struts2/default.properties +++ b/core/src/main/resources/org/apache/struts2/default.properties @@ -243,12 +243,12 @@ struts.ognl.enableExpressionCache=true ### For expressionCacheLRUMode true, the limit will ensure the cache does not exceed ### that size, dropping the oldest (least-recently-used) expressions to add new ones. ### NOTE: If not set, the default is 25000, which may be excessive. -# struts.ognl.expressionCacheMaxSize=1000 +struts.ognl.expressionCacheMaxSize=10000 ### Indicates if the OGNL expressionCache should use LRU mode. ### NOTE: When true, make sure to set the expressionCacheMaxSize to a reasonable value ### for your application. Otherwise the default limit will never (practically) be reached. -# struts.ognl.expressionCacheLRUMode=false +struts.ognl.expressionCacheLRUMode=true ### Specify a limit to the number of entries in the OGNL beanInfoCache. ### For the standard beanInfoCache mode, when the limit is exceeded the entire cache's @@ -256,12 +256,12 @@ struts.ognl.enableExpressionCache=true ### For beanInfoCacheLRUMode true, the limit will ensure the cache does not exceed ### that size, dropping the oldest (least-recently-used) expressions to add new ones. ### NOTE: If not set, the default is 25000, which may be excessive. -# struts.ognl.beanInfoCacheMaxSize=1000 +struts.ognl.beanInfoCacheMaxSize=5000 ### Indicates if the OGNL beanInfoCache should use LRU mode. ### NOTE: When true, make sure to set the beanInfoCacheMaxSize to a reasonable value ### for your application. Otherwise the default limit will never (practically) be reached. -# struts.ognl.beanInfoCacheLRUMode=false +struts.ognl.beanInfoCacheLRUMode=true ### Indicates if Dispatcher should handle unexpected exceptions by calling sendError() ### or simply rethrow it as a ServletException to allow future processing by other frameworks like Spring Security