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