
Java Support Overview
---------------------
$Revision: 1.2 $

JRuby has a new interface for loading and using Java classes as of
version 0.5.2.

Goals:

To make Java classes as easy to use as possible they should ideally
behave just like Ruby classes. In most cases this works flawlessly,
but when compromises have to be made they are not always right for
every purpose. The old Java support solved the first problem, but
didn't offer a solution when more control was needed.
The design goals for the new Java support was to keep the simplicity
of the old java support, but allow for low-level access with full
control whenever needed.

Design:

Java support was split into two halves, "low-level" and
"high-level". The low-level is implemented in Java and provides a thin
wrapper over Java's reflection classes (java.lang.reflection.* and
java.lang.Class). The high-level is built on top of this, implemented
entirely in Ruby(*).

Low-level:

It is probably easier to understand this API if you are familiar with
the Java Reflection API.

All Java objects used in Ruby code are wrapped in JavaObject
instances. On their own they can't do very much. But used together
with instances of JavaMethod, a method call can be made:

    java_method.invoke(java_object, arg1, arg2)

JavaClass, JavaMethod and JavaField are used to get information about
Java classes. Which methods and fields do they have, what interfaces
do they implement, are they final, static or public?
Everything that is possible to do in Java itself should be possible to
do with the low-level API, albeit in an awkward way.

High-level:

A raw JavaObject is not very useful for scripting. So instead we
use a JavaProxy, which has methods corresponding to the real Java
methods on the JavaObject. Every call to one of those methods is
implemented as a call though the low-level 'invoke' method. When using
the high-level API you will rarely come across a JavaObject, since every
returned value is automatically wrapped in a JavaProxy.

The only thing the script developer has to do is to load the
high-level support and include the wanted Java packages into a Ruby
class or module:

    require 'java'                 # Load the high-level Java support

    module Foo
      include_package 'java.util'  # Classes in java.util will be
                                   # available in this module

      r = Random.new               # Create instance of java.util.Random

      puts r.nextInt               # Write a random integer to output

    end

The 'int' returned from the Java method nextInt() is automatically
converted into a Fixnum. These conversions are automatically done for
numbers, booleans and strings, both to and from Java. However, it does
*not* convert collection and array types like the old Java support
did.


Copyright (c) Anders Bengtsson 2002

---------------------

*) We have used one method, Module.const_missing, that isn't (yet) in
 the standard Ruby version. Also the utility method
 Enumerable#group_by, implemented in pure Ruby.
