Great, Tom, I think this will fix the problem for some, perhaps most, 
cases. Unfortunately, it may not be the best solution in all cases: What 
if you want the fields to be serialized, but not deserialized? In my 
case I have java classes on the server and C#-classes on the client. The 
java classes may have final fields with meaningful values that I want 
the client to see. If these are not serialized, the client will not be 
able to see these values, as they use classes generated from the 
WSDL-file. However, the client, being programmed in C#, will in some 
cases try to send the object back (e.g. after modifying some fields) in 
which case the server will (i.e., used to) trow an IllegalAccessException.

Two cases:
- Will the information about final fields AND their values still be in 
the WSDL file? If it is, then this solution will work for me, but not in 
  all cases, as will be seen by the next case. If it isn't, then I'm 
afraid it will not be suitable for me.
- Remember that final fields are not constant over more than one object. 
They may be set to different values by different constructor or simply 
be a calculated value differing from object to object. Even static final 
fields may differ from classloader to classloader.

I think the best solution would be to check whether the field is final 
when trying to _set_ the value, and if it is simply ignore it (even 
though it does indicate an improper use of the .

Of course the ultimate solution takes all considerations into account:

- Two different serializers (or a parametrized BeanSerializer), one that 
includes final fields and one that doesn't
- Two different deserializers (or a parametrized BeanDeserializer), one 
that ignores final fields and one that throws an exception


By the way, I am mighty impressed by the time it took to receive an 
answer and even a fix. Way to go!


Regards,


Narve

-----Original Message-----
List:     axis-user
Subject:  RE: deserialization of final fields
From:     Tom Jordahl <[EMAIL PROTECTED]>
Date:     2002-05-03 17:41:39

Narve,

I have a fix for this that ignores final fields in JavaBeans when 
constructing the BeanPropertyDescriptors.  I believe this will prevent 
the fields from getting serialized in the first place, so Axis will not 
attempt to Deserialize them.

Please try out either the latest CVS build or Mondays nightly build and 
let me know if this solves your issue.

Thanks.

--
Tom Jordahl
Macromedia



-----Original Message-----
From: Narve Saetre [mailto:[EMAIL PROTECTED]]
Sent: Friday, May 03, 2002 12:34 PM
To: [EMAIL PROTECTED]; [EMAIL PROTECTED]
Subject: deserialization of final fields



It seems the BeanDeserializer does not take into account that fields may
be final (you get a java.lang.IllegalAccessException when you try to set
the value). I see that several people (well, at least two) have asked
about this in the user mailing list.

An easy fix is to add

              } catch (java.lang.IllegalAccessException ex) {
                // Final field - Ignore


on line 113 of BeanPropertyTarget.java. (From beta-2, that is, the
complete method is shown at the bottom).

This is probably not the best solution (one should check whether the
field is final before one even try to set the value), and it may not
even be suitable for all purposes, but it works for me and I'll keep the
change locally until this issue is resolved.

Please, if anybody has better solutions post them here (or update the
source).

Regards,


Narve


--- from BeanPropertyTarget.java ---

      public void set(Object value) throws SAXException {
          try {
              if (index < 0)
                  pd.set(object, value);
              else
                  pd.set(object, index, value);
          } catch (Exception e) {
              Class type = pd.getType();
              value = JavaUtils.convert(value, type);
              try {
                  if (index < 0)
                      pd.set(object, value);
                  else
                      pd.set(object, index, value);
              } catch (java.lang.IllegalAccessException ex) {
                // Final field - Ignore
              } catch (Exception ex) {
                  String field= pd.getName();
                  int i = 0;
                  if (index >=0) {
                      field += "[" + index + "]";
                      i = 1;
                  }
                  if (log.isErrorEnabled()) {
                      String valueType = "null";
                      if (value != null)
                          valueType = value.getClass().getName();
                      log.error(JavaUtils.getMessage("cantConvert02",
                                                     new String[] {
                                                         valueType,
                                                         field,
                                                        pd.getType().getName()}));
                  }
                  throw new SAXException(ex);
              }
          }
      }

Reply via email to