Hi Ram,
The code for setMapping is as follows:
<snip>
if (_cdResolver == null)
_cdResolver = new ClassDescriptorResolverImpl();
_cdResolver.setMappingLoader((XMLMappingLoader)mapping.getResolver(Mapping.XML));
</snip>
That's all!
Perhaps Mapping#getResolver is not thread safe.
Upon it's first call it creates the appropriate MappingResolver and
caches it. The method is not synchronized. However subsequent calls to
Mapping#getResolver will returned the cached MappingResolver.
I don't have time right now to look into the issue, but if you've
tracked it down to the setMapping method, than it's probably
Mapping#getResolver which is the culprit.
When I have some time, I will run your test case. Currently I have a
lot on my plate..I don't scale very easily.
Thanks,
--Keith
Ram Chidambaram wrote:
>
> Hi Keith,
>
> I'm loading the mapping once and caching this Mapping object.
>
> I do create a new Marshaller everytime and this Marshaller is not shared
> accoss threads.
>
> The following is the section of code...
>
> //get the Mapping object from cache
> Mapping mapping = getMappingfromCache( mappingFileName );
>
> StringWriter writer = new StringWriter();
>
> Marshaller marshaller = new Marshaller( writer );
> marshaller.setMapping( mapping );
> marshaller.setMarshalAsDocument( asDocument );
> marshaller.marshal( object );
>
> return writer.toString();
>
> Looks like there is a problem with 'setMapping()' method. When I call this
> method on different Marshaller objects (but same cached mapping) in
> different threads, I get the default Castor behaviour (instead of using the
> mapping file xml-bind name). No exception is thrown here.
>
> Also, UnMarshaller seems to have a problem as well. It throws an exception.
> org.xml.sax.SAXException: The class for the root element 'Order' could not
> be found.
>
> I have been able to recreate this problem with the example provided with
> Castor (Order/Item example). The workaround for this problem is to put
> 'setMapping()' method and 'new UnMashaller(mapping)' constructor in a
> syncronized block. This seems to fix the problem (both with Marshaller and
> UnMarshaller).
>
> Any other suggestions?
>
> Here is the Tester we used to recreate the problem:
> ---------------------------------------------------------
> import java.io.*;
> import org.exolab.castor.mapping.Mapping;
> import org.exolab.castor.mapping.MappingException;
>
> import org.exolab.castor.xml.Unmarshaller;
> import org.exolab.castor.xml.Marshaller;
>
> import java.io.IOException;
> import java.io.FileReader;
> import java.io.OutputStreamWriter;
>
> import org.xml.sax.InputSource;
> import java.util.*;
>
> /**
> * Insert the type's description here.
> * Creation date: (2001/12/06 12:59:10 PM)
> * @author: Edmund Leung
> */
> public class Tester implements Runnable {
>
> static Mapping m_mapping;
>
> static {
>
> try {
> m_mapping = new Mapping();
>
> // 1. Load the mapping information from the file
> m_mapping.loadMapping("mapping.xml");
>
> } catch (Throwable e) {
> e.printStackTrace();
> }
>
> }
> /**
> * Insert the method's description here.
> * Creation date: (2002/01/30 1:58:45 PM)
> */
> public Tester() {}
>
> /**
> * Starts the application.
> * @param args an array of command-line arguments
> */
> public static void main(java.lang.String[] args) {
>
> try {
>
> Tester[] testers = new Tester[100];
>
> for (int i = 0; i < testers.length; i++) {
>
> testers[i] = new Tester();
>
> }
>
> for (int i = 0; i < testers.length; i++) {
>
> new Thread(testers[i]).start();
>
> }
>
> } catch (Exception e) {
> e.printStackTrace();
> }
>
> }
> public void run() {
>
> try {
>
> try {
>
> Unmarshaller unmar = new Unmarshaller(m_mapping);
> MyOrder order =
> (MyOrder) unmar.unmarshal(new
> InputSource(new FileReader("order.xml")));
>
> // 3. Do some processing on the data
> float total = order.getTotalPrice();
> System.out.println("Order total price = " + total);
> order.setTotal(total);
>
> } catch (Exception e) {
> e.printStackTrace();
> }
>
> try {
>
> StringWriter writer = new StringWriter();
>
> Marshaller marshaller = new Marshaller(writer);
> marshaller.setMapping(m_mapping);
> marshaller.setMarshalAsDocument(false);
> marshaller.marshal(m_order);
>
> System.out.println(writer.toString());
>
> } catch (Exception e) {
> e.printStackTrace();
> }
>
> } catch (Exception e) {
> e.printStackTrace();
> }
> }
>
> }
>
> --------------------------------------------------------------
>
> Thanks,
> Ram.
>
> -----Original Message-----
> From: Keith Visco [mailto:[EMAIL PROTECTED]]
> Sent: 2002/01/30 11:44 AM
> To: [EMAIL PROTECTED]
> Subject: Re: [castor-dev] Castor XML --> Marshalling problem.
>
> Ram Chidambaram wrote:
> >
> > Hi Arnaud,
> >
> > Thanks for you reply. I'm using a mapping file which defines the
> 'bind-xml'
> > + 'name' to define the name of elements and attributes (also
> 'map-to'->'xml'
> > for the root element).
> >
> > Does 'castor.properties' apply for this scenario as well?
>
> No. castor.proprerties naming is only for introspection or when a name
> isn't specified in the mapping file.
>
> >
> > Also, why am I seeing this inconsistent behaviour (works most of the times
> > and occasionally (with heavy load), I see the output XML created using the
> > default castor behaviour instead of using the mapping file)
>
> Once the Mapping is loaded you should be able to access it as many times
> as you want, since the Marshaller doesn't save any information in the
> mapping, it just gets information from it.
>
> The Marshaller is not meant to be shared...make sure you always create a
> new one.
>
> Make sure you don't call the static Marshaller#marshal methods as these
> methods won't have access to any mapping file that has been set.
>
> --Keith
>
> >
> > Thanks for your time.
> >
> > Ram.
> >
> > -----Original Message-----
> > From: Arnaud Blandin [mailto:[EMAIL PROTECTED]]
> > Sent: 2002/01/30 10:09 AM
> > To: [EMAIL PROTECTED]
> > Subject: Re: [castor-dev] Castor XML --> Marshalling problem.
> >
> > Hi Ram,
> >
> > You should take a look at the castor.properties file:
> >
> > # Defines the Naming "style" or conventions to use when
> > # creating XML names from Java class or field names.
> > # Valid values are as follows:
> > # -----------------------------------------------------------------
> > # lower (default) | All names are lowercase with hyphens
> > # | separating words.
> > # |
> > # | Example: personInfo = person-info
> > # -----------------------------------------------------------------
> > # mixed | All names are mixed case, with Uppercase
> > # | character as the first letter of a new word.
> > # |
> > # | Example: personInfo = personInfo
> > # | Example: FooBar = fooBar
> > # -----------------------------------------------------------------
> > # {Any ClassName} | Any Class which implements
> > # | org.exolab.castor.xml.XMLNaming
> > # -----------------------------------------------------------------
> > #
> > # By default all names are treated as the "lower" option.
> > # To preserve the Java mixed-case conventions simply
> > # uncomment the following line.
> > #
> > #org.exolab.castor.xml.naming=mixed
> >
> > Arnaud
> >
> > > -----Original Message-----
> > > From: Ram Chidambaram [mailto:[EMAIL PROTECTED]]
> > > Sent: Tuesday, January 29, 2002 11:46 PM
> > > To: [EMAIL PROTECTED]
> > > Subject: [castor-dev] Castor XML --> Marshalling problem.
> > >
> > > Hello All,
> > >
> > > I'm using Castor 0.9.3 for mapping XML to java objects and vice versa.
> > It
> > > has been working really well until recently I hit a problem with
> > > marshalling
> > > a java object to XML.
> > >
> > > I'm currently caching the Mapping object (after loading the mapping
> > file).
> > >
> > > Whenever I need to create an XML from a Java Object, I create a new
> > > Marshaller(with a new writer) and set the mapping to the cached
> > Mapping
> > > object and then call the marshal() method. I'm using this in a multi
> > > threaded environment.
> > >
> > > This approach seemed to work for most cases. Just recently I have hit
> > a
> > > problem with the created XML not reflecting the Mapping file(for XML
> > > tags),
> > > but with the default XML tags from the java object.
> > >
> > > eg.
> > >
> > > Based on the mapping file, If the excepted XML was something like..
> > >
> > > <OrderInfo>
> > > <OrderType>
> > > .....
> > > </OrderInfo>
> > >
> > > and my java Object 'OrderInfo' had a 'set' and 'get' method for
> > OrderType
> > > (getOrderType, setOrderType..) etc.
> > >
> > > My out XML is sometimes,
> > >
> > > <order-info>
> > > <order-type>
> > > .....
> > > </order-info>
> > >
> > >
> > > I'm not sure why this is happening suddenly. Could this be related to
> > > caching of the Mapping object ?
> > > I tried going through the mailing list to see if Mapping was thread
> > > safe...but couldn't find any info on this.
> > >
> > > Thanks for all you help.
> > >
> > > Ram.
> > >
> > > -----------------------------------------------------------
> > > If you wish to unsubscribe from this mailing, send mail to
> > > [EMAIL PROTECTED] with a subject of:
> > > unsubscribe castor-dev
> >
> > -----------------------------------------------------------
> > If you wish to unsubscribe from this mailing, send mail to
> > [EMAIL PROTECTED] with a subject of:
> > unsubscribe castor-dev
> >
> > -----------------------------------------------------------
> > If you wish to unsubscribe from this mailing, send mail to
> > [EMAIL PROTECTED] with a subject of:
> > unsubscribe castor-dev
>
> -----------------------------------------------------------
> If you wish to unsubscribe from this mailing, send mail to
> [EMAIL PROTECTED] with a subject of:
> unsubscribe castor-dev
>
> -----------------------------------------------------------
> If you wish to unsubscribe from this mailing, send mail to
> [EMAIL PROTECTED] with a subject of:
> unsubscribe castor-dev
-----------------------------------------------------------
If you wish to unsubscribe from this mailing, send mail to
[EMAIL PROTECTED] with a subject of:
unsubscribe castor-dev