You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@cxf.apache.org by Jim Talbut <jt...@spudsoft.co.uk> on 2014/02/16 17:30:51 UTC

Further problem with FIQL and interfaces

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

Re: Further problem with FIQL and interfaces

Posted by gamo <ga...@gmail.com>.
In my experience, this problem appears in jdk1.6 (perhaps other minor
versions too), but not in 1.7.



--
View this message in context: http://cxf.547215.n5.nabble.com/Further-problem-with-FIQL-and-interfaces-tp5740033p5746010.html
Sent from the cxf-user mailing list archive at Nabble.com.

Re: Further problem with FIQL and interfaces

Posted by Sergey Beryozkin <sb...@gmail.com>.
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