users@jax-rpc.java.net

Re: Returning array of custom object -> NULL objects in array

From: Pedro Salazar <pedro-b-salazar_at_PTINOVACAO.PT>
Date: Mon, 09 Dec 2002 10:46:36 +0000

Greetings,

Doug Kohlert and Kenneth Baltz, thanks for all your help.

A workaround that I figure is using the private array field to public
and do not interfere in set/get methods. The serialization process works
fine. The problem is that is not possible to manipulate the array if we
would like to do it.

A better solution is to use the same reference to the original array in
the argument of the set method (look to my code below), as you said. In
this case, we must have attention to not share (update) the original
array.

---BEGIN CODE---
// get/set methods
public Profile[] getProfiles(){
   return this.profiles;
}
public void setProfiles(Profile[] profiles){
   /*if(profiles.length>0){
      this.profiles=new Profile[profiles.length];
      System.arraycopy(profiles,0,this.profiles,0,profiles.length);
   }*/
   this.profiles=profiles; //NEW
}
---END CODE---

But, I didn't understand quite well the your explanation for the
succeed. For example, if the type array was primitive (e.g. int[]), it
works just fine with the arraycopy approach. So, could you explain me
better the "multirefed" problem that you referred?

thanks,

Pedro Salazar.

On Fri, 2002-12-06 at 20:31, Doug Kohlert wrote:
> Ken, is correct on the behavior of JAXRPC. The reason this happens is that the
> array instance is created when it is first encountered in the XML stream, but
> it cannot be populated because the elements of the array have been multirefed
> (href-ed) and do not appear until the end of the stream. So the object that
> contains the array is given the empty array and the JAXRPC runtime also maintains
> a reference to that array. When the array elements are deserialized from the
> xml stream the array is populated.
>
> A work around for this is to modify your class that contains the array to lazily
> extract the contents of the array as needed (i.e. don't extract them when the
> setter is called, extract them when some other method requiring them is called).
>
>
> For example, if I have a class that has the following fields and methods
> String concantenatedNames = "";
> String[] theNames;
> public void setNames(String[] names) {
> theNames = names;
> for(int i=0;i<names.length;i++)
> concatenatedNames += names[i];
> }
> public String[] getNames() {
> return theNames;
> }
> public String concatenateNames() {
> return concantenatedNames;
> }
> The concatenatedNames string would be empty has you have encountered above.
> But if you modify the code slightly everything works because by the
> time the concatenatedNames method is called everything has been
> deserialized.
>
> String concantenatedNames = null;
> String[] theNames;
> public void setNames(String[] names) {
> theNames = names;
> }
> public String[] getNames() {
> return theNames;
> }
> public String concatenateNames() {
> if (concatenatedNames == null) {
> for(int i=0;i<theNames.length;i++)
> concatenatedNames += theNames[i];
> }
> return concantenatedNames;
> }
>
> I hope this helps
>
> Baltz, Kenneth wrote:
> > I know this one very well. I wasted 3 days tracking it down. It might
> > be a bug; I can't decide.
> >
> > The way the JAX-RPC array deserializers are written looks something like
> > this:
> >
> > // Using your code as an example
> > Profile [] profiles = new Profile[/* correct number of obejcts];
> >
> > Object3.setProfiles( profiles ); // note that the array is unpopulated
> > at this point
> >
> > for( int i = 0; i < profiles.length; i++ ) {
> > profiles[i] = new Profile( ... );
> > ... call Profile setters ...
> > }
> >
> > The trouble is caused by the fact that you don't keep the Array
> > reference that is passed to your setter. The JAX-RPC implementation
> > assumes that getters/setters are basically the same as actual variables.
> >
> > I believe the same behavior appears for Collections objects as well.
> > I.e. The object is passed to you before it's populated.
> >
> > K.C.
> >
> >
> > > -----Original Message-----
> > > From: Pedro Salazar [mailto:pedro-b-salazar_at_PTINOVACAO.PT]
> > > Sent: Friday, December 06, 2002 3:23 AM
> > > To: JAXRPC-INTEREST_at_JAVA.SUN.COM
> > > Subject: Returning array of custom object -> NULL objects in array
> > >
> > >
> > > Greetings,
> > >
> > > I created a jaxrpc web service that returns a custom object which has
> > > two fields: a custom object2 and a array of custom object3 ( ->
> > > Profile[]). In my client, when I can retrieve the custom
> > > object2 ok, but
> > > when I try to get my array of custom object3, all the positions are
> > > null!
> > >
> > > My setX/getX of custom object3 are:
> > >
> > > private Profile[] profiles;
> > > public Profile[] getProfiles(){
> > > return this.profiles;
> > > }
> > > public void setProfiles(Profile[] profiles){
> > > if(profiles.length>0){
> > > this.profiles=new Profile[profiles.length];
> > >
> > > System.arraycopy(profiles,0,this.profiles,0,profiles.length);
> > > }
> > > }
> > >
> > > PS. the object Profile is a simple object with two fields (int,String)
> > > with a set/get to both of them.
> > >
> > > thanks for your attention,
> > > regards.
> > >
> > > --
> > > pedro salazar (pt-inovacao) <pedro-b-salazar_at_ptinovacao.pt>
> > > key id: D803BC61
> > >
> >
>
>
> --
> Doug Kohlert
> Java Software Division
> Sun Microsystems, Inc.
> phone: 503 345-9806
--
pedro salazar (pt-inovacao) <pedro-b-salazar_at_ptinovacao.pt>
key id: D803BC61