[
https://issues.apache.org/jira/browse/WW-5119?focusedWorklogId=569263&page=com.atlassian.jira.plugin.system.issuetabpanels:worklog-tabpanel#worklog-569263
]
ASF GitHub Bot logged work on WW-5119:
--------------------------------------
Author: ASF GitHub Bot
Created on: 20/Mar/21 16:41
Start Date: 20/Mar/21 16:41
Worklog Time Spent: 10m
Work Description: JCgH4164838Gh792C124B5 commented on a change in pull
request #477:
URL: https://github.com/apache/struts/pull/477#discussion_r598130091
##########
File path:
core/src/main/java/com/opensymphony/xwork2/util/AbstractLocalizedTextProvider.java
##########
@@ -413,11 +411,11 @@ public ResourceBundle findResourceBundle(String
aBundleName, Locale locale) {
}
} catch (MissingResourceException e) {
LOG.debug("Missing resource bundle [{}]!", aBundleName, e);
- missingBundles.add(key);
+ missingBundles.put(key, Boolean.TRUE);
}
} else {
LOG.debug("Missing resource bundle [{}]!", aBundleName);
- missingBundles.add(key);
+ missingBundles.put(key, Boolean.TRUE);
Review comment:
And the same `missingBundles.putIfAbsent(key, Boolean.TRUE);`
consideration here.
##########
File path:
core/src/main/java/com/opensymphony/xwork2/util/AbstractLocalizedTextProvider.java
##########
@@ -413,11 +411,11 @@ public ResourceBundle findResourceBundle(String
aBundleName, Locale locale) {
}
} catch (MissingResourceException e) {
LOG.debug("Missing resource bundle [{}]!", aBundleName, e);
- missingBundles.add(key);
+ missingBundles.put(key, Boolean.TRUE);
Review comment:
Consider changing `put()` to `putIfAbsent()` as the closest behaviour
match to the previous `add()` method usage:
`missingBundles.putIfAbsent(key, Boolean.TRUE);`
##########
File path:
core/src/main/java/com/opensymphony/xwork2/util/AbstractLocalizedTextProvider.java
##########
@@ -61,7 +59,7 @@
private final ConcurrentMap<MessageFormatKey, MessageFormat>
messageFormats = new ConcurrentHashMap<>();
private final ConcurrentMap<Integer, List<String>> classLoaderMap = new
ConcurrentHashMap<>();
- private final Set<String> missingBundles = Collections.synchronizedSet(new
HashSet<String>());
+ private final ConcurrentMap<String,Boolean> missingBundles = new
ConcurrentHashMap<>();
Review comment:
Minor formatting suggestion: Add a space before `Boolean` for:
`ConcurrentMap<String, Boolean>`.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
[email protected]
Issue Time Tracking
-------------------
Worklog Id: (was: 569263)
Time Spent: 1.5h (was: 1h 20m)
> Blocking Threads in retrieving text from resource bundle
> --------------------------------------------------------
>
> Key: WW-5119
> URL: https://issues.apache.org/jira/browse/WW-5119
> Project: Struts 2
> Issue Type: Bug
> Components: Core Tags
> Affects Versions: 2.5.26
> Reporter: Tobias Barth
> Priority: Major
> Fix For: 2.5.27, 2.6
>
> Attachments: WW-5119.jmx, ww-5119-threaddump.txt, ww5119.zip
>
> Time Spent: 1.5h
> Remaining Estimate: 0h
>
> Hi,
> I am running load tests with an application based on Apache Struts 2.5.26 and
> Spring Framework. In the thread dumps I took during the load tests, there are
> many many threads with stacktraces that tell me there is a synchronization in
> com.opensymphony.xwork2.TextProviderSupport.getText which blocks all other
> threads.
>
> The jsp tag leading to that is for example:
>
> <s:set var="variablename" value="getText('topic.find.value.field.name')"/>
>
> The stack trace is then:
> {code}
> "http-nio-8080-exec-69" #144 daemon prio=5 os_prio=0 tid=0x0000000027b84000
> nid=0x1ca4 waiting for monitor entry
> [0x000000003939b000]"http-nio-8080-exec-69" #144 daemon prio=5 os_prio=0
> tid=0x0000000027b84000 nid=0x1ca4 waiting for monitor entry
> [0x000000002937b000] java.lang.Thread.State: BLOCKED (on object monitor) at
> java.util.Collections$SynchronizedCollection.contains(Collections.java:2021)
> - locked <0x00000009d3b1b8f0> (a java.util.Collections$SynchronizedSet) at
> com.opensymphony.xwork2.util.AbstractLocalizedTextProvider.findResourceBundle(AbstractLocalizedTextProvider.java:393)
> at
> com.opensymphony.xwork2.util.StrutsLocalizedTextProvider.findResourceBundle(StrutsLocalizedTextProvider.java:39)
> at
> com.opensymphony.xwork2.util.AbstractLocalizedTextProvider.getMessage(AbstractLocalizedTextProvider.java:500)
> at
> com.opensymphony.xwork2.util.AbstractLocalizedTextProvider.findMessage(AbstractLocalizedTextProvider.java:537)
> at
> com.opensymphony.xwork2.util.AbstractLocalizedTextProvider.findMessage(AbstractLocalizedTextProvider.java:583)
> at
> com.opensymphony.xwork2.util.StrutsLocalizedTextProvider.findText(StrutsLocalizedTextProvider.java:244)
> at
> com.opensymphony.xwork2.util.StrutsLocalizedTextProvider.findText(StrutsLocalizedTextProvider.java:166)
> at
> com.opensymphony.xwork2.TextProviderSupport.getText(TextProviderSupport.java:212)
> at
> com.opensymphony.xwork2.TextProviderSupport.getText(TextProviderSupport.java:127)
> at com.opensymphony.xwork2.ActionSupport.getText(ActionSupport.java:91) at
> sun.reflect.GeneratedMethodAccessor163.invoke(Unknown Source) at
> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
> at java.lang.reflect.Method.invoke(Method.java:498) at
> ognl.OgnlRuntime.invokeMethodInsideSandbox(OgnlRuntime.java:1266) at
> ognl.OgnlRuntime.invokeMethod(OgnlRuntime.java:1251) at
> ognl.OgnlRuntime.callAppropriateMethod(OgnlRuntime.java:1969) at
> ognl.ObjectMethodAccessor.callMethod(ObjectMethodAccessor.java:68) at
> com.opensymphony.xwork2.ognl.accessor.XWorkMethodAccessor.callMethodWithDebugInfo(XWorkMethodAccessor.java:98)
> at
> com.opensymphony.xwork2.ognl.accessor.XWorkMethodAccessor.callMethod(XWorkMethodAccessor.java:83)
> at ognl.OgnlRuntime.callMethod(OgnlRuntime.java:2045) at
> com.opensymphony.xwork2.ognl.accessor.CompoundRootAccessor.callMethod(CompoundRootAccessor.java:237)
> at ognl.OgnlRuntime.callMethod(OgnlRuntime.java:2045) at
> ognl.ASTMethod.getValueBody(ASTMethod.java:97) at
> ognl.SimpleNode.evaluateGetValueBody(SimpleNode.java:212) at
> ognl.SimpleNode.getValue(SimpleNode.java:258) at
> ognl.Ognl.getValue(Ognl.java:537) at ognl.Ognl.getValue(Ognl.java:501) at
> com.opensymphony.xwork2.ognl.OgnlUtil$2.execute(OgnlUtil.java:484) at
> com.opensymphony.xwork2.ognl.OgnlUtil.compileAndExecute(OgnlUtil.java:523) at
> com.opensymphony.xwork2.ognl.OgnlUtil.getValue(OgnlUtil.java:482) at
> com.opensymphony.xwork2.ognl.OgnlValueStack.getValueUsingOgnl(OgnlValueStack.java:296)
> at
> com.opensymphony.xwork2.ognl.OgnlValueStack.tryFindValue(OgnlValueStack.java:279)
> at
> com.opensymphony.xwork2.ognl.OgnlValueStack.tryFindValueWhenExpressionIsNotNull(OgnlValueStack.java:261)
> at
> com.opensymphony.xwork2.ognl.OgnlValueStack.findValue(OgnlValueStack.java:241)
> at org.apache.struts2.components.Component.findValue(Component.java:275) at
> org.apache.struts2.components.Set.end(Set.java:102) at
> org.apache.struts2.views.jsp.ComponentTagSupport.doEndTag(ComponentTagSupport.java:39){code}
> Is it really needed to put this kind of synchronization there, which causes
> thread contention? Would for example a ConcurrentHashMap be possible?
--
This message was sent by Atlassian Jira
(v8.3.4#803005)