Jay,

On 12/20/05, Jay Strauss <[EMAIL PROTECTED]> wrote:
> Hi, I'd like my Java to call an already instantiated perl object.  I tried the
> code below (plus other variations), but can't seem to make the right
> incantation.
>
> Is this possible?

You like to keep me on my toes, hey... :)

"Officially" this is not supported yet. If you only have a few
objects, you can get around it by storing your objects in a hash on
the perl side and calling a wrapper function that will dispatch the
method call to the proper object.

Or, you can use an undocument feature of Inline::Java called:
InlineJavaPerlObject. Here's how it would work in your case:

...
use Inline Java => <<'END';
   import org.perl.inline.java.* ;

   class callback extends InlineJavaPerlCaller {
       InlineJavaPerlObject Obj;
       public callback(InlineJavaPerlObject PerlObj) throws
InlineJavaException {
           Obj = PerlObj;
       }

       public void perl() throws InlineJavaException,
                                   InlineJavaPerlException {

           Obj.InvokeMethod("logic", new Object [] {"hi"}) ;
       }
   }
END


This should allow you to do what you want. However, the reason is it
not documented is that I am not 100% happy with the interface yet. The
problem is that this can lead to object leaks on the Perl side. When
you "send" a Perl object to the Java side, the object reference is
stored in a hash to make sure the the object stays alive while it is
being used on the Java side.

The problem is that the garbage collector in Java is crappy (IMOO) and
doesn't run very often (read never). That means that the Java part of
Inline::Java has no way of knowing when you are done with this object
on the Java side, therefore it stays in that hash indefinetely. The
way aroud this is to manually tell Inline::Java that you are done with
an object by calling:

  Obj.Dispose() ;

Note that you must do that each time you send a Perl object to the
Java side, even if it is the same object. That means that for every
time this line:

my $c = callback->new($obj);

is executed on the Perl side, you should execute Obj.Dispose() on the
Java side when
your are done using the Object. If you only call

my $c = callback->new($obj);

once and store the reference on the Java side (as shown in your
example), you only need
to call Obj.Dispose() once when you are done with the object.

See InlineJavaPerlObject.java for a list of methods that can be called
on an InlineJavaPerlObject.


Patrick
>
> Thanks
> Jay
>
> #!/usr/bin/perl
>
> package SomeObject;
>
> sub new {
>     my $class = shift;
>
>     bless {}, $class;
> }
>
> sub logic {
>
>     my ($self, $arg) = @_;
>     print "in logic: $arg \n";
> }
>
> package main;
>
>
> use Inline Java => <<'END';
>     import org.perl.inline.java.* ;
>
>     class callback extends InlineJavaPerlCaller {
>         String ObjName;
>         public callback(String Name) throws InlineJavaException {
>             ObjName = Name;
>         }
>
>         public void perl() throws InlineJavaException,
>                                     InlineJavaPerlException {
>
>             CallPerlSub(ObjName+"->logic()", new Object [] {}) ;
>         }
>     }
> END
>
>
> my $obj = SomeObject->new();
> my $c = callback->new($obj);
> $c->perl();
>


--
=====================
Patrick LeBoutillier
Laval, Québec, Canada

Reply via email to