Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Illegal access exception when trying to access attibrute from parent class by introspection

I am currently playing with introspection and annotations in Java 1.5. The have a parent abstract class AbstractClass. The inherited classes can have attributes (of type ChildClass) annotated with a custom @ChildAttribute annotation.

I wanted to write a generic method that would list all @ChildAttribute attributes of an instance.

Here is my code so far.

The parent class :

public abstract class AbstractClass {

    /** List child attributes (via introspection) */
    public final Collection<ChildrenClass> getChildren() {

        // Init result
        ArrayList<ChildrenClass> result = new ArrayList<ChildrenClass>();

        // Loop on fields of current instance
        for (Field field : this.getClass().getDeclaredFields()) {

            // Is it annotated with @ChildAttribute ?
            if (field.getAnnotation(ChildAttribute.class) != null) {
                result.add((ChildClass) field.get(this));
            }

        } // End of loop on fields

        return result;
    }
}

A test implementation, with some child attributes

public class TestClass extends AbstractClass {

    @ChildAttribute protected ChildClass child1 = new ChildClass();
    @ChildAttribute protected ChildClass child2 = new ChildClass();
    @ChildAttribute protected ChildClass child3 = new ChildClass();

    protected String another_attribute = "foo";

}

The test itself:

TestClass test = new TestClass();
test.getChildren()

I get the following error :

IllegalAccessException: Class AbstractClass can not access a member of class TestClass with modifiers "protected"

I tought that introspection access did not care about modifiers, and could read / write even private members.It seems that it is not the case.

How can I access the values of these attributes ?

Thanks in advance for your help,

Raphael

like image 276
Raphael Jolivet Avatar asked Aug 13 '10 13:08

Raphael Jolivet


2 Answers

Add field.setAccessible(true) before you get the value:

field.setAccessible(true);
result.add((ChildClass) field.get(this));
like image 200
Kirk Woll Avatar answered Oct 09 '22 20:10

Kirk Woll


Try field.setAccessible(true) before calling field.get(this). By default, modifiers are honored, but that can be switched off.

like image 45
Thomas Lötzer Avatar answered Oct 09 '22 19:10

Thomas Lötzer