Hi Jim

Can you please open a JIRA issue and prototype some code which will help me reproduce the issue ?

Thanks, Sergey
On 16/02/14 16:30, Jim Talbut wrote:
Hi,

Further to previous discussions about issues using FIQL with interfaces,
I've just come across another issue.
I have a Task interface that has a getJob() method that returns a Job
interface.
This is implemented by the Task_Impl class that returns a Job_Impl
interface.

Unfortunately I'm hitting this error:
     Caused by: java.lang.IllegalArgumentException: Accessor 'job' type
mismatch, getter type is Job while setter type is Job_Impl
(package names redacted)

The Task_Impl class, which is the one being worked on, returns Job_Impl
from getJob(), so why is it wrong?

The answer lies here:
Beanspectors.init() {
         if (tclass == null) {
             tclass = (Class<T>)tobj.getClass();
         }
         for (Method m : tclass.getMethods()) {
             if (isGetter(m)) {
                 getters.put(getPropertyName(m), m);
             } else if (isSetter(m)) {
                 setters.put(getPropertyName(m), m);
             }
         }
         // check type equality for getter-setter pairs
         Set<String> pairs = new HashSet<String>(getters.keySet());
         pairs.retainAll(setters.keySet());
         for (String accessor : pairs) {
             Class<?> getterClass = getters.get(accessor).getReturnType();
             Class<?> setterClass =
setters.get(accessor).getParameterTypes()[0];
             if (!getterClass.equals(setterClass)) {
                 throw new IllegalArgumentException(String
                     .format("Accessor '%s' type mismatch, getter type
is %s while setter type is %s",
                             accessor, getterClass.getName(),
setterClass.getName()));
             }
         }
     }

It seems that Java puts two getJob methods in the class object - one
from the interface and one from the class.
And, for my Task_Impl class the abstract getJob comes after the concrete
getJob.
And whilst the order of the methods is consistent between runs it's not
fixed for different classes - so whilst the trick of overriding the
return type of getJob works some of the time it doesn't work in all cases.

For my situation it would work if the
                 getters.put(getPropertyName(m), m);
checked for an existing method and only replaced it if the new method
returned a more specific class.
I think that would work in general because the actual class has to be
actually returning the more specific class - but you might have to do
some check on the setter too to ensure that you have consistency between
the two, which is a bit nasty.

Jim

Jim


--
Sergey Beryozkin

Talend Community Coders
http://coders.talend.com/

Blog: http://sberyozkin.blogspot.com

Reply via email to