Bug 59939 - NoSuchMethodException: java.util.HashMap.get(java.lang.String)
Summary: NoSuchMethodException: java.util.HashMap.get(java.lang.String)
Alias: None
Product: Tomcat 7
Classification: Unclassified
Component: Jasper (show other bugs)
Version: 7.0.53
Hardware: PC Linux
: P2 normal (vote)
Target Milestone: ---
Assignee: Tomcat Developers Mailing List
Depends on:
Reported: 2016-08-03 17:58 UTC by Hao
Modified: 2016-08-05 04:33 UTC (History)
1 user (show)


Note You need to log in before you can comment on or make changes to this bug.
Description Hao 2016-08-03 17:58:20 UTC
Our code is broken after upgrading Tomcat from 7.0.52 to 7.0.55 with exception
javax.el.MethodNotFoundException: java.lang.NoSuchMethodException: java.util.HashMap.get(java.lang.String)

The JSP code is like this
<a:string id="${textMap.get(report)}"/>

'report' is a String, and 'textMap' is a Map. When invoking textMap.get(report), ELResolver tries to find the get() method that exactly matched the argument type. The get() method takes an Object in method signature but 'report' argument is a String type. That results in the Exception. Stacktrace: 

Caused by: javax.el.MethodNotFoundException: java.lang.NoSuchMethodException: java.util.HashMap.get(java.lang.String)
      at javax.el.BeanELResolver.invoke(BeanELResolver.java:422)
      at org.apache.jasper.el.JasperELResolver.invoke(JasperELResolver.java:139)
      at org.apache.el.parser.AstValue.getValue(AstValue.java:174)
      at org.apache.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:184)
      at org.apache.jasper.runtime.PageContextImpl.proprietaryEvaluate(PageContextImpl.java:950)
      at org.apache.jsp.tag.web.reportSelector_tag._jspx_meth_aui_005fdropdownOption_005f0(reportSelector_tag.java:222)
      at org.apache.jsp.tag.web.reportSelector_tag._jspx_meth_c_005fforEach_005f0(reportSelector_tag.java:193)
      at org.apache.jsp.tag.web.reportSelector_tag._jspx_meth_aui_005fdropdown_005f0(reportSelector_tag.java:162)
      at org.apache.jsp.tag.web.reportSelector_tag.doTag(reportSelector_tag.java:126)
      at org.apache.jsp.tag.web.genericReport_tag._jspx_meth_vxa_005freportSelector_005f0(genericReport_tag.java:295)
      at org.apache.jsp.tag.web.genericReport_tag._jspx_meth_aui_005ffixedGridColumn_005f0(genericReport_tag.java:266)
      at org.apache.jsp.tag.web.genericReport_tag._jspx_meth_aui_005ffixedGridRow_005f0(genericReport_tag.java:231)
      at org.apache.jsp.tag.web.genericReport_tag.doTag(genericReport_tag.java:145)
      at org.apache.jsp.layouts.AraBasicDashboardLayout1_jsp._jspx_meth_vxa_005fgenericReport_005f0(AraBasicDashboardLayout1_jsp.java:169)
      at org.apache.jsp.layouts.AraBasicDashboardLayout1_jsp._jspService(AraBasicDashboardLayout1_jsp.java:133)
      ... 38 more
Caused by: java.lang.NoSuchMethodException: java.util.HashMap.get(java.lang.String)
      at java.lang.Class.getMethod(Class.java:1786)
      at javax.el.BeanELResolver.invoke(BeanELResolver.java:419)
      ... 52 more }, RID=1ERZG1MHXPWD3PBNK67H

It was working in Tomcat 7.0.52 because 7.0.52 tries to find a random method with the same name without considering the argument type. That caused problem when there is method overload and was fixed in 7.0.53 here
This fix broke our code because now ELResolver tries to find a method exactly matching the argument type.
Comment 1 Hao 2016-08-03 18:08:00 UTC
A logic should be added so that when there is no method overload, just return the only method that matches the name, so that it is compatible with the version 7.0.52. Current behavior broke our code in multiple places and makes method invocation hard to use. For example, the code below is broken because actionItems is an ArrayList, but the method writeValueAsString() takes an Object in method signature.
<c:set target="${actionItemsMap}" property="actionItems" value="${objectMapper.writeValueAsString(actionItems)}" />

javax.el.MethodNotFoundException: java.lang.NoSuchMethodException: org.codehaus.jackson.map.ObjectMapper.writeValueAsString(java.util.ArrayList)

Moreover, we have a method in some class defined like this 
  public List<String> getActionOptions(Map<String, String> mappings)

And it is being invoked like this in JSP 
  <c:forEach var="option" items="${doc.getActionOptions(endpointMappings)}">

The new Tomcat version caused exception here too:
Caused by: javax.el.MethodNotFoundException: java.lang.NoSuchMethodException: com.amazon.edi.ssi.lib.types.IntegrationStatus.getActionOptions(java.util.HashMap)

The exception happens because ELResolver tries to find a method that matches the runtime argument type of variable 'endpointMappings', which is a HashMap. But the method signature takes an Map interface argument so it does not match. That should be fixed.
Comment 2 Mark Thomas 2016-08-04 16:12:07 UTC
A simple, self-contained JSP that demonstrates the issue would help.
Comment 3 Hao 2016-08-05 04:33:46 UTC
(In reply to Mark Thomas from comment #2)
> A simple, self-contained JSP that demonstrates the issue would help.

I am sorry Mark. This is an issue on our side. These parameterized method calls are supported in the new version. My apologies.