[ 
https://issues.apache.org/jira/browse/SLING-9312?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Hans-Peter Stoerr updated SLING-9312:
-------------------------------------
    Description: 
The method entrySet in org.apache.sling.api.scripting.LazyBindings currently 
has a bug that forces the hashCode of the entry values in Bindings are 
calculated in each HTL request, when it should only be the hashCode of the keys 
- if at all. This can be a performance problem if the value is e.g. a large 
map, in our (complicated) case this even got us a StackOverflowError.

The problematic code is:
{code:java}
    public Set<Entry<String, Object>> entrySet() {
        HashSet<Entry<String, Object>> entrySet = new 
HashSet<>(super.entrySet());
        for (Map.Entry supplierEntry : suppliers.entrySet()) {
            entrySet.add(supplierEntry);
        }
        return Collections.unmodifiableSet(entrySet);
    } {code}
Since the entries are put together in a HashSet, each add will calculate the 
hashCode of the entry - which sums the hashCode of the key *and the value* of 
each binding entry. I suggest to replace this with a HashMap and return it's 
entrySet. Another problem is that this could return several entries for the 
same key, which is probably not intended..

In case you are wondering, this is called in every HTL request like this:
{code:java}
         at java.base/java.util.HashSet.add(HashSet.java:220)
          at 
java.base/java.util.AbstractCollection.addAll(AbstractCollection.java:336)
          at java.base/java.util.HashSet.<init>(HashSet.java:120)
          at 
org.apache.sling.api.scripting.LazyBindings.entrySet(LazyBindings.java:117) 
[org.apache.sling.api:2.21.0]
          at 
org.apache.sling.api.scripting.LazyBindings.putAll(LazyBindings.java:87) 
[org.apache.sling.api:2.21.0]
          at 
org.apache.sling.scripting.sightly.impl.engine.SightlyCompiledScript.eval(SightlyCompiledScript.java:50)
 [org.apache.sling.scripting.sightly:1.2.0.0]
          at 
org.apache.sling.scripting.core.impl.DefaultSlingScript.call(DefaultSlingScript.java:386)
 [org.apache.sling.scripting.core:2.1.0]
          at 
org.apache.sling.scripting.core.impl.DefaultSlingScript.eval(DefaultSlingScript.java:184)
 [org.apache.sling.scripting.core:2.1.0]
          at 
org.apache.sling.scripting.core.impl.DefaultSlingScript.service(DefaultSlingScript.java:491)
 [org.apache.sling.scripting.core:2.1.0]
          at 
org.apache.sling.engine.impl.request.RequestData.service(RequestData.java:552) 
[org.apache.sling.engine:2.6.20]
          at 
org.apache.sling.engine.impl.filter.SlingComponentFilterChain.render(SlingComponentFilterChain.java:44)
 [org.apache.sling.engine:2.6.20] {code}
 

 

  was:
The method entrySet in org.apache.sling.api.scripting.LazyBindings currently 
has a bug that forces the hashCode of the entry values in Bindings are 
calculated in each HTL request, when it should only be the hashCode of the keys 
- if at all. This can be a performance problem if the value is e.g. a large 
map, in our (complicated) case this even got us a StackOverflowError.

The problematic code is:
{code:java}
    public Set<Entry<String, Object>> entrySet() {
        HashSet<Entry<String, Object>> entrySet = new 
HashSet<>(super.entrySet());
        for (Map.Entry supplierEntry : suppliers.entrySet()) {
            entrySet.add(supplierEntry);
        }
        return Collections.unmodifiableSet(entrySet);
    } {code}
Since the entries are put together in a HashSet, each add will calculate the 
hashCode of the entry - which sums the hashCode of the key *and the value* of 
each binding entry. I suggest to replace this with a HashMap and return it's 
entrySet.

In case you are wondering, this is called in every HTL request like this:
{code:java}
         at java.base/java.util.HashSet.add(HashSet.java:220)
          at 
java.base/java.util.AbstractCollection.addAll(AbstractCollection.java:336)
          at java.base/java.util.HashSet.<init>(HashSet.java:120)
          at 
org.apache.sling.api.scripting.LazyBindings.entrySet(LazyBindings.java:117) 
[org.apache.sling.api:2.21.0]
          at 
org.apache.sling.api.scripting.LazyBindings.putAll(LazyBindings.java:87) 
[org.apache.sling.api:2.21.0]
          at 
org.apache.sling.scripting.sightly.impl.engine.SightlyCompiledScript.eval(SightlyCompiledScript.java:50)
 [org.apache.sling.scripting.sightly:1.2.0.0]
          at 
org.apache.sling.scripting.core.impl.DefaultSlingScript.call(DefaultSlingScript.java:386)
 [org.apache.sling.scripting.core:2.1.0]
          at 
org.apache.sling.scripting.core.impl.DefaultSlingScript.eval(DefaultSlingScript.java:184)
 [org.apache.sling.scripting.core:2.1.0]
          at 
org.apache.sling.scripting.core.impl.DefaultSlingScript.service(DefaultSlingScript.java:491)
 [org.apache.sling.scripting.core:2.1.0]
          at 
org.apache.sling.engine.impl.request.RequestData.service(RequestData.java:552) 
[org.apache.sling.engine:2.6.20]
          at 
org.apache.sling.engine.impl.filter.SlingComponentFilterChain.render(SlingComponentFilterChain.java:44)
 [org.apache.sling.engine:2.6.20] {code}
 

 


> Bug in LazyBindings.entrySet: hashCode of binding values is calculated
> ----------------------------------------------------------------------
>
>                 Key: SLING-9312
>                 URL: https://issues.apache.org/jira/browse/SLING-9312
>             Project: Sling
>          Issue Type: Bug
>          Components: API
>    Affects Versions: API 2.21.0, API 2.22.2
>            Reporter: Hans-Peter Stoerr
>            Priority: Minor
>
> The method entrySet in org.apache.sling.api.scripting.LazyBindings currently 
> has a bug that forces the hashCode of the entry values in Bindings are 
> calculated in each HTL request, when it should only be the hashCode of the 
> keys - if at all. This can be a performance problem if the value is e.g. a 
> large map, in our (complicated) case this even got us a StackOverflowError.
> The problematic code is:
> {code:java}
>     public Set<Entry<String, Object>> entrySet() {
>         HashSet<Entry<String, Object>> entrySet = new 
> HashSet<>(super.entrySet());
>         for (Map.Entry supplierEntry : suppliers.entrySet()) {
>             entrySet.add(supplierEntry);
>         }
>         return Collections.unmodifiableSet(entrySet);
>     } {code}
> Since the entries are put together in a HashSet, each add will calculate the 
> hashCode of the entry - which sums the hashCode of the key *and the value* of 
> each binding entry. I suggest to replace this with a HashMap and return it's 
> entrySet. Another problem is that this could return several entries for the 
> same key, which is probably not intended..
> In case you are wondering, this is called in every HTL request like this:
> {code:java}
>          at java.base/java.util.HashSet.add(HashSet.java:220)
>           at 
> java.base/java.util.AbstractCollection.addAll(AbstractCollection.java:336)
>           at java.base/java.util.HashSet.<init>(HashSet.java:120)
>           at 
> org.apache.sling.api.scripting.LazyBindings.entrySet(LazyBindings.java:117) 
> [org.apache.sling.api:2.21.0]
>           at 
> org.apache.sling.api.scripting.LazyBindings.putAll(LazyBindings.java:87) 
> [org.apache.sling.api:2.21.0]
>           at 
> org.apache.sling.scripting.sightly.impl.engine.SightlyCompiledScript.eval(SightlyCompiledScript.java:50)
>  [org.apache.sling.scripting.sightly:1.2.0.0]
>           at 
> org.apache.sling.scripting.core.impl.DefaultSlingScript.call(DefaultSlingScript.java:386)
>  [org.apache.sling.scripting.core:2.1.0]
>           at 
> org.apache.sling.scripting.core.impl.DefaultSlingScript.eval(DefaultSlingScript.java:184)
>  [org.apache.sling.scripting.core:2.1.0]
>           at 
> org.apache.sling.scripting.core.impl.DefaultSlingScript.service(DefaultSlingScript.java:491)
>  [org.apache.sling.scripting.core:2.1.0]
>           at 
> org.apache.sling.engine.impl.request.RequestData.service(RequestData.java:552)
>  [org.apache.sling.engine:2.6.20]
>           at 
> org.apache.sling.engine.impl.filter.SlingComponentFilterChain.render(SlingComponentFilterChain.java:44)
>  [org.apache.sling.engine:2.6.20] {code}
>  
>  



--
This message was sent by Atlassian Jira
(v8.3.4#803005)

Reply via email to