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

Reply via email to