We are facing an issue with the latest beta12 release : it looks like beanlib tries to instantiate the abstract superclass rather than the concrete child.
After investigation, it looks like the problem comes from the (new) 'chooseClass' method :
Hibernate3JavaBeanReplicator)
protected <T> T createToInstance(Object from, Class<T> toClass)
throws InstantiationException, IllegalAccessException, SecurityException, NoSuchMethodException
{
// figure out the pre-enhanced class
Class<T> actualClass = UnEnhancer.getActualClass(from);
Class<T> targetClass = chooseClass(actualClass, toClass);
return newInstanceAsPrivileged(targetClass);
}
Anyhow, your proposed solution looks reasonable. Given an abstract class cannot be instantiated, returning the other class is probably the best it can do. I've made the change and will prepare a release shortly.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hi,
We are facing an issue with the latest beta12 release : it looks like beanlib tries to instantiate the abstract superclass rather than the concrete child.
After investigation, it looks like the problem comes from the (new) 'chooseClass' method :
Hibernate3JavaBeanReplicator)
protected <T> T createToInstance(Object from, Class<T> toClass)
throws InstantiationException, IllegalAccessException, SecurityException, NoSuchMethodException
{
// figure out the pre-enhanced class
Class<T> actualClass = UnEnhancer.getActualClass(from);
Class<T> targetClass = chooseClass(actualClass, toClass);
return newInstanceAsPrivileged(targetClass);
}
(ReplicatorTemplate)
protected final <T> Class<T> chooseClass(Class<?> fromClass, Class<T> toClass) {
return (Class<T>)(toClass.isAssignableFrom(fromClass) ? fromClass : toClass);
}
Maybe we can complete it with another test, such as :
protected final <T> Class<T> chooseClass(Class<?> fromClass, Class<T> toClass) {
if (toClass.isAssignableFrom(fromClass) == false)
{
return toClass;
}
else
{
// is the fromClass abstract ?
int modifiers = fromClass.getModifiers();
if (Modifier.isAbstract(modifiers))
{
// Do not choose abstract class
return toClass;
}
else
{
return fromClass;
}
}
}
Do you think I am right ?
Regards
Bruno
Do you have a test case that can demonstrate this problem ?
Anyhow, your proposed solution looks reasonable. Given an abstract class cannot be instantiated, returning the other class is probably the best it can do. I've made the change and will prepare a release shortly.
You can now download beta13 for the fix. Thanks for pointing this out :)
Great :) !
I try it ASAP and keep you informed.
Thanks a lot for your quick answer !
Bruno