|
View:
New views
8 Messages
—
Rating Filter:
Alert me
|
|
|
Java integration: Swing string problemHi,
I'm mainly just recording some information here in a place where it might be useful. I can't drill deeper at the moment. There's no bug here, but there may be an opportunity to improve Java integration. I encountered a case where Swing compares a passed in string, against a static final field, using ==. IOW, they're using it like an enum. In Java SE 6 it's in AbstractButton.actionPropertyChanged. So my JRuby program calls AbstractAction putValue(String key, object value). The action object notifies listeners, including JMenuItems which inherit from AbstractButton. This is how how you change menu text in Swing, so the undo menu reads "Undo Typing" or whatever. My call in jruby looked like: my_action.put_value(Action::NAME, "Undo Typing") The AbstractButton code, however, fails the comparison of this key against Action.NAME. I guess JRuby is passing a copy of the string around. That's why it fails ==. My workaround is: ActionNameKey = javax.swing.Action.java_class.declared_field('NAME').static_value my_action.put_value(ActionNameKey, "Undo Typing") If I had the time right now I'd dig into whether Jruby could make cases like this succeed by always calling String.intern before passing the string around. 1. I don't know that jruby doesn't do this, 2. I don't know that it would fix the problem. But it would be nice to reduce the friction if possible. Hugh --------------------------------------------------------------------- To unsubscribe from this list please visit: http://xircles.codehaus.org/manage_email |
|
|
Re: Java integration: Swing string problemThis fails in your original case because the Java String is converted to a Ruby String when the constant is set. Ruby string values are stored as ByteLists (wrapping a byte array), and are divorced from the original Java string. The second case works because JavaField#static_value just wraps the original Java string in a JavaObject (low-level wrapper).
JavaObject is likely to go away (or at least be re-purposed) post-1.1, so we'll need to be mindful of this use case. If we do the refactoring right, it should be possible to have an alternative String implementation for strings returned from Java that retains the original value (converting to ByteList only if necessary), which will make sense because in many (most?) cases, strings returned from Java are just going to be passed back in without further manipulation. -Bill On 1/5/08, Hugh Winkler <hughw@...> wrote: Hi, |
|
|
Re: Java integration: Swing string problemThanks for these comments.
On Jan 5, 2008 11:25 PM, Bill Dortch <bill.dortch@...> wrote: > This fails in your original case because the Java String is converted to a > Ruby String when the constant is set. Ruby string values are stored as > ByteLists (wrapping a byte array), and are divorced from the original Java > string. So to clarify, I'm thinking that when JRuby passes one of these ByteLists back to java, it could call String.intern on it before passing it. The following test passes. I suspect if we call intern() on the ByteList copy, it would make the Swing calls succeed. public class Main { public static final String ORIGINAL="something"; public static void main(String[] args) { char[] bytes = {'s','o','m','e','t','h','i','n','g'}; String copy = new String(bytes); String interned = copy.intern(); assert(copy.equals(ORIGINAL)); assert(copy != ORIGINAL); assert(interned == ORIGINAL); } } The second case works because JavaField#static_value just wraps the > original Java string in a JavaObject (low-level wrapper). > > JavaObject is likely to go away (or at least be re-purposed) post-1.1, so > we'll need to be mindful of this use case. If we do the refactoring right, > it should be possible to have an alternative String implementation for > strings returned from Java that retains the original value (converting to > ByteList only if necessary), which will make sense because in many (most?) > cases, strings returned from Java are just going to be passed back in > without further manipulation. > > -Bill > > --------------------------------------------------------------------- To unsubscribe from this list please visit: http://xircles.codehaus.org/manage_email |
|
|
Re: Java integration: Swing string problemHugh Winkler pisze:
> So to clarify, I'm thinking that when JRuby passes one of these > ByteLists back to java, it could call String.intern on it before > passing it. The following test passes. I suspect if we call intern() > on the ByteList copy, it would make the Swing calls succeed. > > public class Main { > > public static final String ORIGINAL="something"; > > public static void main(String[] args) { > char[] bytes = {'s','o','m','e','t','h','i','n','g'}; > String copy = new String(bytes); > String interned = copy.intern(); > assert(copy.equals(ORIGINAL)); > assert(copy != ORIGINAL); > assert(interned == ORIGINAL); > } > } > possible. Marcin. --------------------------------------------------------------------- To unsubscribe from this list please visit: http://xircles.codehaus.org/manage_email |
|
|
Re: Java integration: Swing string problemOn Jan 6, 2008 9:02 AM, Marcin Mielżyński <lopx@...> wrote:
> Interning arbitrary strings is evil, we should avoid this as much as > possible. > What is your reason? |
|
|
Re: Java integration: Swing string problemHugh Winkler pisze:
> On Jan 6, 2008 9:02 AM, Marcin Mielżyński <lopx@...> wrote: > > >> Interning arbitrary strings is evil, we should avoid this as much as >> possible. >> >> > > What is your reason? > big permgen footprint already). Marcin. --------------------------------------------------------------------- To unsubscribe from this list please visit: http://xircles.codehaus.org/manage_email |
|
|
Re: Java integration: Swing string problemOn Jan 6, 2008 9:45 AM, Marcin Mielżyński <lopx@...> wrote:
> Hugh Winkler pisze: > > > On Jan 6, 2008 9:02 AM, Marcin Mielżyński <lopx@...> wrote: > > > > > >> Interning arbitrary strings is evil, we should avoid this as much as > >> possible. > >> > >> > > > > What is your reason? > > > Interned Strings are not GCable, this leads to permgen issues (JRuby has > big permgen footprint already). > > Oh. Well that is a very good reason. 1. It could be a runtime switch to jruby : -Djruby.intern.java.string=true. (along with -XX:MaxPermGen=...) Then the developer takes responsibility. 2. Jruby might apply intern only to "public static final" strings that originated with a java import, because that is the real use case. It would have to set a flag that travels around with the RubyString somehow, to remember to intern the string when needed. 3. I tried to find a way to call intern from JRuby, but I ended up with Ruby strings. My jruby java integration knowledge isn't great, and I suspect there might be a way to do that. I'm not sure how much an improvement that would be over my workaround, though. It's still going to be a surprise for anyone developing a Swing app, some APIs they will have to learn to treat specially. Hugh > Marcin. > > --------------------------------------------------------------------- > To unsubscribe from this list please visit: > > http://xircles.codehaus.org/manage_email > > |
|
|
Re: Java integration: Swing string problemAs Bill had mentioned above we have a JavaObject wrapper needs to go
away and when it does we can fix this problem. We won't need to convert the Java String into a Ruby String and then recreate it as a Java String on the way out. It will just be the Java String the whole time. -Tom On Jan 6, 2008 10:08 AM, Hugh Winkler <hughw@...> wrote: > On Jan 6, 2008 9:45 AM, Marcin Mielżyński <lopx@...> wrote: > > Hugh Winkler pisze: > > > > > On Jan 6, 2008 9:02 AM, Marcin Mielżyński <lopx@...> wrote: > > > > > > > > >> Interning arbitrary strings is evil, we should avoid this as much as > > >> possible. > > >> > > >> > > > > > > What is your reason? > > > > > Interned Strings are not GCable, this leads to permgen issues (JRuby has > > big permgen footprint already). > > > > > > > Oh. Well that is a very good reason. > > 1. It could be a runtime switch to jruby : > -Djruby.intern.java.string=true. (along with -XX:MaxPermGen=...) Then > the developer takes responsibility. > > 2. Jruby might apply intern only to "public static final" strings that > originated with a java import, because that is the real use case. It > would have to set a flag that travels around with the RubyString > somehow, to remember to intern the string when needed. > > 3. I tried to find a way to call intern from JRuby, but I ended up > with Ruby strings. My jruby java integration knowledge isn't great, > and I suspect there might be a way to do that. I'm not sure how much > an improvement that would be over my workaround, though. It's still > going to be a surprise for anyone developing a Swing app, some APIs > they will have to learn to treat specially. > > Hugh > > > > > Marcin. > > > > --------------------------------------------------------------------- > > To unsubscribe from this list please visit: > > > > http://xircles.codehaus.org/manage_email > > > > > -- Blog: http://www.bloglines.com/blog/ThomasEEnebo Email: enebo@... , tom.enebo@... |
| Free embeddable forum powered by Nabble | Forum Help |