access exception when invoking method of an anonymous class using java reflection
- by Asaf David
Hello
I'm trying to use an event dispatcher to allow a model to notify subscribed listeners when it changes. the event dispatcher receives a handler class and a method name to call during dispatch. the presenter subscribes to the model changes and provide a Handler implementation to be called on changes.
Here's the code (I'm sorry it's a bit long).
EventDispacther:
package utils;
public class EventDispatcher<T> {
    List<T> listeners;
    private String methodName;
    public EventDispatcher(String methodName) {
        listeners = new ArrayList<T>();
        this.methodName = methodName;
    }
    public void add(T listener) {
        listeners.add(listener);
    }
    public void dispatch() {
        for (T listener : listeners) {
            try {
                Method method = listener.getClass().getMethod(methodName);
                method.invoke(listener);
            } catch (Exception e) {
                System.out.println(e.getMessage());
            }
        }
    }
}
Model:
package model;
public class Model {
    private EventDispatcher<ModelChangedHandler> dispatcher;
    public Model() {
        dispatcher = new EventDispatcher<ModelChangedHandler>("modelChanged");
    }
    public void whenModelChange(ModelChangedHandler handler) {
        dispatcher.add(handler);
    }
    public void change() {
        dispatcher.dispatch();
    }
}
ModelChangedHandler:
package model;
public interface ModelChangedHandler {
    void modelChanged();
}
Presenter:
package presenter;
public class Presenter {
    private final Model model;
    public Presenter(Model model) {
        this.model = model;
        this.model.whenModelChange(new ModelChangedHandler() {
            @Override
            public void modelChanged() {
                System.out.println("model changed");
            }
        });
    }
}
Main:
package main;
public class Main {
    public static void main(String[] args) {
        Model model = new Model();
        Presenter presenter = new Presenter(model);
        model.change();
    }
}
Now, I except to get the "model changed" message. However, I'm getting an  java.lang.IllegalAccessException: Class utils.EventDispatcher can not access a member of class presenter.Presenter$1 with modifiers "public". 
I understand that the class to blame is the anonymous class i created inside the presenter, however I don't know how to make it any more 'public' than it currently is. If i replace it with a named nested class it seem to work. It also works if the Presenter and the EventDispatcher are in the same package, but I can't allow that (several presenters in different packages should use the EventDispatcher)
any ideas?