Important Notice - Forums is archived
To simplify things and help our users to be more productive, we have archived the current forum and focus our efforts on helping developers on Stack Overflow. You can post new questions on Stack Overflow or join our Discord channel.

Vaadin lets you build secure, UX-first PWAs entirely in Java.
Free ebook & tutorial.
Abstract property in BeanContainer
Hello,
I have a bean, that one property is an interface without any method:
public class Security {
<some common properties>
private SecurityTail tail;
<getters an setters>
public SecurityTail getTail() {
return tail;
}
public void setTail(SecurityTail tail) {
this.tail = tail;
}
}
public interface SecurityTail {}
I display the beans in tables with AbstractBeanContainer. I have the main table with all security types and it works fine. But I would like to display other table with specified kind of security, ie. in each table the tail property would be of the same (not abstact type). Is it possible?
Now when trying to add property tail.effectiveDate I get an exception:
java.lang.IllegalArgumentException: Bean property 'effectiveDate' not found
at com.vaadin.data.util.NestedMethodProperty.initialize(NestedMethodProperty.java:146)
at com.vaadin.data.util.NestedMethodProperty.<init>(NestedMethodProperty.java:106)
at com.vaadin.data.util.NestedPropertyDescriptor.<init>(NestedPropertyDescriptor.java:52)
at com.vaadin.data.util.AbstractBeanContainer.addNestedContainerProperty(AbstractBeanContainer.java:853)
at cz.px.iis.ng.ui.view.PxTableViewRoot.init(PxTableViewRoot.java:542)
at cz.pse.agata.commons.ui.view.PxTabWithTableAndMenuWithBasicOperations.init(PxTabWithTableAndMenuWithBasicOperations.java:175)
at cz.px.iis.ng.ui.view.PxTableViewRoot.attach(PxTableViewRoot.java:980)
at com.vaadin.ui.AbstractComponent.setParent(AbstractComponent.java:484)
at com.vaadin.ui.AbstractComponentContainer.addComponent(AbstractComponentContainer.java:210)
at com.vaadin.ui.TabSheet.addTab(TabSheet.java:342)
at com.vaadin.ui.TabSheet.addTab(TabSheet.java:378)
at com.vaadin.ui.TabSheet.addTab(TabSheet.java:359)
at cz.px.iis.ng.ui.PxUI.addTab(PxUI.java:146)
at cz.pse.agata.commons.CommonUI.addPxTab(CommonUI.java:368)
at cz.pse.cp.ui.view.SecuritiesView.lambda$3(SecuritiesView.java:187)
at cz.pse.cp.ui.view.SecuritiesView$$Lambda$9/1079210580.execute(Unknown Source)
at cz.px.iis.ng.ui.menu.PxActionFactory$PxAction$1.buttonClick(PxActionFactory.java:142)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at com.vaadin.event.ListenerMethod.receiveEvent(ListenerMethod.java:508)
at com.vaadin.event.EventRouter.fireEvent(EventRouter.java:198)
at com.vaadin.event.EventRouter.fireEvent(EventRouter.java:161)
at com.vaadin.server.AbstractClientConnector.fireEvent(AbstractClientConnector.java:979)
at com.vaadin.ui.Button.fireClick(Button.java:393)
at com.vaadin.ui.Button$1.click(Button.java:57)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at com.vaadin.server.ServerRpcManager.applyInvocation(ServerRpcManager.java:168)
at com.vaadin.server.ServerRpcManager.applyInvocation(ServerRpcManager.java:118)
at com.vaadin.server.communication.ServerRpcHandler.handleInvocations(ServerRpcHandler.java:287)
at com.vaadin.server.communication.ServerRpcHandler.handleRpc(ServerRpcHandler.java:180)
at com.vaadin.server.communication.UidlRequestHandler.synchronizedHandleRequest(UidlRequestHandler.java:93)
at com.vaadin.server.SynchronizedRequestHandler.handleRequest(SynchronizedRequestHandler.java:41)
at com.vaadin.server.VaadinService.handleRequest(VaadinService.java:1406)
at com.vaadin.server.VaadinServlet.service(VaadinServlet.java:305)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:611)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1023)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:312)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.NoSuchMethodException: cz.pse.agata.commons.dto.SecurityTail.areEffectiveDate()
at java.lang.Class.getMethod(Class.java:1773)
at com.vaadin.data.util.MethodProperty.initGetterMethod(MethodProperty.java:547)
at com.vaadin.data.util.NestedMethodProperty.initialize(NestedMethodProperty.java:141)
... 55 more
even thought this concrete tail has method getEffectiveDate().
Hi, I could have a look at it if you attach an example project.
Hi Alejandro,
at last I implemented it in following way:
private static class MyNestedPropertyDescriptor<BT> implements VaadinPropertyDescriptor<BT>{
private static final long serialVersionUID = 6525407357415432577L;
private String name;
private Class<?> propertyType;
private Class<?> middleType;
public MyNestedPropertyDescriptor(String name, Class<BT> beanType, Class<?> propType){
this.name = name;
MyNestedMethodProperty<?> property = new MyNestedMethodProperty<Object>(
beanType, propType, name);
this.middleType = propType;
this.propertyType = property.getType();
}
@Override
public String getName() {
return name;
}
@Override
public Class<?> getPropertyType() {
return propertyType;
}
@Override
public Property<?> createProperty(BT bean) {
return new MyNestedMethodProperty<>(bean, middleType, name);
}
}
private static class MyNestedMethodProperty<T> extends AbstractProperty<T>{
private static final long serialVersionUID = -4842009339734837059L;
private Object instance;
private Method firstGetter;
private Method secondGetter;
private Method setMethod;
private Class<? extends T> type;
public MyNestedMethodProperty(Object instance, Class<?> propertyType, String propertyName){
this.instance = instance;
initialize(instance.getClass(), propertyType, propertyName);
}
public MyNestedMethodProperty(Class<?> instanceClass, Class<?> propertyType, String propertyName){
instance = null;
initialize(instanceClass, propertyType, propertyName);
}
private void initialize(Class<?> beanClass, Class<?> propertyClass, String propertyName) {
String simplePropertyNames = propertyName.split("\\.");
try {
firstGetter = NestedMethodProperty.initGetterMethod(simplePropertyNames[0], beanClass);
secondGetter = NestedMethodProperty.initGetterMethod(simplePropertyNames[1], propertyClass);
} catch (NoSuchMethodException e) {
throw new IllegalArgumentException("Bean property not found", e);
}
type = (Class<? extends T>) secondGetter.getReturnType();
try {
setMethod = propertyClass.getMethod("set" + simplePropertyNames[1], new Class { type });
} catch (NoSuchMethodException | SecurityException e) {
}
}
@Override
public T getValue() {
Object v1;
try {
v1 = firstGetter.invoke(instance);
return v1 == null ? null : (T)secondGetter.invoke(v1);
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
throw new MethodException(this, e);
}
}
@Override
public void setValue(T newValue) throws com.vaadin.data.Property.ReadOnlyException {
try {
Object v1 = firstGetter.invoke(instance);
setMethod.invoke(v1, newValue);
} catch (IllegalAccessException | IllegalArgumentException e) {
throw new MethodException(this, e);
} catch (InvocationTargetException e) {
throw new MethodException(this, e.getTargetException());
}
fireValueChange();
}
@Override
public Class<? extends T> getType() {
return type;
}
}
private static class SecurityHistoryContainer<T extends SecurityTail> extends BeanItemContainer<Security> {
private static final long serialVersionUID = -6287052228121829118L;
private Class<T> tailClass;
public SecurityHistoryContainer(Class<T> tailClass) throws IllegalArgumentException {
super(Security.class);
this.tailClass = tailClass;
}
@Override
public boolean addNestedContainerProperty(String propertyId) {
if (!propertyId.startsWith("tail.")) {
return super.addNestedContainerProperty(propertyId);
}
return addContainerProperty(propertyId, new MyNestedPropertyDescriptor<>(propertyId, Security.class, tailClass));
}
}
It doesn't work for nested properties in tail, but such functionality is enough for me.
Hi, thanks for sharing.
The problem is that the SecurityTail interface doesn't declare any getEffectiveDate nor setEffectiveDate methods at all. Behind the scenes, BeanItemContainer uses Java reflextion to "discover" properties (and so does your own implementation). In this case it will try to find Java getters and setters in the SecurityTail interface and there are none. The properties are "discovered" at container creation time when no items have been added. Hence, even if you add items to the container and these items correspond to Security instances having references to concrete implementations of SecurityTail that in turn do contain the effectiveDate field, there's no way this property could be discovered.
I would suggest to check whether the design can be improved. Particularly, I would question the need of a SecurityTail interface with no methods. I understand that you may have several implementations of SecurityTail and setting instances of them according to some business rules, but still looks like not the best design. I may be missing something, though.
Hope that helps.
Alejandro, I understand all that, but the SecurityTail can have any properties (even none) and there are not any in common.
Any way, because of having problems with MyBatis also, I changed the architecture by creating classes inheriting from Security instead of having the a tail. With this solution I can use Mcont and everything works as expected.
Agata