Re: Cloning Form Beans

2003-06-12 Thread Erik Price


Jerry Jalenak wrote:
Erik,

Thanks for the lesson - and I'll get out and get a copy of Josh's book.  In
the meantime I've also discovered that 'clone' basically does a shallow copy
- i.e. if there is a nested construct of javabeans, clone will only copy the
hightest level, and then place reference pointers to the nested beans.  I
think this is what is getting me.
Does anyone have a 'deep copy' class that
will clone a complex javabean construct? 
Bloch has a good-sized chapter right at the beginning of the book that 
discusses overriding the clone method correctly.  There is actually a 
fairly strict formula for doing it, since you have to override 
hashCode() and take that into consideration as well.  But I think this 
one is available online for free.  It will show you how to override 
clone in your JavaBean so that you can create a deep copy.

It's in Chapter 3, "Methods Common to All Objects":



Erik

-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]


RE: Cloning Form Beans

2003-06-12 Thread Jerry Jalenak
Erik,

Thanks for the lesson - and I'll get out and get a copy of Josh's book.  In
the meantime I've also discovered that 'clone' basically does a shallow copy
- i.e. if there is a nested construct of javabeans, clone will only copy the
hightest level, and then place reference pointers to the nested beans.  I
think this is what is getting me.  Does anyone have a 'deep copy' class that
will clone a complex javabean construct?  



Jerry Jalenak
Team Lead, Web Publishing
LabOne, Inc.
10101 Renner Blvd.
Lenexa, KS  66219
(913) 577-1496

[EMAIL PROTECTED]


-Original Message-
From: Erik Price [mailto:[EMAIL PROTECTED]
Sent: Thursday, June 12, 2003 2:12 PM
To: Struts Users Mailing List
Subject: Re: Cloning Form Beans




Erik Price wrote:

> But you're still not safe yet.
> 
> What if somehow someone had held onto a reference to one of the Date 
> objects passed into the constructor?
> 
>   Date myEvilStart = new Date();
>   Date end = new Date();
>   Period p = new Period(myEvilStart, end);
>   // at this point is "p" immutable?  NO!
>   myEvilStart.setYear(78);
>   // The "start" field in "p" has just been modified!

Whoops class, sorry, I forgot to finish the lesson.  Bloch teaches us 
that we should also make an internal copy of each argument to the 
constructor:

   public Period(Date start, Date end) {
 this.start = new Date(start);
 this.end = new Date(end);
   }

This way if someone does still have a reference to the argument, they 
can't modify that as a way into our immutable Period class.

Okay class is dimissed.




Erik


-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]


This transmission (and any information attached to it) may be confidential and is 
intended solely for the use of the individual or entity to which it is addressed. If 
you are not the intended recipient or the person responsible for delivering the 
transmission to the intended recipient, be advised that you have received this 
transmission in error and that any use, dissemination, forwarding, printing, or 
copying of this information is strictly prohibited. If you have received this 
transmission in error, please immediately notify LabOne at the following email 
address: [EMAIL PROTECTED]



-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



Re: Cloning Form Beans

2003-06-12 Thread Erik Price


Erik Price wrote:

But you're still not safe yet.

What if somehow someone had held onto a reference to one of the Date 
objects passed into the constructor?

  Date myEvilStart = new Date();
  Date end = new Date();
  Period p = new Period(myEvilStart, end);
  // at this point is "p" immutable?  NO!
  myEvilStart.setYear(78);
  // The "start" field in "p" has just been modified!
Whoops class, sorry, I forgot to finish the lesson.  Bloch teaches us 
that we should also make an internal copy of each argument to the 
constructor:

  public Period(Date start, Date end) {
this.start = new Date(start);
this.end = new Date(end);
  }
This way if someone does still have a reference to the argument, they 
can't modify that as a way into our immutable Period class.

Okay class is dimissed.



Erik

-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]


Re: Cloning Form Beans

2003-06-12 Thread Erik Price


Jerry Jalenak wrote:
So, something like this?

	private String myString;

public String getMyString()
{
String returnedString = this.myString;
return (returnedString);
}
I'm not sure how this applies to my cloning issue


Well, String itself is immutable so it doesn't apply here.  Here's the 
classic example from Bloch's book (p. 122):

public final class Period {
  private final Date start;
  private final Date end;
  public Period(Date start, Date end) {
if (start.compareTo(end) > 0)
  throw new IllegalArgumentException();
this.start = start;
this.end = end;
  }
  public Date getStart() {
return start;
  }
  public Date getEnd() {
return end;
  }
}
Looks like an immutable class, right?  You can set the start and end 
times of the Period when you create it, but once you do that, they are 
fixed until the class is garbage collected.  The fields are final so 
they can't be reassigned, and there's no mutator methods to affect the 
fields.  So fundamentally, this class is "immutable".  Right?

Wrong.  It's easy to overlook the fact that someone's client code can do 
this:

  // p is a Period instance
  Date myEnd = p.getEnd();
  myEnd.setYear(78);
It seems like I've only changed the object pointed to by "myEnd", not 
the object held internally by the "p" instance.  Right?

Nope.  Remember that both references point to the same object.  So 
really the getter method is more like a doorway that lets me into the 
"immutable" Period object.  The way that you make your classes truly 
immutable (and safe from this kind of attack) is to make a defensive 
copy in the getter methods.  Here's how you would implement that in the 
Period class:

  Date getStart() {
return new Date(this.start);
  }
  Date getEnd() {
return new Date(this.end);
  }
This way you're only handing a *copy* of the internal data held by the 
Period instance.

But you're still not safe yet.

What if somehow someone had held onto a reference to one of the Date 
objects passed into the constructor?

  Date myEvilStart = new Date();
  Date end = new Date();
  Period p = new Period(myEvilStart, end);
  // at this point is "p" immutable?  NO!
  myEvilStart.setYear(78);
  // The "start" field in "p" has just been modified!
This lesson has been appropriated entirely from Josh Bloch's "Effective 
Java".  If you found it useful or would like to learn more, you should 
get the book.  4 out of 5 dentists agree it is one of the best Java 
books ever written.



Erik

-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]


RE: Cloning Form Beans

2003-06-12 Thread Derek Richardson
Don't you mean required for immutable classes that are ***composed by*** other objects 
which are mutable?

> -Original Message-
> From: Erik Price [mailto:[EMAIL PROTECTED]
> Sent: Thursday, June 12, 2003 1:39 PM
> To: Struts Users Mailing List
> Subject: Re: Cloning Form Beans
> 
> 
> 
> 
> Jerry Jalenak wrote:
> > Not sure what you mean by 'defensive copies'  Is there 
> something special
> > I need to do in my bean so I end up with a 'true' 
> duplicate, and not just a
> > second reference?
> 
> Defensive copies... described in Josh Bloch's "Effective 
> Java".  Getter 
> methods return a copy of the property that they would return 
> in a normal 
> class, so that client code can't affect that property and have the 
> change trickle back into your object.  Required for immutable classes 
> that compose other objects which are mutable.
> 
> 
> 
> 
> 
> Erik
> 
> 
> -
> To unsubscribe, e-mail: [EMAIL PROTECTED]
> For additional commands, e-mail: [EMAIL PROTECTED]
> 
> 

-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



RE: Cloning Form Beans

2003-06-12 Thread Jerry Jalenak
So, something like this?

private String myString;

public String getMyString()
{
String returnedString = this.myString;
return (returnedString);
}

I'm not sure how this applies to my cloning issue

Jerry Jalenak
Team Lead, Web Publishing
LabOne, Inc.
10101 Renner Blvd.
Lenexa, KS  66219
(913) 577-1496

[EMAIL PROTECTED]


-Original Message-
From: Erik Price [mailto:[EMAIL PROTECTED]
Sent: Thursday, June 12, 2003 12:39 PM
To: Struts Users Mailing List
Subject: Re: Cloning Form Beans




Jerry Jalenak wrote:
> Not sure what you mean by 'defensive copies'  Is there something
special
> I need to do in my bean so I end up with a 'true' duplicate, and not just
a
> second reference?

Defensive copies... described in Josh Bloch's "Effective Java".  Getter 
methods return a copy of the property that they would return in a normal 
class, so that client code can't affect that property and have the 
change trickle back into your object.  Required for immutable classes 
that compose other objects which are mutable.





Erik


-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]


This transmission (and any information attached to it) may be confidential and is 
intended solely for the use of the individual or entity to which it is addressed. If 
you are not the intended recipient or the person responsible for delivering the 
transmission to the intended recipient, be advised that you have received this 
transmission in error and that any use, dissemination, forwarding, printing, or 
copying of this information is strictly prohibited. If you have received this 
transmission in error, please immediately notify LabOne at the following email 
address: [EMAIL PROTECTED]



-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



Re: Cloning Form Beans

2003-06-12 Thread Erik Price


Jerry Jalenak wrote:
Not sure what you mean by 'defensive copies'  Is there something special
I need to do in my bean so I end up with a 'true' duplicate, and not just a
second reference?
Defensive copies... described in Josh Bloch's "Effective Java".  Getter 
methods return a copy of the property that they would return in a normal 
class, so that client code can't affect that property and have the 
change trickle back into your object.  Required for immutable classes 
that compose other objects which are mutable.





Erik

-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]


RE: Cloning Form Beans

2003-06-12 Thread Jerry Jalenak
Not sure what you mean by 'defensive copies'  Is there something special
I need to do in my bean so I end up with a 'true' duplicate, and not just a
second reference?

Jerry Jalenak
Team Lead, Web Publishing
LabOne, Inc.
10101 Renner Blvd.
Lenexa, KS  66219
(913) 577-1496

[EMAIL PROTECTED]


-Original Message-
From: Paul Curren [mailto:[EMAIL PROTECTED]
Sent: Thursday, June 12, 2003 12:19 PM
To: Struts Users Mailing List
Subject: Re: Cloning Form Beans


Hi there,

I don't know the answer but reading the javadoc on cloneBean it states -
"Clone a bean based on the available getters and setters..."

So if the getter on your bean isn't making defensive copies (and neither 
is the setter) then i'd imagine your newly cloned bean will have 
properties that reference the same object as the original bean.

Paul C

Jerry Jalenak wrote:

>Hi All,
>
>I have a form-bean defined in struts-config that is created in session
scope
>in a setup action, then used in another three actions (kinda of a wizard
>thing).  In the second action I have to make an exact copy of the form bean
>so I can do some comparisons between old and new values.  I initially
>thought the the BeanUtils.cloneBean method would do the trick, but I'm
>discovering that when my struts form-bean is updated, the cloned bean is
>also being updated.  Leads me to believe that a copy is not really being
>made, but a second reference is being created.  This form-bean is a fairly
>complex set of nested beans; does anyone have a suggestion on the best way
>to handle this?
>
>TIA
>
>Jerry Jalenak
>Team Lead, Web Publishing
>LabOne, Inc.
>10101 Renner Blvd.
>Lenexa, KS  66219
>(913) 577-1496
>
>[EMAIL PROTECTED]
>
>
>This transmission (and any information attached to it) may be confidential
and is intended solely for the use of the individual or entity to which it
is addressed. If you are not the intended recipient or the person
responsible for delivering the transmission to the intended recipient, be
advised that you have received this transmission in error and that any use,
dissemination, forwarding, printing, or copying of this information is
strictly prohibited. If you have received this transmission in error, please
immediately notify LabOne at the following email address:
[EMAIL PROTECTED]
>
>
>
>-
>To unsubscribe, e-mail: [EMAIL PROTECTED]
>For additional commands, e-mail: [EMAIL PROTECTED]
>
>
>  
>


-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



Re: Cloning Form Beans

2003-06-12 Thread Paul Curren
Hi there,

I don't know the answer but reading the javadoc on cloneBean it states -
"Clone a bean based on the available getters and setters..."
So if the getter on your bean isn't making defensive copies (and neither 
is the setter) then i'd imagine your newly cloned bean will have 
properties that reference the same object as the original bean.

Paul C

Jerry Jalenak wrote:

Hi All,

I have a form-bean defined in struts-config that is created in session scope
in a setup action, then used in another three actions (kinda of a wizard
thing).  In the second action I have to make an exact copy of the form bean
so I can do some comparisons between old and new values.  I initially
thought the the BeanUtils.cloneBean method would do the trick, but I'm
discovering that when my struts form-bean is updated, the cloned bean is
also being updated.  Leads me to believe that a copy is not really being
made, but a second reference is being created.  This form-bean is a fairly
complex set of nested beans; does anyone have a suggestion on the best way
to handle this?
TIA

Jerry Jalenak
Team Lead, Web Publishing
LabOne, Inc.
10101 Renner Blvd.
Lenexa, KS  66219
(913) 577-1496
[EMAIL PROTECTED]

This transmission (and any information attached to it) may be confidential and is intended solely for the use of the individual or entity to which it is addressed. If you are not the intended recipient or the person responsible for delivering the transmission to the intended recipient, be advised that you have received this transmission in error and that any use, dissemination, forwarding, printing, or copying of this information is strictly prohibited. If you have received this transmission in error, please immediately notify LabOne at the following email address: [EMAIL PROTECTED]



-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
 



-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]