XMLParser: attribute gets truncated when updated

View: New views
14 Messages — Rating Filter:   Alert me  

XMLParser: attribute gets truncated when updated

by Gael Marziou :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hello,

I'm very new to Groovy so I suppose that I misunderstood something.

I wrote a little test to update an attribute of an XML node and it does
not work: new value gets truncated to the size of the previous value.

def input = '''<tag id="12" />'''
def tag = new XmlParser().parseText(input)
tag.attribute("id").value = "ABCD"
// id contains "AB" it has been truncated to original size
assert tag.attribute("id").size() == 4 : tag.attribute("id")

I suppose that the error is on line 3 but I don't understand it.

Thanks,

Gael

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email



Yikes! String is mutable! (was Re: [groovy-user] XMLParser: attribute gets truncated when updated)

by Jim White :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Holy smokes Batman!

I've always know that Groovy's disregard for private scope is a VERY BAD
THING.

But I've never bothered to work up some cases to demonstrate that fact.

The error on line 3 is that you're getting the private field 'value' of
a java.lang.String object.  That field happens to be an array of char
and when you assign a new value to it then the value of the string
changes.  Of course that doesn't have any effect on the length attribute
of the string.

This violation of private permits untold havoc and means all classes,
not just java.lang.String, are deprived of assurance that their API
contracts are enforced.  But such a succinct case is quite compelling.

def s = '12'
s.value = 'abcd'
println s
==>
ab

As for how to change the id attribute of a groovy.util.Node, I'm not
sure, although there are some docs on it.

Jim

Gael Marziou wrote:

> Hello,
>
> I'm very new to Groovy so I suppose that I misunderstood something.
>
> I wrote a little test to update an attribute of an XML node and it does
> not work: new value gets truncated to the size of the previous value.
>
> def input = '''<tag id="12" />'''
> def tag = new XmlParser().parseText(input)
> tag.attribute("id").value = "ABCD"
> // id contains "AB" it has been truncated to original size
> assert tag.attribute("id").size() == 4 : tag.attribute("id")
>
> I suppose that the error is on line 3 but I don't understand it.
>
> Thanks,
>
> Gael


---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email



Re: Yikes! String is mutable! (was Re: [groovy-user] XMLParser: attribute gets truncated when updated)

by Mike Dillon-4 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

begin Jim White quotation:
> This violation of private permits untold havoc and means all classes,
> not just java.lang.String, are deprived of assurance that their API
> contracts are enforced.  But such a succinct case is quite compelling.

I brought this up a while ago:

    http://www.nabble.com/Access-modifiers-in-Groovy-to13099409.html

-md

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email



Re: Yikes! String is mutable! (was Re: [groovy-user] XMLParser: attribute gets truncated when updated)

by Jim White :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Mike Dillon wrote:

> begin Jim White quotation:
>
>>This violation of private permits untold havoc and means all classes,
>>not just java.lang.String, are deprived of assurance that their API
>>contracts are enforced.  But such a succinct case is quite compelling.
>
> I brought this up a while ago:
>
>     http://www.nabble.com/Access-modifiers-in-Groovy-to13099409.html

Indeed, although the case is more compelling with 'ABC' than '[ "A",
"B", "C" ] as char[]'.

I also noted this problem in an earlier (but different) topic:

http://www.nabble.com/Re%3A-Why-does-Groovy-do-object-conversion--p15587047.html

And I should repeat here what I said there, please vote for this issue:

http://jira.codehaus.org/browse/GROOVY-1875

I'm confused now though, because at that time I got the impression that
only private methods were exposed, and I thought I had made a test for
myself that showed fields were protected.  I think though I must have
made a mistake there somewhere.

Ah, I see.  I was misled by the fact that private fields do not show up
in the property list of a class and mistakenly assumed that you couldn't
set a property that isn't in the list.  I'll update the issue.

As I say there, it is time to close the gaping hole and should do it for
1.6.  If it is too big an incompatiblity, and some users can't deal with
it right away (this being so close to time for 1.6RC1), then we can have
a switch to enable the old behavior for them.

Jim


---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email



Parent Message unknown Re: Yikes! String is mutable! (was Re: [groovy-user] XMLParser: attribute gets truncated when updated)

by Scott Hickey-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

I assume you understand that private access is possible in Java using reflection.
 
Scott

----- Original Message ----
From: Jim White <jim@...>
To: user@...
Sent: Friday, April 18, 2008 10:22:22 PM
Subject: Re: [groovy-user] Yikes! String is mutable! (was Re: [groovy-user] XMLParser: attribute gets truncated when updated)

Mike Dillon wrote:

> begin Jim White quotation:
>
>>This violation of private permits untold havoc and means all classes,
>>not just java.lang.String, are deprived of assurance that their API
>>contracts are enforced.  But such a succinct case is quite compelling.
>
> I brought this up a while ago:
>
>     http://www.nabble.com/Access-modifiers-in-Groovy-to13099409.html

Indeed, although the case is more compelling with 'ABC' than '[ "A",
"B", "C" ] as char[]'.

I also noted this problem in an earlier (but different) topic:

http://www.nabble.com/Re%3A-Why-does-Groovy-do-object-conversion--p15587047.html

And I should repeat here what I said there, please vote for this issue:

http://jira.codehaus.org/browse/GROOVY-1875

I'm confused now though, because at that time I got the impression that
only private methods were exposed, and I thought I had made a test for
myself that showed fields were protected.  I think though I must have
made a mistake there somewhere.

Ah, I see.  I was misled by the fact that private fields do not show up
in the property list of a class and mistakenly assumed that you couldn't
set a property that isn't in the list.  I'll update the issue.

As I say there, it is time to close the gaping hole and should do it for
1.6.  If it is too big an incompatiblity, and some users can't deal with
it right away (this being so close to time for 1.6RC1), then we can have
a switch to enable the old behavior for them.

Jim


---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email







---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email



Re: Yikes! String is mutable! (was Re: [groovy-user] XMLParser: attribute gets truncated when updated)

by Jim White :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Scott Hickey wrote:

> I assume you understand that private access is possible in Java using reflection.
>  
> Scott

Yes, of course.  But it is under the control of the security manager.
That is how access to private stuff should remain.

Groovy doing it by default and with no way to prevent it is seriously
wrong.  I assume you saw the totally ordinary and in no way contrived
case that started this thread?

Jim


---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email



Re: Yikes! String is mutable! (was Re: [groovy-user] XMLParser: attribute gets truncated when updated)

by Gael Marziou :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Thanks for the somehow frightening explanations, it helped me to find a
workaround.

I changed the buggy line :

tag.attribute("id").value = "ABCD"

to this:

tag.attributes().id = "ABCD"

Is there a better way?

Thanks,

Gael

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email



Re: Yikes! String is mutable! (was Re: [groovy-user] XMLParser: attribute gets truncated when updated)

by Jim White :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Gael Marziou wrote:

> Thanks for the somehow frightening explanations, it helped me to find a
> workaround.
>
> I changed the buggy line :
>
> tag.attribute("id").value = "ABCD"
>
> to this:
>
> tag.attributes().id = "ABCD"
>
> Is there a better way?

That looks good to me.  You're getting the map of attributes and setting
the element 'id' to a new value.  It is equivalent to this (less
pleasing) statement:

tag.attributes()['id'] = "ABCD"

Ah, and you've jogged my memory (I don't use this Groovy XML/DOM jazz
much).  There are GPath expressions.  So you can also do this:

tag.'@id' = "ABCD"

or even:

tag.@id = "ABCD"

Although the wiki says that is for when using XmlSlurper, and so I'm not
sure when you can't use it.  There are some differences when using W3C
DOM although they can be adjusted for by using a category.

http://groovy.codehaus.org/GPath

http://groovy.codehaus.org/Processing+XML

More details in the GinA (Groovy in Action) book, which I recommend.

Jim


---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email



Re: Yikes! String is mutable! (was Re: [groovy-user] XMLParser: attribute gets truncated when updated)

by Gael Marziou :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Thanks Jim, I really like this one, it works fine and is so concise:

tag.@id = "ABCD"

The only strange thing is that the compiler rejects this syntax in a
"switch" while it accepts it in an "if " statement.

Gael.


---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email



Re: Yikes! String is mutable! (was Re: [groovy-user] XMLParser: attribute gets truncated when updated)

by Jochen Theodorou :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Jim White schrieb:
[...]
> As I say there, it is time to close the gaping hole and should do it for
> 1.6.  If it is too big an incompatiblity, and some users can't deal with
> it right away (this being so close to time for 1.6RC1), then we can have
> a switch to enable the old behavior for them.

The problem is that the current MOP is not good enough to resolve this
kind of situation. Let me show you an example:


class X {
   private foo
   def bar() {
     return {this.@foo}
   }
   def setFoo(x){foo=x}
}

def x = new X()
x.setFoo(1)
assert x.bar().call() == 1

i this case it is quite clear, that this.@foo means the private field,
we can resolve it statically and last theoretically we could solve this
case... Now let us change the closure a little:

class X {
   private foo
   def bar() {
     return {foo}
   }
   def setFoo(x){foo=x}
}

def x = new X()
x.setFoo(1)
assert x.bar().call() == 1

it is more or less the same code, but now foo is a property in the first
place. Meaning that the lookup will be done using getProperty in
Closure. This method does not transport the caller class, so we can not
verify that the closure has access to foo.

The whole thing is totally blowing up when you do:

class X {
   private foo
   def bar() {
     return {foo}
   }
   def setFoo(x){foo=x}
}
class Y extends X{}

def x = new Y()
x.setFoo(1)
assert x.bar().call() == 1

even with the current information stored in the MOP and not going
through getPropterty, we still have the problem that the caller class is
actually the Closure and not X. But since the private field foo is now
only available in X and not in Y this example will fail even in current
Groovy. And what counts for getProperty partially counts for
invokeMethod too, but the problem is not as big there, as invokeMethod
is usually only called if the normal method call fails. Of course that
also means that Interceptable successfully deletes any access
information during the method call.

Not to mention that transporting the type information and checking
access rights is bad for the runtime performance

bye blackdrag

--
Jochen "blackdrag" Theodorou
The Groovy Project Tech Lead (http://groovy.codehaus.org)
http://blackdragsview.blogspot.com/
http://www.g2one.com/

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email



Re: Yikes! String is mutable! (was Re: [groovy-user] XMLParser: attribute gets truncated when updated)

by Jim White :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Yes, Java has the same issues with private members and inner classes.

While dealing with all of the finer points of that will have to wait for
<http://jira.codehaus.org/browse/GROOVY-69>, we can take some of their
tricks such as providing package scope access to private members when
needed.

Which in the current compiler probably means always, so rather than
creating hidden methods as Java does, I'd say just have private compiled
as package.

Groovy already doesn't respect private, so there is no loss by compiling
them to package, and there is great gain in restoring the meaning of
private.

And Java code is not going to suddenly run into improper access issues
because it does respect package scope, and for code in the same package
the access situation would be effectively the same as now.

Jim

Jochen Theodorou wrote:

> Jim White schrieb:
> [...]
>
>> As I say there, it is time to close the gaping hole and should do it
>> for 1.6.  If it is too big an incompatiblity, and some users can't
>> deal with it right away (this being so close to time for 1.6RC1), then
>> we can have a switch to enable the old behavior for them.
>
>
> The problem is that the current MOP is not good enough to resolve this
> kind of situation. Let me show you an example:
>
>
> class X {
>   private foo
>   def bar() {
>     return {this.@foo}
>   }
>   def setFoo(x){foo=x}
> }
>
> def x = new X()
> x.setFoo(1)
> assert x.bar().call() == 1
>
> i this case it is quite clear, that this.@foo means the private field,
> we can resolve it statically and last theoretically we could solve this
> case... Now let us change the closure a little:
>
> class X {
>   private foo
>   def bar() {
>     return {foo}
>   }
>   def setFoo(x){foo=x}
> }
>
> def x = new X()
> x.setFoo(1)
> assert x.bar().call() == 1
>
> it is more or less the same code, but now foo is a property in the first
> place. Meaning that the lookup will be done using getProperty in
> Closure. This method does not transport the caller class, so we can not
> verify that the closure has access to foo.
>
> The whole thing is totally blowing up when you do:
>
> class X {
>   private foo
>   def bar() {
>     return {foo}
>   }
>   def setFoo(x){foo=x}
> }
> class Y extends X{}
>
> def x = new Y()
> x.setFoo(1)
> assert x.bar().call() == 1
>
> even with the current information stored in the MOP and not going
> through getPropterty, we still have the problem that the caller class is
> actually the Closure and not X. But since the private field foo is now
> only available in X and not in Y this example will fail even in current
> Groovy. And what counts for getProperty partially counts for
> invokeMethod too, but the problem is not as big there, as invokeMethod
> is usually only called if the normal method call fails. Of course that
> also means that Interceptable successfully deletes any access
> information during the method call.
>
> Not to mention that transporting the type information and checking
> access rights is bad for the runtime performance
>
> bye blackdrag
>


---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email



Re: Yikes! String is mutable! (was Re: [groovy-user] XMLParser: attribute gets truncated when updated)

by Jochen Theodorou :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Jim White schrieb:

> Yes, Java has the same issues with private members and inner classes.
>
> While dealing with all of the finer points of that will have to wait for
> <http://jira.codehaus.org/browse/GROOVY-69>, we can take some of their
> tricks such as providing package scope access to private members when
> needed.
>
> Which in the current compiler probably means always, so rather than
> creating hidden methods as Java does, I'd say just have private compiled
> as package.
>
> Groovy already doesn't respect private, so there is no loss by compiling
> them to package, and there is great gain in restoring the meaning of
> private.

private currently does not mean the method is hidden if called on an
instance of a class that declares that method. True, but if you
subclass, then the method is hidden. compiling to package will also mean
the method is hidden in subclasses, but what do we gain from this? Isn't
the method still available in a subclass I call from another class in
the same package? Also the current access is not really package scoped.
In fact package scoping is a big problem for us, because checking
package strings will slow the method call down pretty much.

> And Java code is not going to suddenly run into improper access issues
> because it does respect package scope, and for code in the same package
> the access situation would be effectively the same as now.

why should Java code call private methods all of a sudden?


  bye blackdrag


--
Jochen "blackdrag" Theodorou
The Groovy Project Tech Lead (http://groovy.codehaus.org)
http://blackdragsview.blogspot.com/
http://www.g2one.com/

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email



Parent Message unknown Re: Yikes! String is mutable! (was Re: [groovy-user] XMLParser: attribute gets truncated when updated)

by Scott Hickey-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

I'm just curious to know if your String example in your original post is something that happened in the course of coding on a project by yourself or someone one your team, or are you trying to be proactive for possible pitfalls? I know you said it wasn't contrived but I am trying to understand the context in which someone tried to assign something to value on a String. In three years of working with a project team that has spans a wide range of Java experience, I've seem some unexpected things but I haven't seen this personally.

I know this is a emotionally charged topic and I'm not for clarification to fan the flames. I have an interest in tracking hypothetical problems or pitfalls with Groovy versus ones actually encountered in the course of project work.


Scott

----- Original Message ----
From: Jim White <jim@...>
To: user@...
Sent: Saturday, April 19, 2008 12:17:14 AM
Subject: Re: [groovy-user] Yikes! String is mutable! (was Re: [groovy-user] XMLParser: attribute gets truncated when updated)

Scott Hickey wrote:

> I assume you understand that private access is possible in Java using reflection.
>  
> Scott

Yes, of course.  But it is under the control of the security manager.
That is how access to private stuff should remain.

Groovy doing it by default and with no way to prevent it is seriously
wrong.  I assume you saw the totally ordinary and in no way contrived
case that started this thread?

Jim


---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email






---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email



Re: Yikes! String is mutable! (was Re: [groovy-user] XMLParser: attribute gets truncated when updated)

by Jim White :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

The original post was the first in the thread I replied to.

http://markmail.org/message/qppcm7ksqe4akceu

The summary being you get a result from a function and think it has a
property named 'value', you want to change it so you do.  The oringal
poster thinking 'attribute' returned some Node object or the like.

Bad news if the value happens to be java.lang.String or anything else
that has a property named 'value' that is private.  Obviously the error
can occur on either side of the function call.  And with Groovy being
dynamically typed, there is no way to prevent this from happening.

As I said to start with, this is clearly a bad situation but hadn't
bothered to search for compelling examples.  But here it is just tossed
over the transom.

For myself, I just don't write code that is bugged, so it isn't a
problem... ;-)

Jim

Scott Hickey wrote:

> I'm just curious to know if your String example in your original post
> is something that happened in the course of coding on a project by
> yourself or someone one your team, or are you trying to be proactive
> for possible pitfalls? I know you said it wasn't contrived but I am
> trying to understand the context in which someone tried to assign
> something to value on a String. In three years of working with a
> project team that has spans a wide range of Java experience, I've
> seem some unexpected things but I haven't seen this personally.
>
> I know this is a emotionally charged topic and I'm not for
> clarification to fan the flames. I have an interest in tracking
> hypothetical problems or pitfalls with Groovy versus ones actually
> encountered in the course of project work.
>
>
> Scott
>
> ----- Original Message ---- From: Jim White <jim@...> To:
> user@... Sent: Saturday, April 19, 2008 12:17:14 AM
> Subject: Re: [groovy-user] Yikes! String is mutable! (was Re:
> [groovy-user] XMLParser: attribute gets truncated when updated)
>
> Scott Hickey wrote:
>
>
>> I assume you understand that private access is possible in Java
>> using reflection.
>>
>> Scott
>
>
> Yes, of course.  But it is under the control of the security manager.
>  That is how access to private stuff should remain.
>
> Groovy doing it by default and with no way to prevent it is seriously
>  wrong.  I assume you saw the totally ordinary and in no way
> contrived case that started this thread?
>
> Jim


---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email