JRuby: How does one keep Java objects as Java objects so they can be used in method calls?

I'm trying to use JDOM and JRuby (yes I know about RexML). In the following
program, I get an error when I pass f to sb.build because f is a RubyFile and
not a Java File object. The error I get is:

no method 'build' with argument types matching [org.jruby.RubyFile] (NameError)

What is the correct way to deal with this, I believe, common issue?

Thanks,
Steve

···

------
require 'java'

class Foo
  include_package 'java.io'
  include_package 'org.jdom'
  include_package 'org.jdom.input'

  attr_reader :d

  def initialize
    sb = SAXBuilder.new
    f = File.new "/home/drach/schema/modeler/build.xml"
    @d = sb.build f
  end
end

foo=Foo.new

On Sat, 19 Jun 2004, Steve Drach defenestrated me:

I'm trying to use JDOM and JRuby (yes I know about RexML). In the following
program, I get an error when I pass f to sb.build because f is a RubyFile and
not a Java File object. The error I get is:

no method 'build' with argument types matching [org.jruby.RubyFile]
(NameError)

What is the correct way to deal with this, I believe, common issue?

  Well one way is to create a 'java_alias' ala:

java_alias :JFile, :File

  then use 'JFile.new "/etc/blah"'

  I actually think that your original code should have worked, but
it doesn't. In ruby:

module One
  class File
    def initialize(a, b)
    end
  end
end

Class Two
  include One

  def foo
    p File.new("/etc/motd", "r")
  end
end

  Will see One::File instead of File. At the surface I would think
that include_package should work similiarly. I will likely change this
behavior before next release unless someone can explain why doing so
would be a bad idea.

-Tom

···

--
+ http://www.tc.umn.edu/~enebo +---- mailto:enebo@acm.org ----+

Thomas E Enebo, Protagonist | "A word is worth a thousand |
                             > pictures" -Bruce Tognazzini |

Well one way is to create a 'java_alias' ala:

java_alias :JFile, :File

then use 'JFile.new "/etc/blah"'

Ok, I think I understand. It's because the constant File was already
defined to be the org.jruby.RubyFile class. Is that correct? And
java_alias just deals with Java constants? Is that why alias wouldn't
work, since it would have aliased the RubyFile to JFile? It's all
a little subtle for me.

In any case, it seems to work, and both File and SAXBuilder are
the correctly scoped type (symbol?) now. However it now fails
mysteriously, not telling me which method is missing:

jruby-0.7.0/bin/jruby.sh test.rb
Foo::SAXBuilder
Foo::JFile
Exception in thread "main" java.lang.NoSuchMethodError
at org.jruby.javasupport.JavaSupport.createRaiseException(JavaSupport.java:83)

The new code is:

require 'java'

class Foo
  include_package 'java.io'
  include_package 'org.jdom'
  include_package 'org.jdom.input'

  java_alias :JFile, :File

  attr_reader :d

  def initialize
    sb = SAXBuilder.new
    p sb.class
    f = JFile.new "/home/drach/schema/modeler/build.xml"
    p f.class
    @d = sb.build f
  end
end

foo = Foo.new

On Sun, 20 Jun 2004, Steve Drach defenestrated me:

>
> Well one way is to create a 'java_alias' ala:
>
>java_alias :JFile, :File
>
> then use 'JFile.new "/etc/blah"'

Ok, I think I understand. It's because the constant File was already
defined to be the org.jruby.RubyFile class. Is that correct? And
java_alias just deals with Java constants? Is that why alias wouldn't
work, since it would have aliased the RubyFile to JFile? It's all
a little subtle for me.

  yep. I was not the designer of the java integration so I can only
make an educated guess, but I think a decision was made to lazily
load classes from an imported package when they are actually used.
It implements this via const_missing. Obviously, for File, const_missing
is never fired, so I think they made java_alias as a way around this
problem. I sent some more thoughts on this to jruby-dev last night.
Any continued conversation about this should probably continue there.

In any case, it seems to work, and both File and SAXBuilder are
the correctly scoped type (symbol?) now. However it now fails
mysteriously, not telling me which method is missing:

In the current CVS tree I think this problem is fixed (along
with many others). I tried running your script (using another
xml file) and I did not get your error (no news is good news? :)).

A problem was corrected where it was not properly finding the
correct overloaded method in a java class. SaxBuiler.build has
a about thousand versions, so I am guessing it has tripped over that
bug.

-Tom

PS- Could you send any other jruby questions to jruby-user or
jruby-dev (hosted by sourceforge)? It will make jruby not look
so dead :slight_smile:

···

--
+ http://www.tc.umn.edu/~enebo +---- mailto:enebo@acm.org ----+

Thomas E Enebo, Protagonist | "A word is worth a thousand |
                             > pictures" -Bruce Tognazzini |