I am attempting to register a ClickListener to a Button. I am using Vaadin 8. This listener should be implemented using Proxy.
final Button button = new Button("Hello");
final Class<?> clickListenerClass = Button.ClickListener.class;
final Object clickListenerInstance = Proxy.newProxyInstance(clickListenerClass.getClassLoader(),
new Class[] {clickListenerClass}, (proxy, method, args) -> {
System.out.println("TEST");
return null;
});
button.addClickListener((Button.ClickListener)clickListenerInstance);
Here is the stack trace (I have omitted my code. The exception occurs on the last line of the above snippet).
java.lang.NullPointerException: null
at com.sun.proxy.$Proxy20.hashCode(Unknown Source)
at com.vaadin.event.ListenerMethod.hashCode(ListenerMethod.java:571)
at java.util.HashMap.hash(HashMap.java:339)
at java.util.HashMap.put(HashMap.java:612)
at java.util.HashSet.add(HashSet.java:220)
at com.vaadin.event.EventRouter.addListener(EventRouter.java:64)
at com.vaadin.server.AbstractClientConnector.addListener(AbstractClientConnector.java:842)
at com.vaadin.ui.Button.addClickListener(Button.java:333)
You are returning null
for any method invocation on the proxy. In the stack trace, you can see that Vaadin calls the hashCode
method which returns null
according to your implementation. From the InvocationHandler
Javadocs, the invoke
method returns:
the value to return from the method invocation on the proxy instance. If the declared return type of the interface method is a primitive type, then the value returned by this method must be an instance of the corresponding primitive wrapper class; otherwise, it must be a type assignable to the declared return type. If the value returned by this method is null and the interface method's return type is primitive, then a NullPointerException will be thrown by the method invocation on the proxy instance. If the value returned by this method is otherwise not compatible with the interface method's declared return type as described above, a ClassCastException will be thrown by the method invocation on the proxy instance.
So for example, you'll need a reference to the target object, invoke the method from that, and return the result. There's a good tutorial at https://www.baeldung.com/java-dynamic-proxies