You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@cxf.apache.org by Matteo Rulli <ma...@gmail.com> on 2019/01/11 13:05:14 UTC
JAX-RSSearch and FIQL: Beanspector throws (unecessary?)
IllegalArgumentException with some POJOs structures
Hello,
We use JAX-RSSearch and Fiql parser in a JAX-RS endpoint and we have a problem with org.apache.cxf.jaxrs.ext.search.Beanspector.
Let's consider the following pojos:
public class A {
private String value;
public String getValue(){ ... }
public void setValue(String value) { ... }
}
public class B {
private A aValue;
public A getAValue(){ ... }
public void setAValue(A avalue) { ... }
}
And assume one extends these pojos and decorates them with JPA annotations.
To leverage CXF org.apache.cxf.jaxrs.ext.search.SearchContext and JPACriteriaQueryVisitor as explained in the docs (http://cxf.apache.org/docs/jax-rs-search.html#JAX-RSSearch-JPA2.0) and perform searches like
_s=aValue==*search token*
in OpenJPA one has to override the EntityB.getAValue as follows:
@Entity
// ... other JPA annotations are omitted
public class EntityB extends B {
@Override
// We need to specialize return type to EntityA to make SearchContext work
public EntityA getAValue(){ ... }
// This method definition is needed to avoid java.lang.VerifyError from JPA provider
public void setAValue(EntityA avalue) { ... }
}
But with this scenario, the current implementation of org.apache.cxf.jaxrs.ext.search.Beanspector<T> fails, throwing IllegalArgumentException: Accessor 'aValue' type mismatch, getter type is X while setter type is Y, X and Y depending on the order of the EntityB's methods as returned by the Class.getMethods().
This is the current implementation of Beanspector where the exception is triggered:
@SuppressWarnings("unchecked")
private void 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<>(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()));
}
}
}
And this is how we patched it:
@SuppressWarnings("unchecked")
private void init() {
if (tclass == null) {
tclass = (Class<T>)tobj.getClass();
}
for (Method m : tclass.getMethods()) {
if (isGetter(m)) {
String pname = getPropertyName(m);
if (!getters.containsKey(pname)) {
getters.put(getPropertyName(m), m);
} else {
// Prefer the getter that has the most specialized class as a return type
Method _m = getters.get(pname);
if (_m.getReturnType().isAssignableFrom(m.getReturnType())) {
getters.put(pname, m);
}
}
} else if (isSetter(m)) {
String pname = getPropertyName(m);
if (!setters.containsKey(pname)) {
setters.put(getPropertyName(m), m);
} else {
// Prefer the setter that has the most specialized class as a parameter
Method _m = setters.get(pname);
if (_m.getParameterTypes()[0].isAssignableFrom(m.getParameterTypes()[0])) {
setters.put(pname, m);
}
}
}
}
// check type equality for getter-setter pairs
Set<String> pairs = new HashSet<>(getters.keySet());
pairs.retainAll(setters.keySet());
for (String accessor : pairs) {
Class<?> getterClass = getters.get(accessor).getReturnType();
Class<?> setterClass = setters.get(accessor).getParameterTypes()[0];
if (!setterClass.isAssignableFrom(getterClass)) {
throw new IllegalArgumentException(String
.format("Accessor '%s' type mismatch, getter type is %s while setter type is %s",
accessor, getterClass.getName(), setterClass.getName()));
}
}
}
If you think this is OK we can create a pull request with this.
Thank you,
Matteo
Re: JAX-RSSearch and FIQL: Beanspector throws (unecessary?)
IllegalArgumentException with some POJOs structures
Posted by Matteo Rulli <ma...@gmail.com>.
Hello,
I created an issue (https://issues.apache.org/jira/browse/CXF-7966) and submitted a PR (https://github.com/apache/cxf/pull/510/).
Matteo
> On 22 Jan 2019, at 17:33, Colm O hEigeartaigh <co...@apache.org> wrote:
>
> Hi,
>
> Please create a pull request and we will review it in more detail.
>
> Colm.
>
> On Fri, Jan 11, 2019 at 1:28 PM Matteo Rulli <ma...@gmail.com> wrote:
>
>> Hello,
>>
>> We use JAX-RSSearch and Fiql parser in a JAX-RS endpoint and we have a
>> problem with org.apache.cxf.jaxrs.ext.search.Beanspector.
>>
>> Let's consider the following pojos:
>>
>> public class A {
>>
>> private String value;
>>
>> public String getValue(){ ... }
>> public void setValue(String value) { ... }
>> }
>>
>> public class B {
>>
>> private A aValue;
>>
>> public A getAValue(){ ... }
>> public void setAValue(A avalue) { ... }
>> }
>>
>> And assume one extends these pojos and decorates them with JPA
>> annotations.
>>
>> To leverage CXF org.apache.cxf.jaxrs.ext.search.SearchContext and
>> JPACriteriaQueryVisitor as explained in the docs (
>> http://cxf.apache.org/docs/jax-rs-search.html#JAX-RSSearch-JPA2.0) and
>> perform searches like
>>
>> _s=aValue==*search token*
>>
>> in OpenJPA one has to override the EntityB.getAValue as follows:
>>
>> @Entity
>> // ... other JPA annotations are omitted
>> public class EntityB extends B {
>>
>> @Override
>> // We need to specialize return type to EntityA to make
>> SearchContext work
>> public EntityA getAValue(){ ... }
>>
>> // This method definition is needed to avoid java.lang.VerifyError
>> from JPA provider
>> public void setAValue(EntityA avalue) { ... }
>> }
>>
>> But with this scenario, the current implementation of
>> org.apache.cxf.jaxrs.ext.search.Beanspector<T> fails, throwing
>> IllegalArgumentException: Accessor 'aValue' type mismatch, getter type is X
>> while setter type is Y, X and Y depending on the order of the EntityB's
>> methods as returned by the Class.getMethods().
>>
>> This is the current implementation of Beanspector where the exception is
>> triggered:
>>
>> @SuppressWarnings("unchecked")
>> private void 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<>(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()));
>> }
>> }
>> }
>>
>> And this is how we patched it:
>>
>> @SuppressWarnings("unchecked")
>> private void init() {
>> if (tclass == null) {
>> tclass = (Class<T>)tobj.getClass();
>> }
>> for (Method m : tclass.getMethods()) {
>> if (isGetter(m)) {
>> String pname = getPropertyName(m);
>> if (!getters.containsKey(pname)) {
>> getters.put(getPropertyName(m), m);
>> } else {
>> // Prefer the getter that has the most specialized
>> class as a return type
>> Method _m = getters.get(pname);
>> if
>> (_m.getReturnType().isAssignableFrom(m.getReturnType())) {
>> getters.put(pname, m);
>> }
>> }
>> } else if (isSetter(m)) {
>> String pname = getPropertyName(m);
>> if (!setters.containsKey(pname)) {
>> setters.put(getPropertyName(m), m);
>> } else {
>> // Prefer the setter that has the most specialized
>> class as a parameter
>> Method _m = setters.get(pname);
>> if
>> (_m.getParameterTypes()[0].isAssignableFrom(m.getParameterTypes()[0])) {
>> setters.put(pname, m);
>> }
>> }
>> }
>> }
>> // check type equality for getter-setter pairs
>> Set<String> pairs = new HashSet<>(getters.keySet());
>> pairs.retainAll(setters.keySet());
>> for (String accessor : pairs) {
>> Class<?> getterClass = getters.get(accessor).getReturnType();
>> Class<?> setterClass =
>> setters.get(accessor).getParameterTypes()[0];
>> if (!setterClass.isAssignableFrom(getterClass)) {
>> throw new IllegalArgumentException(String
>> .format("Accessor '%s' type mismatch, getter type is %s
>> while setter type is %s",
>> accessor, getterClass.getName(),
>> setterClass.getName()));
>> }
>> }
>> }
>>
>> If you think this is OK we can create a pull request with this.
>>
>> Thank you,
>> Matteo
>
>
>
> --
> Colm O hEigeartaigh
>
> Talend Community Coder
> http://coders.talend.com
Re: JAX-RSSearch and FIQL: Beanspector throws (unecessary?)
IllegalArgumentException with some POJOs structures
Posted by Colm O hEigeartaigh <co...@apache.org>.
Hi,
Please create a pull request and we will review it in more detail.
Colm.
On Fri, Jan 11, 2019 at 1:28 PM Matteo Rulli <ma...@gmail.com> wrote:
> Hello,
>
> We use JAX-RSSearch and Fiql parser in a JAX-RS endpoint and we have a
> problem with org.apache.cxf.jaxrs.ext.search.Beanspector.
>
> Let's consider the following pojos:
>
> public class A {
>
> private String value;
>
> public String getValue(){ ... }
> public void setValue(String value) { ... }
> }
>
> public class B {
>
> private A aValue;
>
> public A getAValue(){ ... }
> public void setAValue(A avalue) { ... }
> }
>
> And assume one extends these pojos and decorates them with JPA
> annotations.
>
> To leverage CXF org.apache.cxf.jaxrs.ext.search.SearchContext and
> JPACriteriaQueryVisitor as explained in the docs (
> http://cxf.apache.org/docs/jax-rs-search.html#JAX-RSSearch-JPA2.0) and
> perform searches like
>
> _s=aValue==*search token*
>
> in OpenJPA one has to override the EntityB.getAValue as follows:
>
> @Entity
> // ... other JPA annotations are omitted
> public class EntityB extends B {
>
> @Override
> // We need to specialize return type to EntityA to make
> SearchContext work
> public EntityA getAValue(){ ... }
>
> // This method definition is needed to avoid java.lang.VerifyError
> from JPA provider
> public void setAValue(EntityA avalue) { ... }
> }
>
> But with this scenario, the current implementation of
> org.apache.cxf.jaxrs.ext.search.Beanspector<T> fails, throwing
> IllegalArgumentException: Accessor 'aValue' type mismatch, getter type is X
> while setter type is Y, X and Y depending on the order of the EntityB's
> methods as returned by the Class.getMethods().
>
> This is the current implementation of Beanspector where the exception is
> triggered:
>
> @SuppressWarnings("unchecked")
> private void 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<>(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()));
> }
> }
> }
>
> And this is how we patched it:
>
> @SuppressWarnings("unchecked")
> private void init() {
> if (tclass == null) {
> tclass = (Class<T>)tobj.getClass();
> }
> for (Method m : tclass.getMethods()) {
> if (isGetter(m)) {
> String pname = getPropertyName(m);
> if (!getters.containsKey(pname)) {
> getters.put(getPropertyName(m), m);
> } else {
> // Prefer the getter that has the most specialized
> class as a return type
> Method _m = getters.get(pname);
> if
> (_m.getReturnType().isAssignableFrom(m.getReturnType())) {
> getters.put(pname, m);
> }
> }
> } else if (isSetter(m)) {
> String pname = getPropertyName(m);
> if (!setters.containsKey(pname)) {
> setters.put(getPropertyName(m), m);
> } else {
> // Prefer the setter that has the most specialized
> class as a parameter
> Method _m = setters.get(pname);
> if
> (_m.getParameterTypes()[0].isAssignableFrom(m.getParameterTypes()[0])) {
> setters.put(pname, m);
> }
> }
> }
> }
> // check type equality for getter-setter pairs
> Set<String> pairs = new HashSet<>(getters.keySet());
> pairs.retainAll(setters.keySet());
> for (String accessor : pairs) {
> Class<?> getterClass = getters.get(accessor).getReturnType();
> Class<?> setterClass =
> setters.get(accessor).getParameterTypes()[0];
> if (!setterClass.isAssignableFrom(getterClass)) {
> throw new IllegalArgumentException(String
> .format("Accessor '%s' type mismatch, getter type is %s
> while setter type is %s",
> accessor, getterClass.getName(),
> setterClass.getName()));
> }
> }
> }
>
> If you think this is OK we can create a pull request with this.
>
> Thank you,
> Matteo
--
Colm O hEigeartaigh
Talend Community Coder
http://coders.talend.com