Hello,

 

I have just updated my castor version from 1.0 to 1.3, and I encountered
a problem with the Unmarshaller when using the same mapping object in
different threads.

 

In my current application, I noticed this as one of my objects was only
partially unmarshalled (it was missing some of the attributes in the
xml-file). This object was unmarshalled at the same time as another
object, both with separate Unmarshalle-objects, but using the same
Mapping-object. 

 

First I tried to reproduce this behavior in a cleaner environment,
without luck. I guess it is a timing issue, which I cannot reproduce
under my artificial test-environment. Then I tried reproduce it with
breakpoints in my debugger and I managed to create a different bug, with
an exception:

 

org.exolab.castor.xml.MarshalException: Stream closed

      at
org.exolab.castor.xml.Unmarshaller.unmarshal(Unmarshaller.java:757)

      at
org.castor.mapping.MappingUnmarshaller.loadMappingInternal(MappingUnmars
haller.java:247)

     at
org.castor.mapping.MappingUnmarshaller.getMappingLoader(MappingUnmarshal
ler.java:155)

     at
org.castor.mapping.MappingUnmarshaller.getMappingLoader(MappingUnmarshal
ler.java:130)

      at
org.exolab.castor.xml.Unmarshaller.setMapping(Unmarshaller.java:525)

      at test.DBConnectionCfg.unmarshal(DBConnectionCfg.java:111)

      at test.DBConnectionCfg.unmarshal(DBConnectionCfg.java:121)

      at test.Test$2.run(Test.java:41)

      at java.lang.Thread.run(Thread.java:619)

 

The critical region is:

 

    private void loadMappingInternal(final Mapping mapping, final
DTDResolver resolver,

                                     final InputSource source)

    throws MappingException {

        // Clear all the cached resolvers, so they can be reconstructed
a

        // second time based on the new mappings loaded

        _registry.clear();

        

        Object id = source.getSystemId();

        if (id == null) { id = source.getByteStream(); }

        if (id != null) {

            //check that the mapping has already been processed

            if (mapping.processed(id)) { return; } 

        // *** Critical, error is produced if both 

        // *** threads reach this point at the same time

 

            //mark the mapping as being processed

            mapping.markAsProcessed(id);

        }

 

 

This is not the same issue which I discovered in my application, and I
could not reproduce this error without the debugger, but they are
somehow related. When I put a synchronized-block over
Unmarshaller.setMapping(), my original issue disappeared. I tried to
find the cause of my issue, but I this is the first time I have looked
into the source code, and I really don't know where to look.

 

So, should I report this as a bug?

 

Best regards,

Mads Stavang

Reply via email to