You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@cxf.apache.org by "Andrei Shakirin (JIRA)" <ji...@apache.org> on 2014/05/01 10:24:14 UTC
[jira] [Updated] (CXF-5722) JAXB generated Enum throws
IllegalArgumentException by unmarshalling as @QueryParam
[ https://issues.apache.org/jira/browse/CXF-5722?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Andrei Shakirin updated CXF-5722:
---------------------------------
Description:
By processing request with Query parameter, InjectionUtils tries to recognize and instantiate parameter class.
In case of Enum parameter class, InjectionUtils.handleParameter() method calls in loop following methods: "fromString", "fromValue", "valueOf" using reflection. If method returns null, it tries the next one:
if (result == null) {
// check for valueOf(String) static methods
String[] methodNames = cls.isEnum()
? new String[] {"fromString", "fromValue", "valueOf"}
: new String[] {"valueOf", "fromString"};
for (String mName : methodNames) {
result = evaluateFactoryMethod(value, cls, pType, mName);
if (result != null) {
break;
}
}
The problem is that factory methods in JAXB generated Enum behaves differently:
- valueOf accepts enum identifier (not value)
- fromValue accepts enum value
Both methods throws IllegalArgumentException by worng argument and do not return null, how current code expecting.
As a result following method throws IllegalArgumentException:
1) method:
@GET
@Path("/enum/")
Response checkEnum(@QueryParam("car") CarType car);
2) generated enum:
@XmlRootElement(name = "Car")
@XmlType(name = "carType")
@XmlEnum
public enum CarType {
@XmlEnumValue("Audi")
AUDI("Audi"),
@XmlEnumValue("Golf")
GOLF("Golf"),
BMW("BMW");
private final String value;
CarType(String v) {
value = v;
}
public String value() {
return value;
}
public static CarType fromValue(String v) {
for (CarType c: CarType.values()) {
if (c.value.equals(v)) {
return c;
}
}
throw new IllegalArgumentException(v);
}
}
3) call:
customerService.checkEnum(CarType.AUDI);
was:
By processing request with Query parameter, InjectionUtils tries to recognize and instantiate parameter class.
In case of Enum parameter class, InjectionUtils.handleParameter() method calls in loop following methods: "fromString", "fromValue", "valueOf" using reflection. If method returns null, it tries the next one:
if (result == null) {
// check for valueOf(String) static methods
String[] methodNames = cls.isEnum()
? new String[] {"fromString", "fromValue", "valueOf"}
: new String[] {"valueOf", "fromString"};
for (String mName : methodNames) {
result = evaluateFactoryMethod(value, cls, pType, mName);
if (result != null) {
break;
}
}
The problem is that JAXB generated Enum doesn't returns null, but throws IllegalArgumentException in fromValue() if argument is in wrong case.
As a result following method throws IllegalArgumentException:
@GET
@Path("/enum/")
Response checkEnum(@QueryParam("car") CarType car);
for generated bean:
@XmlRootElement(name = "Car")
@XmlType(name = "carType")
@XmlEnum
public enum CarType {
@XmlEnumValue("Audi")
AUDI("Audi"),
@XmlEnumValue("Golf")
GOLF("Golf"),
BMW("BMW");
private final String value;
CarType(String v) {
value = v;
}
public String value() {
return value;
}
public static CarType fromValue(String v) {
for (CarType c: CarType.values()) {
if (c.value.equals(v)) {
return c;
}
}
throw new IllegalArgumentException(v);
}
}
> JAXB generated Enum throws IllegalArgumentException by unmarshalling as @QueryParam
> -----------------------------------------------------------------------------------
>
> Key: CXF-5722
> URL: https://issues.apache.org/jira/browse/CXF-5722
> Project: CXF
> Issue Type: Bug
> Components: JAX-RS
> Affects Versions: 3.0.0-milestone2
> Reporter: Andrei Shakirin
> Assignee: Andrei Shakirin
>
> By processing request with Query parameter, InjectionUtils tries to recognize and instantiate parameter class.
> In case of Enum parameter class, InjectionUtils.handleParameter() method calls in loop following methods: "fromString", "fromValue", "valueOf" using reflection. If method returns null, it tries the next one:
> if (result == null) {
> // check for valueOf(String) static methods
> String[] methodNames = cls.isEnum()
> ? new String[] {"fromString", "fromValue", "valueOf"}
> : new String[] {"valueOf", "fromString"};
> for (String mName : methodNames) {
> result = evaluateFactoryMethod(value, cls, pType, mName);
> if (result != null) {
> break;
> }
> }
> The problem is that factory methods in JAXB generated Enum behaves differently:
> - valueOf accepts enum identifier (not value)
> - fromValue accepts enum value
> Both methods throws IllegalArgumentException by worng argument and do not return null, how current code expecting.
> As a result following method throws IllegalArgumentException:
> 1) method:
> @GET
> @Path("/enum/")
> Response checkEnum(@QueryParam("car") CarType car);
> 2) generated enum:
> @XmlRootElement(name = "Car")
> @XmlType(name = "carType")
> @XmlEnum
> public enum CarType {
> @XmlEnumValue("Audi")
> AUDI("Audi"),
> @XmlEnumValue("Golf")
> GOLF("Golf"),
> BMW("BMW");
> private final String value;
> CarType(String v) {
> value = v;
> }
> public String value() {
> return value;
> }
> public static CarType fromValue(String v) {
> for (CarType c: CarType.values()) {
> if (c.value.equals(v)) {
> return c;
> }
> }
> throw new IllegalArgumentException(v);
> }
> }
> 3) call:
> customerService.checkEnum(CarType.AUDI);
--
This message was sent by Atlassian JIRA
(v6.2#6252)