castor
  1. castor
  2. CASTOR-1492

Reuse of mapping objects and Unmarshaller object to unmarshal causing failures..

    Details

    • Type: Bug Bug
    • Status: Closed Closed
    • Priority: Minor Minor
    • Resolution: Fixed
    • Affects Version/s: 1.0.2
    • Fix Version/s: 1.0.3
    • Component/s: None
    • Labels:
      None
    • Number of attachments :
      1

      Description

      We're having failures on code that used to work in 1.0-M1 in the way that XML mappings are handled.

      Specifically:

      Stream closed
      at org.exolab.castor.xml.Unmarshaller.unmarshal(Unmarshaller.java:717)
      at org.castor.mapping.MappingUnmarshaller.loadMappingInternal(MappingUnmarshaller.java:202)
      at org.castor.mapping.MappingUnmarshaller.getMappingLoader(MappingUnmarshaller.java:124)
      at org.castor.mapping.MappingUnmarshaller.getMappingLoader(MappingUnmarshaller.java:99)
      at org.exolab.castor.xml.Unmarshaller.setMapping(Unmarshaller.java:484)

      When a Mapping object is loaded for a given mapping file, we cache that object and keep it for the runtime's lifetime, or until the file timestamp is changed out from under us.

      To unmarshal, we do:

      org.exolab.castor.xml.Unmarshaller unm = new org.exolab.castor.xml.Unmarshaller();
      unm.setMapping(mapping);
      unm.setValidation(validate);
      unm.setIgnoreExtraAttributes(ignoreExtraAttributes);
      unm.setIgnoreExtraElements(ignoreExtraElements);
      unm.setReuseObjects(reuseObjects);
      unm.setWhitespacePreserve(preserveWhitespace);

      As you can see from the above code, we create a new Unmarshaller object, and set the mapping. That mapping object that we set never changes for instances of the same file; and we're getting failures on subsequent calls to that mapping object. The first time succeeds; the second time throws the above exception.

      Note that it's created from a stream, and that stream is closed and gone. It mustn't be referenced again - yet somehow, it seems to want to reload itself each time.

        Activity

        Hide
        Gregory Block added a comment -

        Additional note: The creation of a mapping, by us, is done within a CachedMapping object, which does the heavy lifting of representing a cacheable entry with the associated date of the source it came from, for integrity validation.

        Our code for doing so throws a MappingException in the constructor; we do that because we want to throw the underlying exception thrown by Castor.

        Castor throws one at loadMapping(xxxxx) in 1.0.1; it doesn't appear to in 1.0.2 - Eclipse warns us that the API has lost the exception, on at least the one we're calling.

        That may be important, and related.

        Show
        Gregory Block added a comment - Additional note: The creation of a mapping, by us, is done within a CachedMapping object, which does the heavy lifting of representing a cacheable entry with the associated date of the source it came from, for integrity validation. Our code for doing so throws a MappingException in the constructor; we do that because we want to throw the underlying exception thrown by Castor. Castor throws one at loadMapping(xxxxx) in 1.0.1; it doesn't appear to in 1.0.2 - Eclipse warns us that the API has lost the exception, on at least the one we're calling. That may be important, and related.
        Hide
        Gregory Block added a comment -

        Workaround: We've changed over to using setReslover() instead of setMapper() on the unmarshaller, with Ralf's help from IRC. The following changes were made in our code to work around this:

        1) Instead of loading the mapper, do this in our cached mapping representation:
        this.cdResolver = (XMLClassDescriptorResolver) ClassDescriptorResolverFactory.createClassDescriptorResolver(BindingType.XML);
        MappingUnmarshaller mum = new MappingUnmarshaller();
        MappingLoader resolver = mum.getMappingLoader(mapping, BindingType.XML);
        this.cdResolver.setMappingLoader(resolver);

        2) At the unmarshaller/marshaller, do this:
        org.exolab.castor.xml.Unmarshaller unm = new org.exolab.castor.xml.Unmarshaller();
        unm.setResolver(cdResolver);

        Works as well as the original, and is probably even faster, I'll bet.

        Show
        Gregory Block added a comment - Workaround: We've changed over to using setReslover() instead of setMapper() on the unmarshaller, with Ralf's help from IRC. The following changes were made in our code to work around this: 1) Instead of loading the mapper, do this in our cached mapping representation: this.cdResolver = (XMLClassDescriptorResolver) ClassDescriptorResolverFactory.createClassDescriptorResolver(BindingType.XML); MappingUnmarshaller mum = new MappingUnmarshaller(); MappingLoader resolver = mum.getMappingLoader(mapping, BindingType.XML); this.cdResolver.setMappingLoader(resolver); 2) At the unmarshaller/marshaller, do this: org.exolab.castor.xml.Unmarshaller unm = new org.exolab.castor.xml.Unmarshaller(); unm.setResolver(cdResolver); Works as well as the original, and is probably even faster, I'll bet.
        Hide
        Werner Guttmann added a comment -

        Great. I was just about to suggest the same, as that's what ClassDescriptorResolver was designed for. I guess what needs to be done is to put the knowledge that exists here (and in some brains) into writing and make it available on the web site.

        Show
        Werner Guttmann added a comment - Great. I was just about to suggest the same, as that's what ClassDescriptorResolver was designed for. I guess what needs to be done is to put the knowledge that exists here (and in some brains) into writing and make it available on the web site.
        Hide
        Werner Guttmann added a comment -

        As commented upon above, I'd like to see this resolved through additional documentation.

        Show
        Werner Guttmann added a comment - As commented upon above, I'd like to see this resolved through additional documentation.
        Hide
        Werner Guttmann added a comment -

        Initail (and final) patch, adding an XML best practice document to the Castor XML section of the HTML docs.

        Show
        Werner Guttmann added a comment - Initail (and final) patch, adding an XML best practice document to the Castor XML section of the HTML docs.

          People

          • Assignee:
            Werner Guttmann
            Reporter:
            Gregory Block
          • Votes:
            1 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: