我有一个Spring MVC控制器,它在范围/模型中添加了一个Guava HashMultimap
。然后,JSP读取该数据结构以显示每个应用程序的角色列表:
在控制器中:
HashMultimap<Long,Role> rolesByApp = HashMultimap.create();
//... fill the multimap
model.addAttribute("rolesByApp", rolesByApp);
在JSP中:
<c:forEach items="${applications}" var="app" varStatus="s1">
<c:set var="appRoles" value="${rolesByApp.get(app.id)}"/>
<!-- for each role display a checkbox, etc. -->
</c:forEach>
当我尝试从IllegalAccessException
读取时,我在JSP的c:set行上得到HashMultiMap
:
java.lang.IllegalAccessException: Class javax.el.BeanELResolver can not access a member of class com.google.common.collect.AbstractSetMultimap with modifiers "public volatile"
它不会一直发生,也许在我的开发机器(Mac)上有4次中有3次。在服务器上它一直运行良好(Red Hat Linux)。它曾经在我的开发机器上正常工作,当我开发它时,我在Win7下。
如果我将HashMultimap<Long,Role>
替换为HashMap<Long, List<Role>>
,它也可以正常工作。
我不明白这个错误。可能是什么原因?
答案 0 :(得分:2)
在使用MultiMap
构建数据结构的同时,我公开了Map
视图,而不是MultiMap
本身:
model.addAttribute("rolesByApp", rolesByApp.asMap());
在JSP中我替换了
<c:set var="appRoles" value="${rolesByApp.get(app.id)}"/>
与
<c:set var="appRoles" value="${rolesByApp[app.id]}"/>
这可以解决错误。
我仍然不知道上一次错误的原因。如果有人可以复制并解释错误,我会接受答案。否则我最终会接受我自己的解决方法。
答案 1 :(得分:1)
请注意com.google.common.collect.Multimap
不实施java.util.Map
。
因此,除非您在Servlet 3.0兼容容器中运行代码,否则JSTL表达式语言不支持Multimap。 JSTL-specification指出,如果应用了JSTL表达式的对象既没有实现java.util.List,也没有实现java.util.Map,JSTL期望Java-Bean标准符合getter。
这意味着对于Servlet 2而言,必须将Multimap转换为&#34; normal&#34;在将其交给JSP之前映射,以便使用JSTL表达式访问映射。
答案 2 :(得分:1)
Code使用反射来访问该方法。由于它不时地工作并且仅在Mac上工作,因此它产生的问题是它与JDK实现有关。手上的问题是由我猜这个JDK的安全经理造成的。尝试安装OpenJDK(顺便说一下你使用的JDK)并使用不同的JDK并在问题仍然存在时重试。
如果第二个JDK没有引起问题,请尝试将问题最小化到可以重现问题并使用visualVM或(远程)调试器来访问和理解手头的问题。将您拥有的所有内容发送给JDK开发人员团队,并享受发现错误。
您也可以尝试使用自己的Reflection方法访问相关方法,看看它是否也失败。
问题是有效的问题并且不是基于显然随机的属性...