Details
-
Type:
Bug
-
Status:
Closed
-
Priority:
Blocker
-
Resolution: Fixed
-
Affects Version/s: 0.9.9 M1
-
Fix Version/s: 0.9.9.1
-
Component/s: XML code generator
-
Labels:None
-
Environment:Windows 2000
-
Number of attachments :3
Description
steps to reproduce:
1. create a directory c:\newcastor and unzip castor-0.9.9M1.zip in it. This will create the sub directory castor-0.9.9M1.
2. copy the attached JAR files to that sub directory.
3. copy the attached myjavac.bat and resdesc.xsd to c:\newcastor.
4. edit myjavac.bat if needed to point to a JDK 1.4.2_06 home directory.
5. run myjavac.bat. you will get the following error.
C:\newcastor>myjavac
CP c:\newcastor\castor-0.9.9M1\castor-0.9.9M1.jar;c:\newcastor\castor-0.9.9M1\sax.jar;c:\newcastor\castor-0.9.9M1\jaxpap
i.jar;c:\newcastor\castor-0.9.9M1\xercesImpl.jar;c:\newcastor\castor-0.9.9M1\commons-logging-1.0.4.jar
0.9.9M1 [20050824.164428]
.\com\geobot\ResourceDesc.java:102: unmarshal(java.io.Reader) in com.geobot.ResourceDesc cannot override unmarshal(java.
io.Reader) in com.geobot.ResourceDescriptionType; attempting to use incompatible return type
found : com.geobot.ResourceDesc
required: com.geobot.ResourceDescriptionType
public static com.geobot.ResourceDesc unmarshal(java.io.Reader reader)
^
1 error
-
Hide
- jarfiles.zip
- 16/Sep/05 12:56 PM
- 939 kB
- Bill Leng
-
- xercesImpl.jar 952 kB
- jaxp-api.jar 26 kB
- sax.jar 26 kB
- commons-logging-1.0.4.jar 35 kB
-
- myjavac.bat
- 16/Sep/05 12:56 PM
- 0.7 kB
- Bill Leng
-
- resdesc.xsd
- 16/Sep/05 12:56 PM
- 3 kB
- Bill Leng
Activity
ok.. after mode digging - it's apparently due to a change in the return type
of the of the unmarshal method as created by the createUnmarshalMethods
method of the org.exolab.castor.builder.SourceFactory.
Until 0.9.7 unmarshal's return type was java.lang.Object whereas in 0.9.9 it is
made to be (effectively) the superclass of the unmarshaled class which
effectively breaks the resulting code
lukasz
pre 0.9.7, such as 0.9.5?, it returns the specific type. the root cause is, the unmarshal method should ONLY be generated on the most specific class (class that does not have subclass). this is the behaviour pre 0.9.9. starting from 0.9.9, both superclass and subclass have the unmarshal method generated. each returns its own type. this caused the compile failure.
> pre 0.9.7, such as 0.9.5?
I've just compared what's generated by 0.9.9 & 0.9.7
> the unmarshal method should ONLY
nope, that's not the case - in both 0.9.9 & 0.9.7 unmarshal shows up in all the classes, not only in
the superclass....
lukasz
I have traced the problem to org.exolab.castor.builder.SourceFactory version 1.21 Which was added in the 0.9.9 branch.
Keith applied a patch to use more concrete return type than java.lang.Object in the generated unmarshal method.
If possible, please fix this for the next release, as it makes code generated by the source generator uncompilable!
Thanks,
Matt
All,
I've checked in a patch that improves my previous patch in SourceFactory 1.21, please give this a shot.
Thanks for everyone's feedback and patience.
Thanks for the quick fix, but it looks like perhaps you forgot to check a file in . . . in SGTypes there is no PropertyChangeSupport defined.
compile.xml:
[javac] Compiling 1 source file to /home/matt/castor-0.9.9/build/classes
[javac] /home/matt/castor-0.9.9/src/main/org/exolab/castor/builder/SourceFactory.java:808: cannot resolve symbol
[javac] symbol : variable PropertyChangeSupport
[javac] location: class org.exolab.castor.builder.SGTypes
[javac] JField field = new JField(SGTypes.PropertyChangeSupport, vName);
[javac] ^
[javac] 1 error
Matt
Matt,
I didn't make the changes related to PropertyChangeSupport. Those were checked in by Andrew Fawcett in version 1.23. But his changes work fine for me, so I'm not sure what the issue could be for you.
--Keith
Keith, what shell we do with this issue as Werner wants to release 0.9.9.1? Mark it as resolved?
And more importantly, what to do with Matt's comment (which btw seems to be related to a different bug Andrew has checked in recently ?
Matt, is it safe to assume that your comment was meant to go elsewhere ?
I'm going to mark it as fixed as the steps to reproduce no longer reproduce the issue for me. Matt's last comment seems to be related to perhaps an incomplete checkout. Maybe he didn't check out the code using the -d flag or something. I don't see the error he is seeing and Andrew's code compiles fine for me.
So if the code is compiling for you guys I think we can ignore Matt's latest comments.
As for this bug, I believe it's now fixed.
I checked out 0.9.9.1 and tried again. This bug did get fixed. However, a new bug is introduced, I believe. Below is the generated Java source code. In class ResourceDesc, the static unmarshal method returned ResourceDescriptionType instead of ResourceDesc. If we cannot return the correct type, this is, in my opinion, worse than java.lang.Object. At lease java.lang.Object is uniform and consistent, though not convinient.
public class ResourceDesc extends ResourceDescriptionType
implements java.io.Serializable
{
/**
- Method unmarshal
- @param reader
- @return ResourceDescriptionType
*/
public static com.geobot.ResourceDescriptionType unmarshal(java.io.Reader reader)
throws org.exolab.castor.xml.MarshalException, org.exolab.castor.xml.ValidationException
{ return (com.geobot.ResourceDescriptionType) Unmarshaller.unmarshal(com.geobot.ResourceDesc.class, reader); }//-- com.geobot.ResourceDescriptionType unmarshal(java.io.Reader)
}
Keith can you please verify the issue Bill reported. Werner have stopped 0.9.9.1 release according to this problem.
Bill, Ralf,
It's not the wrong type. Since ResourceDesc extends ResourceDescriptionType it's returning the least-common denomator. It's illegal in Java to change the return type of a method that is inherited. So the user is simply going to have to cast if they want the more specific type. This is much better than simply returning java.lang.Object and it is the desired behavior in my opinion. If it always returned java.lang.Object the user would always require a cast no matter what. At least in this case the user can use the methods provided by the superclass without needing the cast. And for types which do not extend something else you get the correct class type as the return type.
--Keith
Keith,
I think there is a better solution to this problem. That is to suppress the unmarshal method on the super class (ResourceDescriptionType) and let the most specific class (ResourceDesc) return its correct type which is (ResourceDesc). In fact, this is the behaviour upto 0.9.5. Up to 0.9.5, the super class is abstract and the unmarshal method does not get generated. When a user generates java source files from a XML schema, what he really interested in is whatever in the schema. In this case, it is ResourceDesc. ResourceDescDescriptionType is really something within the boundary of castor and the user really don't care about it. If we cannot do that, I still think java.lang.Object is better because the user has to cast anyway. It does not make difference to cast from ResourceDescriptionType or from java.lang.Object.
Keith, Bill, I'd love to see you guys coming to an agreement (rather sooner than later), as I'd like to see a possible fix be integrated and shipped with the 0.9.9.1 release.
Hi Werner,
Since the code compiles this bug should be closed. I do believe the implementation and current behavior is the correct one, however since Bill feels differently perhaps a new request can be open that asks to allow for greater control over the generated source code. The Castor framework will work just fine whether java.lang.Object is used as the return type, or whether a more concrete class name is used. It will also work just fine if complex types didn't have the unmarshalmethod so that subclasses don't have to use the superclass type in the unmarshal methods return signature. Obviously this is a "user-preference" type of issue at this point. It really depends on the user.
In earlier versions of Castor we always used the most specific class name, but this of course caused code to be uncompilable when it extended another class. So the first fix was to use java.lang.Object. Over the course of the years we had numerous requests that we should try and use the most specific class name we could that wouldn't cause compilation problems. Which is what I tried to implement in 0.9.6 and later, though there was a bug in certain cases as described in this bug report which has subsequently been fixed with my patch. What Bill is asking for may be a perfectly reasonable request, however there are just as many people out there that will want the code to be generated as it is right now as there are who might want it generated the way Bill is asking for.
So it simply comes down to a matter of preference and to add additional ways to configure the source generator. Since this is the way I originally intended my code to work, I prefer to leave my patch in place. An enhancement request can be opened up requesting greater flexibility in controlling the generated code.
Thanks,
--Keith
Sounds fine to me, especially with regards to raising new issues as a follow-up.
Hopefully someone still sees this... I'm wondering if this is still an issue? I'm getting the same error, under 0.9.9.1.
... getContent() in <class> cannot override getContent() in <class>; attempting to use incompatible return type
found: <Type>
required: String
If you want an excellent test case for Castor to generate against some large, complex XML, please try generating the ACORD Property and Casualty/Surety XML standard - http://www.acord.org/standards/PandCXMLSpecs.aspx. (It's not working for me, hence this posting.)
Hi Marc, your comment has been recognized even if the issue has been closed. Would you mind to create a new one on your findings and if possible attach a small test case that points us to the area where you have problems with. Having said that I'm not one of the XML gurus here but to me it sounds to be something different then the original problem Bill had.
uh... it seems to be a generic problem with nested named complexType
lukasz