Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Problems calling getValue on Action object #1654

Closed
rhinton opened this issue Apr 24, 2014 · 8 comments
Closed

Problems calling getValue on Action object #1654

rhinton opened this issue Apr 24, 2014 · 8 comments

Comments

@rhinton
Copy link

rhinton commented Apr 24, 2014

I can't figure out what I'm doing wrong here. The Java code works. All the Ruby permutations fail. How can I get the values I want?

EDIT: Conversation on [jruby-user] on 8 Apr 2014 confirms this is a JRuby bug.

deleteme.java:

import java.io.*;
import javax.swing.*;

class Deleteme {
    public static void main(String args[]) throws IOException {
        String str;
        str = (String)TransferHandler.getCutAction().getValue(Action.NAME);
        System.out.println("Cut action name is: " + str);
        str = (String)TransferHandler.getCopyAction().getValue(Action.NAME);
        System.out.println("Copy action name is: " + str);
        str = (String)TransferHandler.getPasteAction().getValue(Action.NAME);
        System.out.println("Paste action name is: " + str);
    }
}

Results from running deleteme.java:

$ javac deleteme.java
$ java Deleteme
Cut action name is: cut
Copy action name is: copy
Paste action name is: paste

Now the ruby code in deleteme.rb:

require 'java'

# Easier way to do this at file scope?  Normally I would just include_package
# 'javax.swing' in my class.
java_import javax.swing.TransferHandler
java_import javax.swing.Action


name = TransferHandler.getCutAction.getValue(Action.NAME)
puts "Cut action name is: #{name}"
name = TransferHandler.getCopyAction.getValue(Action.NAME)
puts "Copy action name is: #{name}"
name = TransferHandler.getPasteAction.getValue(Action.NAME)
puts "Paste action name is: #{name}"

# try really hard
action = TransferHandler.getCutAction
name = action.java_send(:getValue, [java.lang.String], Action.NAME)
puts "Cut action #{action.inspect} name is: #{name}"

# try another way; doesn't work because getValue takes an argument
#name = TransferHandler.getCutAction.value(Action.NAME)
#puts "Cut action name is: #{name}"

# try another way
meth = action.java_method(:getValue, [java.lang.String])
puts "Cut action name is: #{meth.call(Action.NAME)}"
puts "Cut action name is: #{meth.call(Action.NAME.to_java)}"

Results of running deleteme.rb:

$ jruby deleteme.rb
Cut action name is: 
Copy action name is: 
Paste action name is: 
Cut action #<Java::JavaxSwing::TransferAction:0x7548c02f> name is: 
Cut action name is: 
Cut action name is: 
$ jruby --version
jruby 1.7.4 (1.9.3p392) 2013-05-16 2390d3b on OpenJDK 64-Bit Server VM 1.6.0_22-b22 [linux-amd64]

C:\...> jruby deleteme.rb
[all names still missing]
C:\...> jruby --version
jruby 1.7.10 (1.9.3p392) 2014-01-09 c4ecd6b on Java HotSpot(TM) Client VM 1.6.0_37-b06 [Windows 7-x86]
@kwando
Copy link

kwando commented Apr 24, 2014

Try reference Action.NAME with Action::NAME in the ruby code instead.

@rhinton
Copy link
Author

rhinton commented Apr 24, 2014

I have no problem getting the action constants (although it looks wrong, now that you mention it). I've tried calling getValue with the appropriate strings hard-coded. It's the getValue call that isn't working.

@kwando
Copy link

kwando commented Apr 24, 2014

Maybe this?

TransferHandler.cut_action.value(Action::NAME)

I have no clue really, I bet someone who actually knows will come by soon =)

@rtyler
Copy link

rtyler commented Aug 7, 2015

I've been tinkering with this a bit on JRuby 9k and I can't for the life of me figure out why the getValue() method won't be called correctly. But I did discover that you can access the name field on the Action object:

[16] pry(main)> TransferHandler.copy_action.name
=> "copy"
[17] pry(main)> TransferHandler.cut_action.name
=> "cut"
[18] pry(main)> TransferHandler.paste_action.name
=> "paste"
[19] pry(main)> 

@enebo
Copy link
Member

enebo commented Aug 10, 2015

I think this is a problem with how JI works and how the underlying Swing code is written. I find this to be a primal limitation of our automatic coercion so it is not something we can actually fix. I will mark as WONTFIX, but I will show you how to work around this and why it is happening.

Look at http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/sun/swing/UIAction.java#72

We can see that this code is weird. Namely: 'key == NAME'. In JRuby, we convert between Java <-> Ruby string types. When we get the value of NAME we convert to a Ruby String and then when we call getValue we convert it back to a Java String. Since it is a new Java String then Java object identity fails and it returns null. The good news is when people use Java Object identity with Strings they also tend to intern() the string value. So you can make all this work by intern'ing your string:

name = TransferHandler.getCutAction.getValue(Action::NAME.intern)

Things will work. I wonder why they did not use .equals() in this code since this could not possibly be a hot path in Swing?

@enebo enebo closed this as completed Aug 10, 2015
@enebo enebo added this to the Won't Fix milestone Aug 10, 2015
@rtyler
Copy link

rtyler commented Aug 10, 2015

@enebo this wasn't my ticket but I definitely appreciate you dropping some knowledge on us :)

@enebo
Copy link
Member

enebo commented Aug 10, 2015

@rtyler your excellent triaging and pondering what was wrong had me dig in. So thanks for updating the issue. This one was quite old :)

@rhinton
Copy link
Author

rhinton commented Dec 11, 2015

Thanks all for the answers and information!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants