You are viewing a plain text version of this content. The canonical link for it is here.
Posted to soap-user@ws.apache.org by "Hansen, Richard" <Ri...@westgroup.com> on 2001/08/21 21:30:56 UTC

FW: DateSerializer bug fix

I hope someone in the Dev group will check this out an commit the changes. I
got little response on the Dev list, so in the mean time I will post to the
larger group here.

Rick Hansen

-----Original Message-----
From: Hansen, Richard 
Sent: Friday, August 17, 2001 10:15 AM
To: 'soap-dev@xml.apache.org'
Subject: DateSerializer bug fix


It appears that the DateSerializer does need some synchronized blocks. I
verified that the Date output from unmarshall() is not always equivalent to
the string value input to unmarshall(). So, I placed synchronized blocks
around the SimpleDateFormat.format() calls. This seems to have fixed the
problem. I did not explore how serializers are created and used. I assume
they shared and that is why there are synchronization issues?

I looked at most of the serializers/deserializers in the
org.apache.soap.encoding.soapenc package and Date and Calendar seem to be
the only ones with member variables. I think Calendar has the same problem
as it also creates a SimpleDateFormat object.

I have marked my chages below, so I hope someone will commit them. If there
is a better way to fix this I would like to hear about it.

Thanks

Rick Hansen

  public void marshall(String inScopeEncStyle, Class javaType, Object src,
                       Object context, Writer sink, NSStack nsStack,
                       XMLJavaMappingRegistry xjmr, SOAPContext ctx)
                        throws IllegalArgumentException, IOException
  {
    if(!javaType.equals(java.util.Date.class))
    {
      throw new IllegalArgumentException("Can only serialize java.util.Date
instances");
    }
    nsStack.pushScope();
    if(src!=null)
    {
      SoapEncUtils.generateStructureHeader(inScopeEncStyle,
                                           javaType,
                                           context,
                                           sink,
                                           nsStack,xjmr);
	// ************ START CHANGE
      String fdate;			
      
      synchronized(sdf) {
        fdate=sdf.format((Date)src);
      }
	// ************ END CHANGE
      sink.write(fdate);
      sink.write("</" + context + '>');
    }
    else
    {
      SoapEncUtils.generateNullStructure(inScopeEncStyle,
                                           javaType,
                                           context,
                                           sink,
                                           nsStack,xjmr);
    }
    nsStack.popScope();
  }

  public Bean unmarshall(String inScopeEncStyle, QName elementType, Node
src,
                         XMLJavaMappingRegistry xjmr, SOAPContext ctx)
                          throws IllegalArgumentException
  {
    Date date=null;
    Element root = (Element)src;
    String value = DOMUtils.getChildCharacterData(root);
    if(value!=null && !((value=value.trim()).equals("")))
    {
      try
      {
        // ************ START CHANGE
        synchronized(sdf) {
          date=sdf.parse(value);
        }
       // ************ END CHANGE 
      }
      catch (ParseException pe)
      {
        try
        {
          // ************ START CHANGE 
          synchronized(sdf_ms) {
            date=sdf_ms.parse(value);
          }
          // ************ END CHANGE
        }
        catch (ParseException pe2)
        {
          throw new IllegalArgumentException("String represents no valid " +
                                             "Date for this Deserializer; "
+
                                             "try " + sdf.toPattern() +
".");
        }
      }
    }
    
    return new Bean(java.util.Date.class,date);
  }
}

> 
> Before I dive into any code changes, has anyone else had 
> problems with the
> DateSerialzier? I have a SOAP method that has a Date as one 
> of the params.
> When it gets two simultaneous calls the dates seem to be 
> wrong, not the same
> as what was passed to call.invoke(). As far as I can tell 
> good dates are
> going in and bad dates are getting passed into my Soap method 
> by the rpc
> router.
> 
> I peeked at DateSerializer and it uses two SimpleDateFormat 
> objects, which
> it creates in the constructor and stores in member variables. 
> No use of
> these SimpleDateFormat objects use any synchronization. If 
> the rpc router
> just creates a single DateSerializer and reuses it then it 
> seems to me this
> would be a problem. Can anyone verify?
> 
> Thanks
> 
> Rick
>