|
|
|
[
Permlink
| « Hide
]
Bill Dortch - 05/Apr/07 10:07 AM
This seems to be OS-dependent; the example works for me in WinXP/Java6/trunk.
It might be JDK version dependent. On both Linux & MacOSX, it works fine with JDK1.6.0, but fails with SystemStackError on JDK 1.5.0.
This is pretty severe...we need to tidy up issues like this for 0.9.9
This post from the jruby-user list might provide a clue:
At 1:49 PM -0500 3/18/07 on the jruby-user list Micah Martin <micah@8thlight.com wrote: I've been digging into the code.... It has something to do with the __jcreate! method when constructing the ConcreteProxy. There is a block that seems to get called for every method on the Panel class. It ends up in infinite recursion around the method "insets". I've been debugging it for a while but to be honest, I haven't been able to figure out what's causing the infinite recursion or what exactly that block of code is trying to accomplish. Any hints would be appreciated. def JavaUtilities.setup_java_subclass(subclass, java_class)
subclass.send(:define_method, "__jcreate!") {|*args|
Micah This is the code in question: require 'java' class MyPanel < java.awt.Panel frame = java.awt.Frame.new("test frame") frame.pack Further info:
The problem is triggered because Container#getInsets() just delegates to Container#insets(). When Container#insets is called, the Ruby proxy is invoked. This method is incorrectly bound to #getInsets() rather than #insets, and so infinite recursion results. I suspect the difference in behaviour seen between JDK5 and JDK6 is due to the different order of methods returned via reflection. Therefore, it's probably the case that the ruby method 'insets' that's declared as an alias of the property getter 'getInsets' stomps over the real 'insets' method (in JDK5). Seems like a proper definition of the rules needs to be figured out, and when the proxy class is created those rules must be followed. For example, when defining a friendly ruby property alias 'foo' for java method 'getFoo', this should only be used if there's not a real java method called 'foo'. As Jonathan notes, this appears to be a bug (oversimplification?) in JavaClass#define_instance_methods_for_proxy.
Here's another example, from Micah Martin on jruby-user: On 4/12/07, Micah Martin <micah@8thlight.com> wrote:
************ JAVA CODE **********
public class MyClass {
public void open() {
System.out.println("open()");
}
public boolean isOpen() {
System.out.println("isOpen()");
return false;
}
}
********** JRUBY CODE ***********
require 'java'
include_class 'MyClass'
mine = MyClass.new
mine.open
mine.is_open
mine.open?
********** OUTPUT *****************
isOpen()
isOpen()
isOpen()
Why is the open() method getting lost? How do I call it from JRuby?
I'm on mac os x 10.4.9, Java 1.5.
Micah
I just tried this on JRuby trunk (3494) and the original hello swing app started up ok. Can y'all re-test this? I know we have some additional fixes coming from Bill for these sorts of things, but at least the original case appears to work for me on OS X.
Mac6S 10.4.9, Java 1.5.0_07-164
updated to trunk: 3499 compiled new jruby with 'ant' ran my shell script: JRUBY_HOME=`pwd` export JRUBY_HOME PATH=`pwd`/bin:$PATH export PATH Here's the program helloswing.rb: require 'java'
class MyFrame < javax.swing.JFrame
def initialize
super("Hello Swing!")
pack
end
end
MyFrame.new.visible = true
Here are the errors reported: $ jruby helloswing.rb 2007-04-18 20:42:03.064 java[2076] CFLog (0): CFMessagePort: bootstrap_register(): failed 1103 (0x44f), port = 0x18403, name = 'java.ServiceProvider' See /usr/include/servers/bootstrap_defs.h for the error codes. 2007-04-18 20:42:03.065 java[2076] CFLog (99): CFMessagePortCreateLocal(): failed to name Mach port (java.ServiceProvider) /Users/stephen/dev/jruby-trunk/jruby/src/builtin/javasupport.rb:128 warning: already initialized constant EXIT_ON_CLOSE helloswing.rb:9:in `initialize': invokee not a java object (TypeError) from helloswing.rb:9:in `new' from helloswing.rb:9 The first three errors also appear when sucessfully running: samples/swing.rb . I'm pretty sure the first two are a Mac thing...I see them too, and I don't know that there's anything we can do to prevent them.
The initialize thing is still a bug...so we're closer but not quite. FYI: regarding the first two non-important error messages:
http://lists.apple.com/archives/Java-dev/2005/Jun/msg00546.html: Subject: Re: Eclipse launches java app. with error: CFMessagePort bootstrap_register(): failed 1103 The message is a system diagnostic telling you that more than one process tried to register Services (i.e. the Thanks Stephen...so I suppose it's a side effect of running multiple Java versions on the same system (since within a single version they should use the same in-memory HotSpot, but multiple versions wouldn't share HotSpots and would re-register...).
The remaining issues are scheduled to be fixed by Bill Dortch's uber-patch. Bill's patch for
This will be fixed when we commit the
FYI:
Just checked out r 3534. I still get: helloswing.rb:9:in `initialize': invokee not a java object (TypeError)
from helloswing.rb:9:in `new'
from helloswing.rb:9
running this program: require 'java'
class MyFrame < javax.swing.JFrame
def initialize
super("Hello Swing!")
pack
end
end
MyFrame.new.visible = true[~/dev/jr/sandbox/jruby]$
Still not fixed it seems...perhaps I should have double-checked that it was actually working...
This works on WinXP / Java 6 (on my desk). The problems seem to arise on Mac OS / Java 5. I've attached a diagnostic (jruby_778_diagnostic.rb, reproduced below) that may help shed some light on the problem. If folks could run it and report the results, I'd appreciate it.
Thanks, Bill jruby_778.diagnostic.rb: require 'java' class MyFrame < javax.swing.JFrame def initialize super puts "\nself = [#{self}]" puts "\nself.class = [#{self.class}]" if self.respond_to?(:java_class) puts "\nself.java_class = [#{self.java_class}]" else puts "\njava_class not defined" end if self.respond_to?(:java_object) puts "\nself.java_object = [#{self.java_object}]" puts "\njava_object JavaObject? = [#{self.java_object.kind_of?(Java::JavaObject)}]" puts "\njava_object.class = [#{self.java_object.class}]" else puts "\njava_object not defined" end end end MyFrame.new.visible = true Here's the output from jruby_778.diagnostic.rb Biill. I'm testing on:
jruby svn rev 3534 $ jruby jruby_778.diagnostic.rb self = [] self.class = [MyFrame] self.java_class = [javax.swing.JFrame] self.java_object = [] java_object JavaObject? = [false] java_object.class = [NilClass] Stephen,
Thanks for the quick feedback. There was something in the output that suggested you might not be running the latest JRuby trunk version (the EXIT_ON_CLOSE warning should not be there, and javasupport.rb is now well under 100 lines). I've attached a version check script (reproduced below) – if you could run it and report the output, I'd really appreciate it. BTW, this isn't to say that the bug isn't still there, I just want to make sure the symptoms are current. Thanks, Bill jruby_version_check.rb if defined?JRUBY_VERSION puts "JRUBY_VERSION = #{JRUBY_VERSION}" else puts "JRUBY_VERSION not defined" end include Java JFrame = javax.swing.JFrame puts "JFrame ancestors:" puts JFrame.ancestors.join("\n") Hi Bill,
I think the error you noticed mentioning EXIT_ON_CLOSE is happening because Java and JRuby are registering for services more than once. See my comment 10 up from here. Here are the results from running jruby_version_check.rb: $ jruby jruby_version_check.rb
JRUBY_VERSION not defined
jruby_version_check.rb:6:in `const_missing': uninitialized constant Java (NameError)
from jruby_version_check.rb:6
Here's more details from the shell: This is how I setup my environment: [~/dev/jr/sandbox/jruby]$ ./setpaths.sh [~/dev/jr/sandbox/jruby]$ cat setpaths.sh JRUBY_HOME=`pwd` export JRUBY_HOME PATH=`pwd`/bin:$PATH export PATH I got rev 3536 checked out: $ svn info Path: . URL: svn://svn.codehaus.org/jruby/trunk/jruby Repository Root: svn://svn.codehaus.org/jruby Repository UUID: 961051c9-f516-0410-bf72-c9f7e237a7b7 Revision: 3536 Node Kind: directory Schedule: normal Last Changed Author: headius Last Changed Rev: 3535 Last Changed Date: 2007-04-22 23:51:36 -0400 (Sun, 22 Apr 2007) Just in case I'll compile it again. [~/dev/jr/sandbox/jruby]$ ant
Buildfile: build.xml
init:
prepare:
compile.tasks:
[copy] Copying 1 file to /Users/stephen/dev/jr/sandbox/jruby/build/classes/jruby
check-for-optional-java4-packages:
check-for-optional-packages:
compile-jruby:
compile:
serialize:
generate-method-classes:
[touch] Creating /Users/stephen/dev/jr/sandbox/jruby/build/__empty.rb
[delete] Deleting: /Users/stephen/dev/jr/sandbox/jruby/build/__empty.rb
jar-jruby:
[jar] Building jar: /Users/stephen/dev/jr/sandbox/jruby/lib/jruby.jar
jar:
BUILD SUCCESSFUL
Total time: 19 seconds
And try running my test programs again: [~/dev/jr/sandbox/jruby]$ jruby helloswing.rb 2007-04-23 10:51:56.006 java[3273] CFLog (0): CFMessagePort: bootstrap_register(): failed 1103 (0x44f), port = 0x18403, name = 'java.ServiceProvider' See /usr/include/servers/bootstrap_defs.h for the error codes. 2007-04-23 10:51:56.007 java[3273] CFLog (99): CFMessagePortCreateLocal(): failed to name Mach port (java.ServiceProvider) /Users/stephen/dev/jruby-trunk/jruby/src/builtin/javasupport.rb:128 warning: already initialized constant EXIT_ON_CLOSE helloswing.rb:9:in `initialize': invokee not a java object (TypeError) from helloswing.rb:9:in `new' from helloswing.rb:9 [~/dev/jr/sandbox/jruby]$ jruby jruby_778.diagnostic.rb 2007-04-23 10:52:04.366 java[3276] CFLog (0): CFMessagePort: bootstrap_register(): failed 1103 (0x44f), port = 0x18103, name = 'java.ServiceProvider' See /usr/include/servers/bootstrap_defs.h for the error codes. 2007-04-23 10:52:04.366 java[3276] CFLog (99): CFMessagePortCreateLocal(): failed to name Mach port (java.ServiceProvider) /Users/stephen/dev/jruby-trunk/jruby/src/builtin/javasupport.rb:128 warning: already initialized constant EXIT_ON_CLOSE self = [] self.class = [MyFrame] self.java_class = [javax.swing.JFrame] self.java_object = [] java_object JavaObject? = [false] java_object.class = [NilClass] [~/dev/jr/sandbox/jruby]$ jruby jruby_version_check.rb JRUBY_VERSION not defined jruby_version_check.rb:6:in `const_missing': uninitialized constant Java (NameError) from jruby_version_check.rb:6 Stephen,
Hmm, strange, I see that you're checking out the current version, but you're definitely not running against it. The JRUBY_VERSION constant has been in for about a week, since build 3478 (see http://fisheye.codehaus.org/changelog/jruby/?cs=3478 While I don't see anything obviously wrong with your environment setup, I'm not really an expert on that sort of thing (even on Windows, which is my main platform). But I'd say you must have an older version of JRuby lying around somewhere, and somehow that's what is being run. Or maybe there's a build issue; have you tried "ant clean"? If you have time to play around with this, it would be great to know what your results are with the current build. The output from jruby_version_check.rb should look like this: JRUBY_VERSION = 0.9.9-pre JFrame ancestors: JFrame Java::JAVA.AWT.Frame Java::JAVA.AWT.Window Java::JAVA.AWT.Container Java::JAVA.AWT.Component Java::JAVA.LANG.Object ConcreteJavaProxy JavaProxy Object Java Kernel If you wait for the 0.9.9 release later today, you may not see the JAVA.AWT... class names; I think they'll be disabled for the release. But you should at least see a list of classes between JFrame and ConcreteJavaProxy. Thanks again for your feedback. Let me know what you find out. -Bill Hi Bill,
First – thanks very much for all your work and patience! You are right. I was running an older jruby. My problem was that I was executing my shell script by running it. Well that runs it in another shell so any of the parameters it sets are only valid until that shell exits – which is when my script finished (I should have known better). The right way to execute this kind of script is with the 'source' command (also aliased as '.') like this: $ source setpaths.sh This executes the script in the context of the current shell. Now JRUBY_HOME and PATH are set correctly. Would it make sense to log the JRUBY_VERSION and subversion revision to stderr? I wouldn't have wasted so much of your time. The code now seems to work. Here are my results: $ jruby helloswing.rb
2007-04-23 14:15:15.722 java[3524] CFLog (0): CFMessagePort: bootstrap_register(): failed 1103 (0x44f), port = 0x16603, name = 'java.ServiceProvider'
See /usr/include/servers/bootstrap_defs.h for the error codes.
2007-04-23 14:15:15.722 java[3524] CFLog (99): CFMessagePortCreateLocal(): failed to name Mach port (java.ServiceProvider)
except for the two (presumably harmless) in the console this roks fine. Here's the output from the diagnostic: [~/dev/jr/sandbox/jruby]$ jruby jruby_778.diagnostic.rb 2007-04-23 14:15:55.767 java[3526] CFLog (0): CFMessagePort: bootstrap_register(): failed 1103 (0x44f), port = 0x16903, name = 'java.ServiceProvider' See /usr/include/servers/bootstrap_defs.h for the error codes. 2007-04-23 14:15:55.768 java[3526] CFLog (99): CFMessagePortCreateLocal(): failed to name Mach port (java.ServiceProvider) self = [org.jruby.javasupport.proxy.gen.JFrame$Proxy0[frame0,0,22,0x0,invalid,hidden,layout=java.awt.BorderLayout,title=,resizable,normal,defaultCloseOperation=HIDE_ON_CLOSE,rootPane=javax.swing.JRootPane[,0,0,0x0,invalid,layout=javax.swing.JRootPane$RootLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=449,maximumSize=,minimumSize=,preferredSize=],rootPaneCheckingEnabled=true]] self.class = [MyFrame] self.java_class = [javax.swing.JFrame] self.java_object = [org.jruby.javasupport.proxy.gen.JFrame$Proxy0[frame0,0,22,0x0,invalid,hidden,layout=java.awt.BorderLayout,title=,resizable,normal,defaultCloseOperation=HIDE_ON_CLOSE,rootPane=javax.swing.JRootPane[,0,0,0x0,invalid,layout=javax.swing.JRootPane$RootLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=449,maximumSize=,minimumSize=,preferredSize=],rootPaneCheckingEnabled=true]] java_object JavaObject? = [true] java_object.class = [Java::JavaObject] And here's the output from the version check. [~/dev/jr/sandbox/jruby]$ jruby jruby_version_check.rb JRUBY_VERSION = 0.9.9-pre 2007-04-23 14:16:15.418 java[3528] CFLog (0): CFMessagePort: bootstrap_register(): failed 1103 (0x44f), port = 0x16703, name = 'java.ServiceProvider' See /usr/include/servers/bootstrap_defs.h for the error codes. 2007-04-23 14:16:15.418 java[3528] CFLog (99): CFMessagePortCreateLocal(): failed to name Mach port (java.ServiceProvider) JFrame ancestors: Java::JAVAX::SWING::JFrame Java::JAVA::AWT::Frame Java::JAVA::AWT::Window Java::JAVA::AWT::Container Java::JAVA::AWT::Component Java::JAVA::LANG::Object ConcreteJavaProxy JavaProxy Object Java Kernel Stephen,
Thanks for the follow up. I'm glad to see things are working for you now. I think we can mark this issue closed! Cheers, -Bill The comments compel me to resolve this issue
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||