Open glassfishrobot opened 18 years ago
Reported by mosh
kohsuke said: I think this issue has been fixed some time ago.
mosh said: I dont think so. At leat not with the version from 18/10/2006. Look at the the following code at ClassInfoImp.java:
// Match getter with setters by comparing getter return type to setter param
for (Map.Entry<String,M> entry : getters.entrySet()) {
String propName = entry.getKey();
M getter = entry.getValue();
List
{ //no matching setter continue; }
allSetters is only from this class and not from its super-classes (unless the super-class is @XmlTransient).
I've created a function that also seeks for setters in the super-class. I can submit it as a patch. What is the procedure?
Thanks! Mosh
//////////////////////////////////// // This is the method BTW:
List
Collection<? extends M> methods = nav().getDeclaredMethods(c); for( M method : methods ) { if(nav().isBridgeMethod(method)) continue; // ignore
String name = nav().getMethodName(method); int arity = nav().getMethodParameters(method).length;
// TODO - is needed???? if(nav().isStaticMethod(method))
{ ensureNoAnnotation(method); continue; }
// is this a set method? String propNameFromSetter = getPropertyNameFromSetMethod(name); if(propNameFromSetter!=null && arity==1) { if(propNameFromSetter.equals(propName)){ if(propSetters == null)
{ propSetters = new ArrayList
propSetters.add(method); } } }
if(propSetters != null)
{ return propSetters; }
else
{ // If we havent found the getter - going up to its super-class C sc = nav().getSuperClass(c); if((sc==null) || (sc==Object.class)) return null; else return findSetterInSuperClass(sc,propName); }
}
kohsuke said: Yes, if you can provide us a patch, that would be great!
See https://glassfish.dev.java.net/public/GovernancePolicy.html#SCA_Policy and please send us the SCA so that we can accept a patch. Otherwise, just go create a patch and post the diff to the issue please.
You'll only need to make sure that the patch will work for you. We'll run it through the tests on our side as well.
rebeccas said: Implementation complete.
desruisseaux said: Is this improvement really done? I tried the following code snippet. It work well if the argument type of the setValue method is Double, but doesn't work anymore if I relax it to Number:
import java.io.*;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.annotation.*;
@XmlRootElement
public class SetterWithParentClass {
private double value;
@XmlElement
public Double getValue() {
return value;
}
// Argument type should be Double - testing with a relaxed type.
public void setValue(Number n) {
value = n.doubleValue();
}
public static void main(String[] args) throws Exception {
JAXBContext c = JAXBContext.newInstance(SetterWithParentClass.class);
SetterWithParentClass test = new SetterWithParentClass();
test.value = 3;
StringWriter out = new StringWriter();
c.createMarshaller().marshal(test, out);
String xml = out.toString();
System.out.println(xml);
// Unmarshall
StringReader in = new StringReader(xml);
test = (SetterWithParentClass) c.createUnmarshaller().unmarshal(in);
System.out.println("value = " + test.value);
}
}
Output is (adding indentation for clarity):
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<setterWithParentClass>
<value>3.0</value>
</setterWithParentClass>
value = 0.0
I would have hopped a value of 3.0, as we get when the setter method is setValue(Double).
yaroska said: I think this is not a valid issue.
If JAXB is working with JavaBeans-style classes its expected that properties should have getters and setters of the same type. Which is not true in this case.
desruisseaux said: This issue is not incompatible with JavaBeans-style classes. It is a relaxed interpretation - not everyone want the JavaBeans constraints. In my case, I have about 100 classes derived from the ISO 19115 international standard, and I would like to design the API for ease of use rather than JAXB constraints. In its current form, the API forces the users to perform themselves a lot of wrapping toward some specialized interfaces (InternationalString - which is specific to the project) while the setters could accept a more generic interface (CharSequence - which would allow the users to specify a plain String) and do the wrapping themselves.
If the JavaBeans restriction is still considered necessary, some annotation allowing us to specify that a method is the setter of a property would be appreciated. Maybe we could reuse the current tt>@Element</tt annotation, which would be allowed to be applied to setter methods.
An alternative is to declare setter methods twice: one JavaBeans-compliant method and one convenience method. But this approach bloat the API and binary file for few purpose. I currently don't do that since I think it would bloat too much a collection of classes of the size of ISO 19115.
This issue was imported from java.net JIRA JAXB-251
The problem Im having is that JAXB doesnt recognize a setter for a property if the setter parameter is a not exactly of the same as the parameter of the getter but rather a "parent-class".
for Example, when i have the following classes:
class A{ }
class B extends A{ A parent; void setParent(A parent)
{...} abstract A getParent();
}
class C extends B{ @XMLIDREF B getParent(){...}
}
JAXB doesnt recognize the setter inside A as the right setter for "parent".
After going over the JAXB source code i found that the cause is that ClassInfoImpl.collectGetterSetters() method has the following code:
========================= for (M setter : propSetters) { T setterType = nav().getMethodParameters(setter)[0]; if (setterType.equals(getterType)) { setters.put(propName, setter); break; } }
Since setterType.equals(getterType)==false, JAXB wont find setParent() as a setter.
Environment
Operating System: All Platform: All URL: http://forums.java.net/jive/thread.jspa?threadID=18616&tstart=0
Affected Versions
[2.1]