[
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)