Java.lang.IllegalAccessException: cannot access a member of the java.util.Collections $ UnmodifiableCollection class with "public" modifiers

I have the classes PrimitiveProperty and ComplexProperty and the Property interface. I want to create a property implementation that forces an empty, unmodifiable set of instances of Property as the return value of Property.getProperties , for example.

 public interface Property { Set<Property> getProperties(); } public class ComplexProperty implements Property { private Set<Property> properties; //getter overrides the interface method } public class PrimitiveProperty implements Property { private final static Set<Property> EMPTY_PROPS = Collections.unmodifiableSet(new HashSet<Property>(1)); @Override public Set<Property> getProperties() { return EMPTY_PROPS; } } 

With Glassfish 4.0 and I get

java.lang.IllegalAccessException: class javax.el.ELUtil cannot access a member of class java.util.Collections $ UnmodifiableCollection with "public" modifiers

when I access a property in the leaf Richfaces tree attribute, for example.

 <r:tree id="aTree" toggleType="ajax" var="item" > <r:treeModelRecursiveAdaptor roots="#{aCtrl.roots}" nodes="#{item.properties}" leaf="#{item.properties.isEmpty()}"> <r:treeNode> #{item.name} </r:treeNode> <r:treeModelAdaptor nodes="#{item.properties}" leaf="#{item.properties.isEmpty()}"/> </r:treeModelRecursiveAdaptor> </r:tree> 

The problem disappears if I change the constant EMPTY_PROPS constant (assigning an instance of HashSet instead of the return value of Collections.unmodifiableSet ), which is not my intention.

Is it possible to achieve what I want to do? Should I invent or use an implementation of what Collections$UnmodifiableCollection (subclasses) do that are compatible with JSF access needs?

+7
el jsf-2
source share
1 answer

Here is the problem:

 leaf="#{item.properties.isEmpty()}" 

You are trying to call a method directly on an UnmodifiableSet instance. Although it implements Collection , which is public , the implementation of UnmodifiableSet itself, where EL (read: Reflection API) tries to find a method in a class, is not public .

This problem is reproduced in simple Java (a main() ) as follows:

 Set<Object> set = Collections.unmodifiableSet(new HashSet<>()); for (Method method : set.getClass().getMethods()) { if ("isEmpty".equals(method.getName())) { method.invoke(set); // IllegalAccessException. } } 

This is essentially a mistake in the EL implementation used.

It’s better to just use your own empty statement:

 leaf="#{empty item.properties}" 
+10
source share

All Articles