Eric,
I am not sure what the problem is with your classpath. I took a
cursory look and it seems like jruby.sh launch script takes classpath into
consideration. Perhaps someone else can tell you why it wasn't picked up?
In response to your points:
1) You got it.
2) Yes. However, include_class is not just hint to the runtime. It actually
scans the included java class and creates a Ruby class that acts as a proxy
for that Java class.
3) The Java:: prefix is a very neat trick in JRuby that utilizes Ruby's
concept of missing constant. When a Ruby runtime (JRuby or otherwise)
encounters reference to a constant (i.e. a ClassName) that it cannot find,
it calls const_missing. JRuby's Java support uses this to dynamically
intercept and load the associated Java class. This dynamic loader resides
under the Java module (hence you use the Java:: prefix), but is also created
in com, org, and a few others for convenience.
I agree that it would be nice to have links to each message. In the
past, when I posted mailing list reference to the wiki, I used Nabble's view
of the list:
http://www.nabble.com/JRuby---Dev-f14108.html
Peter
-----Original Message-----
From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED]
Sent: Thursday, August 23, 2007 6:33 PM
To: [email protected]
Subject: Re: [jruby-dev] Working with Java classes in JRuby
Much appreciate the follow up, Peter. I'm beginning
to penetrate to the second point. First, the invocation.
I'm in CSH, doing the following:
setenv CLASSPATH /path/to/foo.jar:/path/to/bar.jar
jruby export.rb
Where, "which jruby" goes to my jruby/1.0 install.
But you're absolutely right that the CLASSPATH setting
does not appear to be picked up. The script operates in
exactly the same way, whether or not CLASSPATH is defined
--which may well account for some of the otherwise mysterious
behavior I'm seeing.
As to the second point, your examples were very helpful:
1. Implicitly referenced classes do /not/ need to be included.
So for x = y.returnsFoo(), include_class Foo is /not/ needed
2. An explicit reference /does/ need a class inclusion.
(So include_class is more of a hint to the lexer/syntax
interpreter. It's not a runtime requirement).
x = Foo.new
3. As you indicate, Java:: is needed for a fully qualified
reference -- but only, I think, if the first package
name isn't one of the "magic" names (java, javax, com, org)
x = Java::my.package.Foo.new
y = javax.swing.JFrame.new(...)
PS
It would be nice if email messages came with a pointer to
the page that shows that message along with the thread
hierarchy it's in. I find those kinds of links to add to
my writeups.
Peter K Chan wrote:
> Eric,
> Interesting.
>
> For a), how are you invoking JRuby? Is it possible that your
> CLASSPATH setting is not even picked up by the JVM? From what I know, if
you
> don't need to load JAR in Java code, then you wouldn't have to load the
JAR
> explicitly in JRuby either.
>
> For b), once you include_class 'some.long.package.Foo', you can just
> refer to Foo as simply Foo. If you use the Java prefix with the short
name,
> it will fail.
>
> Let me clarify the last statement: if you are using Foo in an
> implicit setting, as in:
>
> x = get_a_foo(true)
> x.bar(2 + 3) # No problem here if you don't include_class 'Foo'
>
> But if you want to explicitly work with Foo, such as:
>
> x = Foo.new
> y = Java::some.long.package.Foo.new
> return true if x.is_a?(Foo)
>
> then you will need to explicitly include_class 'Foo', or use the
> long syntax, as the second case above.
>
> Peter
>
> -----Original Message-----
> From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED]
> Sent: Wednesday, August 22, 2007 7:35 PM
> To: [email protected]
> Subject: Re: [jruby-dev] Working with Java classes in JRuby
>
> Hi, Peter.
>
> Your comments match my expectation, based on what I had read.
> But what I found was that:
>
> a) Putting the jar in the CLASSPATH was not sufficient.
> An include_class statement failed with "class not found"
> until the JAR was also required in the code. (For JVM core
> classes, it seems that "require 'java'" does that for rt.jar.)
>
> b) It's good to hear that steps 3 & 4 are substitutes for each
> other. I did find it a surprise, however, that after
> include_class "some.long.package.Foo"
> a reference to Java::Foo failed. It was necessary to fully
> qualify the name again (Java::some.long.package.Foo).
>
> Also, I didn't quite follow this bit:
>
> "You only need to include Java classes if you need to refer
> to them by name explicitly."
>
> I would have thought the reverse of that--that I only need to
> include the class explicitly if I'm referring to the name
> implicitly (as when x receives the type Foo without a declaration):
> ^^
>
> x = Java::a.package.MyClass.someMethodThatReturnsFoo()
>
>
>
> Peter K Chan wrote:
>> Eric,
>> I think most of your steps are correct. I suspect that if you are
>> including the JAR on the JVM CLASSPATH, you would not need to require the
>> JAR individually (JRuby can resolve the class using normal Java
>> classloading).
>>
>> 3 and 4 are substitutes for each other. Use one or the other, or
>> both. If you want to avoid namespace pollution, you may want to use
Java::
>> prefix (or there is another form that only imports into a specific Ruby
>> namespace, but I don't remember off my head).
>>
>> If your type is Foo, you don't need to include_class Foo. JRuby uses
>> reflection and can figure out the type by itself. You only need to
include
>> Java classes if you need to refer to them by name explicitly.
>>
>> Peter
>>
>> -----Original Message-----
>> From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED]
>> Sent: Wednesday, August 22, 2007 7:10 PM
>> To: jruby-dev
>> Subject: [jruby-dev] Working with Java classes in JRuby
>>
>> http://java.sun.com/developer/technicalArticles/scripting/jruby/
>> http://www.headius.com/jrubywiki/index.php/Calling_Java_from_JRuby
>>
>> After examining those writeups and doing a lot of experimenting,
>> I've been able to make 3rd party Java classes accessible by doing
>> the following:
>>
>> 1. Putting the JAR files in the CLASSPATH
>> (or $RUBY_HOME/lib)
>>
>> AND 2. Requiring each jar individually
>>
>> AND 3. Doing an include_class on each class I want to access,
>> using a fully qualified package name.
>>
>> AND 4. Using the Java:: prefix when naming one of classes in
>> the code.
>>
>> Comments:
>> * Doing steps 1, 3, and 4 didn't seem to work until I added step 2.
>> * I haven't tried steps 1 and 2 by themselves.
>> * I suspect that either step 3 or 4 is needed, but both are
>> not required. So if this method returns a Foo object:
>> x = Java::some.package.MyClass.staticGetMethod()
>>
>> then:
>> include_class is probably /not/ necessary for MyClass
>> include_class probably /is/ necessary for Foo
>>
>> Is that substantially correct, or are parts of it overkill?
>>
>
>
--
Eric Armstrong, Document Systems Architect, Sun Microsystems
http://blogs.sun.com/coolstuff
http://www.artima.com/weblogs/index.jsp?blogger=cooltools
---------------------------------------------------------------------
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