[libinline-java-perl] 302/398: On the way to 0.48 with InlineJavaPerlObject

Jonas Smedegaard dr at jones.dk
Thu Feb 26 11:43:16 UTC 2015


This is an automated email from the git hooks/post-receive script.

js pushed a commit to tag 0.55
in repository libinline-java-perl.

commit 4dddfe0403a0bd89ba687d983f57974e1fd4a7a5
Author: patrick_leb <>
Date:   Sat Mar 20 14:16:38 2004 +0000

    On the way to 0.48 with InlineJavaPerlObject
---
 Java.pm                                            |  17 ++-
 Java.pod                                           |   2 +-
 Java/Array.pm                                      |   2 +-
 Java/Callback.pm                                   | 139 ++++++++++++++++---
 Java/Class.pm                                      |  63 ++++++---
 Java/JNI.pm                                        |   2 +-
 Java/JNI.xs                                        |   8 +-
 Java/JVM.pm                                        |   2 +-
 Java/Makefile.PL                                   |  14 +-
 Java/Natives/Natives.pm                            |   2 +-
 Java/Object.pm                                     |   2 +-
 Java/PerlInterpreter/PerlInterpreter.pm            |  19 ---
 ...1_perl_interpreter.pl => 01_perl_interpreter.t} |   0
 Java/Portable.pm                                   |   2 +-
 Java/Protocol.pm                                   |  46 +++++--
 .../org/perl/inline/java/InlineJavaCallback.java   |  41 +++++-
 .../org/perl/inline/java/InlineJavaClass.java      |  17 ++-
 .../org/perl/inline/java/InlineJavaPerlCaller.java |  93 +++++++++++--
 .../inline/java/InlineJavaPerlInterpreter.java     |  10 --
 .../org/perl/inline/java/InlineJavaPerlObject.java |  73 ++++++++++
 .../org/perl/inline/java/InlineJavaProtocol.java   |  29 ++--
 .../org/perl/inline/java/InlineJavaServer.java     |  13 +-
 MANIFEST                                           |   1 +
 META.yml                                           |   2 +-
 Makefile.PL                                        |   4 +-
 TODO                                               |  10 +-
 t/03_objects.t                                     |   4 +-
 t/12_1_callbacks.t                                 |  40 ++++--
 t/12_2_perl_objects.t                              | 151 +++++++++++++++++++++
 29 files changed, 659 insertions(+), 149 deletions(-)

diff --git a/Java.pm b/Java.pm
index f392d17..5e153be 100644
--- a/Java.pm
+++ b/Java.pm
@@ -2,13 +2,13 @@ package Inline::Java ;
 @Inline::Java::ISA = qw(Inline Exporter) ;
 
 # Export the cast function if wanted
- at EXPORT_OK = qw(cast study_classes caught jar) ;
+ at EXPORT_OK = qw(cast study_classes caught jar j2sdk) ;
 
 
 use strict ;
 require 5.006 ;
 
-$Inline::Java::VERSION = '0.47' ;
+$Inline::Java::VERSION = '0.48' ;
 
 
 # DEBUG is set via the DEBUG config
@@ -48,6 +48,7 @@ my $JVM = undef ;
 # This list will store the $o objects...
 my @INLINES = () ;
 
+my $report_version = "V2" ;
 
 # This stuff is to control the termination of the Java Interpreter
 sub done {
@@ -85,6 +86,11 @@ sub import {
 			print Inline::Java::Portable::get_server_jar() ;
 			exit() ;
 		}
+		elsif ($a eq 'j2sdk'){
+			print Inline::Java->find_default_j2sdk() . " says '" .
+				Inline::Java::get_default_j2sdk() . "'\n" ;
+			exit() ;
+		}
 	}
     Inline::Java->export_to_level(1, @_) ;
 }
@@ -596,6 +602,13 @@ sub load_jdat {
 
 	my $idx = 0 ;
 	my $current_class = undef ;
+	if (scalar(@{$lines})){
+		my $vline = shift @{$lines} ;
+		chomp($vline) ;
+		if ($vline ne $report_version){
+			croak("Report version mismatch ($vline != $report_version). Delete your '_Inline' and try again.") ; 
+		}
+	}
 	foreach my $line (@{$lines}){
 		chomp($line) ;
 		if ($line =~ /^class ($re) ($re|null)$/){
diff --git a/Java.pod b/Java.pod
index d3e8e0b..31ff123 100644
--- a/Java.pod
+++ b/Java.pod
@@ -93,7 +93,7 @@ used was stored in a file called default_j2sdk.pl that resides with
 the C<Inline::Java> module. You can find this file by using the following
 command:
 
-    % perl -MInline::Java -e 'print Inline::Java->find_default_j2sdk()'
+    % perl -MInline::Java=j2sdk
 
 If you wish to permanently change the default Java 2 SDK that is used
 by C<Inline::Java>, edit this file and change the value found there. 
diff --git a/Java/Array.pm b/Java/Array.pm
index fdf6e1b..5883b77 100644
--- a/Java/Array.pm
+++ b/Java/Array.pm
@@ -4,7 +4,7 @@ package Inline::Java::Array ;
 use strict ;
 use Carp ;
 
-$Inline::Java::Array::VERSION = '0.47' ;
+$Inline::Java::Array::VERSION = '0.48' ;
 
 # Here we store as keys the knots and as values our blessed objects
 my $OBJECTS = {} ;
diff --git a/Java/Callback.pm b/Java/Callback.pm
index 745a418..485667e 100644
--- a/Java/Callback.pm
+++ b/Java/Callback.pm
@@ -3,11 +3,14 @@ package Inline::Java::Callback ;
 use strict ;
 use Carp ;
 
-$Inline::Java::Callback::VERSION = '0.47' ;
+$Inline::Java::Callback::VERSION = '0.48' ;
 
 $Inline::Java::Callback::OBJECT_HOOK = undef ;
 
 
+my %OBJECTS = () ;
+my $next_id = 1 ;
+
 
 sub InterceptCallback {
 	my $inline = shift ;
@@ -19,18 +22,21 @@ sub InterceptCallback {
 		$inline = $Inline::Java::JNI::INLINE_HOOK ;
 	}
 
-	if ($resp =~ s/^callback ([^ ]+) (\w+) ([^ ]+)//){
-		my $module = $1 ;
+	if ($resp =~ s/^callback ([^ ]+) ([\w:]+) ([^ ]+)//){
+		my $via = $1 ;
 		my $function = $2 ;
 		my $cast_return = $3 ;
 		my @args = split(' ', $resp) ;
 
 		# "Relative" namespace...
-		if ($module =~ /^::/){
-			$module = $inline->get_api('pkg') . $module ;
+		if ($via =~ /^::/){
+			$via = $inline->get_api('pkg') . $via ;
 		}
-
-		return Inline::Java::Callback::ProcessCallback($inline, $module, $function, $cast_return, @args) ;
+		if ($function =~ /^::/){
+			$function = $inline->get_api('pkg') . $function ;
+		}
+		
+		return Inline::Java::Callback::ProcessCallback($inline, $via, $function, $cast_return, @args) ;
 	}
 
 	croak "Malformed callback request from server: $resp" ;
@@ -39,7 +45,7 @@ sub InterceptCallback {
 
 sub ProcessCallback {
 	my $inline = shift ;
-	my $module = shift ;
+	my $via = shift ;
 	my $function = shift ;
 	my $cast_return = shift ;
 	my @sargs = @_ ;
@@ -53,12 +59,30 @@ sub ProcessCallback {
 			$a ;
 		} @sargs ;
 
-		Inline::Java::debug(2, "processing callback $module" . "::" . "$function(" . 
-			join(", ", @args) . ")") ;
-
 		no strict 'refs' ;
-		my $sub = "$module" . "::" . $function ;
-		$ret = $sub->(@args) ;
+		if ($via =~ /^(\d+)$/){
+			# Call via object
+			my $id = $1 ;
+			Inline::Java::debug(2, "processing callback $id" . "->" . "$function(" . 
+				join(", ", @args) . ")") ;
+			my $obj = Inline::Java::Callback::GetObject($id) ;
+			$ret = $obj->$function(@args) ;
+		}
+		elsif ($via ne 'null'){
+			# Call via package
+			Inline::Java::debug(2, "processing callback $via" . "->" . "$function(" . 
+				join(", ", @args) . ")") ;
+			$ret = $via->$function(@args) ;
+		}
+		else {
+			# Straight call
+			Inline::Java::debug(2, "processing callback $function(" . 
+				join(", ", @args) . ")") ;
+			if ($function !~ /::/){
+				$function = 'main' . '::' . $function ;
+			}
+			$ret = $function->(@args) ;
+		}
 	} ;
 	if ($@){
 		$ret = $@ ;
@@ -69,12 +93,7 @@ sub ProcessCallback {
 		}
 	}
 
-	my $proto = 'java.lang.Object' ;
-	if ($cast_return ne "null"){
-		$ret = Inline::Java::cast($proto, $ret, $cast_return) ;
-	}
-
-	($ret) = Inline::Java::Class::CastArgument($ret, $proto, $inline) ;
+	($ret) = Inline::Java::Class::CastArgument($ret, $cast_return, $inline) ;
 	
 	# Here we must keep a reference to $ret or else it gets deleted 
 	# before the id is returned to Java...
@@ -86,5 +105,87 @@ sub ProcessCallback {
 }
 
 
+sub GetObject {
+	my $id = shift ;
+
+	my $obj = $OBJECTS{$id} ;
+	if (! defined($obj)){
+		croak("Can't find object $id") ;
+	}
+
+	return $obj ;
+}
+
+
+sub PutObject {
+	my $obj = shift ;
+
+	my $id = $next_id ;
+	$next_id++ ;
+
+	$OBJECTS{$id} = $obj ;
+
+	return $id ;
+}
+
+
+sub DeleteObject {
+	my $id = shift ;
+	my $quiet = shift || 0 ;
+
+	my $obj = delete $OBJECTS{$id} ;
+	if ((! $quiet)&&(! defined($obj))){
+		croak("Can't find object $id") ;
+	}
+}
+
+
+sub ObjectCount {
+	return scalar(keys %OBJECTS) ;
+}
+
+
+########## Utility methods used by Java to access Perl objects #################
+
+
+sub java_eval {
+    my $code = shift ;
+
+	Inline::Java::debug(3, "evaling Perl code: $code") ; 
+    my $ret = eval $code ;
+    if ($@){
+        die($@) ;
+    }
+
+    return $ret ;
+}
+
+
+sub java_require {
+    my $module = shift ;
+	my $is_file = shift ;
+
+	if (! defined($is_file)){
+		if (-e $module){
+			$module = '"$module"' ;
+		}
+	}
+
+	if ($is_file){
+		$module = '"$module"' ;
+	}
+
+	Inline::Java::debug(3, "requiring Perl module/file: $module") ; 
+    return java_eval("require $module ;") ;
+}
+
+
+sub java_finalize {
+	my $id = shift ;
+	my $gc = shift ;
+
+	Inline::Java::Callback::DeleteObject($id, $gc) ;
+}
+
 
 1 ;
diff --git a/Java/Class.pm b/Java/Class.pm
index 304e7b3..5148b56 100644
--- a/Java/Class.pm
+++ b/Java/Class.pm
@@ -3,7 +3,7 @@ package Inline::Java::Class ;
 use strict ;
 use Carp ;
 
-$Inline::Java::Class::VERSION = '0.47' ;
+$Inline::Java::Class::VERSION = '0.48' ;
 
 $Inline::Java::Class::MAX_SCORE = 10 ;
 
@@ -158,7 +158,10 @@ sub CastArgument {
 			else{
 				if (ref($arg)){
 					# We got some other type of ref...
-					croak "Can't convert $arg to object $proto" ;
+					if ($arg !~ /^(.*?)=/){
+						# We do not have a blessed reference, so ...
+						croak "Can't convert $arg to object $proto" ;
+					}
 				}
 				else{
 					# Here we got a scalar
@@ -246,26 +249,46 @@ sub CastArgument {
 			# Here the prototype calls for an object of type $proto
 			# We must ask Java if our object extends $proto		
 			if (ref($arg)){
-				my ($msg, $score) = $arg->__isa($proto) ;
-				if ($msg){
-					croak $msg ;
-				}
-				Inline::Java::debug(3, "$arg is a $proto") ;
-
-				# a matching object, pretty good match, except if proto
-				# is java.lang.Object
-				if ($proto eq "java.lang.Object"){	
-					return ($arg, 1) ;
-				}
+				if ((UNIVERSAL::isa($arg, "Inline::Java::Object"))||(UNIVERSAL::isa($arg, "Inline::Java::Array"))){
+					my ($msg, $score) = $arg->__isa($proto) ;
+					if ($msg){
+						croak $msg ;
+					}
+					Inline::Java::debug(3, "$arg is a $proto") ;
+	
+					# a matching object, pretty good match, except if proto
+					# is java.lang.Object
+					if ($proto eq "java.lang.Object"){	
+						return ($arg, 1) ;
+					}
 				
-				# Here we deduce points the more our argument is "far"
-				# from the prototype.
-				if (! UNIVERSAL::isa($arg, "Inline::Java::Array")){
-					return ($arg, 7 - ($score * 0.01)) ;
+					# Here we deduce points the more our argument is "far"
+					# from the prototype.
+					if (! UNIVERSAL::isa($arg, "Inline::Java::Array")){
+						return ($arg, 7 - ($score * 0.01)) ;
+					}
+					else{
+						# We need to keep the array score somewhere...
+						return ($arg, $array_score) ;
+					}
 				}
-				else{
-					# We need to keep the array score somewhere...
-					return ($arg, $array_score) ;
+				else {
+					# We want to send a Perl object to the Java side.
+					my $ijp = new Inline::Java::Protocol(undef, $inline) ;
+					my ($msg, $score) = $ijp->__ISA($proto, 'org.perl.inline.java.InlineJavaPerlObject') ;
+					if ($msg){
+						croak $msg ;
+					}
+					Inline::Java::debug(3, "$arg is a $proto") ;
+					
+					# a matching object, pretty good match, except if proto
+					# is java.lang.Object
+					if ($proto eq "java.lang.Object"){	
+						return ($arg, 1) ;
+					}
+					else{
+						return ($arg, 7 - ($score * 0.01)) ;
+					}
 				}
 			}
 
diff --git a/Java/JNI.pm b/Java/JNI.pm
index cc1e76b..5807825 100644
--- a/Java/JNI.pm
+++ b/Java/JNI.pm
@@ -4,7 +4,7 @@ package Inline::Java::JNI ;
 
 use strict ;
 
-$Inline::Java::JNI::VERSION = '0.47' ;
+$Inline::Java::JNI::VERSION = '0.48' ;
 
 use DynaLoader ;
 use Carp ;
diff --git a/Java/JNI.xs b/Java/JNI.xs
index d72d15d..4dd8c46 100644
--- a/Java/JNI.xs
+++ b/Java/JNI.xs
@@ -11,7 +11,6 @@
 typedef struct {
 	JavaVM *jvm ;
 	jclass ijs_class ;
-	jclass string_class ;
 	jobject	ijs ;
 	jmethodID jni_main_mid ;
 	jmethodID process_command_mid ;
@@ -201,8 +200,7 @@ new(CLASS, classpath, args, embedded, debug)
 	/* Load the classes that we will use */
 	RETVAL->ijs_class = (*(env))->FindClass(env, "org/perl/inline/java/InlineJavaServer") ;
 	check_exception_from_perl(env, "Can't find class InlineJavaServer") ;
-	RETVAL->string_class = (*(env))->FindClass(env, "java/lang/String") ;
-	check_exception_from_perl(env, "Can't find class java.lang.String") ;
+	RETVAL->ijs_class = (*(env))->NewGlobalRef(env, RETVAL->ijs_class) ;
 
 	/* Get the method ids that are needed later */
 	RETVAL->jni_main_mid = (*(env))->GetStaticMethodID(env, RETVAL->ijs_class, "jni_main",
@@ -254,6 +252,7 @@ create_ijs(this)
 	env = get_env(this) ;
 	this->ijs = (*(env))->CallStaticObjectMethod(env, this->ijs_class, this->jni_main_mid, this->debug) ;
 	check_exception_from_perl(env, "Can't call jni_main in class InlineJavaServer") ;
+	this->ijs = (*(env))->NewGlobalRef(env, this->ijs) ;
 
 
 
@@ -274,7 +273,7 @@ process_command(this, data)
 	check_exception_from_perl(env, "Can't create java.lang.String") ;
 
 	resp = (*(env))->CallObjectMethod(env, this->ijs, this->process_command_mid, cmd) ;
-	/* Thanks Dave Blob for spotting this. This is necessary since this codes never really returns to Java
+	/* Thanks Dave Blob for spotting this. This is necessary since this code never really returns to Java
 	   It simply calls into Java and comes back. */
 	(*(env))->DeleteLocalRef(env, cmd);
 	check_exception_from_perl(env, "Can't call ProcessCommand in class InlineJavaServer") ;
@@ -288,4 +287,5 @@ process_command(this, data)
 	RETVAL
 
 	CLEANUP:
+	(*(env))->DeleteLocalRef(env, resp) ;
 	(*(env))->ReleaseStringUTFChars(env, resp, RETVAL) ;
diff --git a/Java/JVM.pm b/Java/JVM.pm
index 04d8986..f96e762 100644
--- a/Java/JVM.pm
+++ b/Java/JVM.pm
@@ -7,7 +7,7 @@ use IPC::Open3 ;
 use IO::File ;
 use IO::Socket ;
 
-$Inline::Java::JVM::VERSION = '0.47' ;
+$Inline::Java::JVM::VERSION = '0.48' ;
 
 my %SIGS = () ;
 
diff --git a/Java/Makefile.PL b/Java/Makefile.PL
index 1ec9906..56cfbbd 100644
--- a/Java/Makefile.PL
+++ b/Java/Makefile.PL
@@ -138,11 +138,19 @@ TXT
 			if (AskYN("Do you wish to build the PerlNatives extension?", 'n')){
 				push @{$DIR}, 'Natives' ;
 			}
+			print "\n" ;
 
-			# Not quite yet...
-			# push @{$DIR}, 'PerlInterpreter' ;
-
+			print <<TXT;
+The PerlInterpreter extension allows Inline::Java to be loaded directly from
+Java using an embedded PerlInterpreter. It is still EXPERIMENTAL and 
+currently builds and works only with gcc under Linux. See documentation for 
+more details.
+TXT
+			if (AskYN("Do you wish to build the PerlInterpreter extension?", 'n')){
+				push @{$DIR}, 'PerlInterpreter' ;
+			}
 			print "\n" ;
+
 			WriteMakefile(
 				NAME => 'Inline::Java::JNI',
 				VERSION_FROM => 'JNI.pm',
diff --git a/Java/Natives/Natives.pm b/Java/Natives/Natives.pm
index 34e4d80..7558fa9 100644
--- a/Java/Natives/Natives.pm
+++ b/Java/Natives/Natives.pm
@@ -2,6 +2,6 @@ package Inline::Java::Natives ;
 
 use strict ;
 
-$Inline::Java::Natives::VERSION = '0.47' ;
+$Inline::Java::Natives::VERSION = '0.48' ;
 
 1 ;
diff --git a/Java/Object.pm b/Java/Object.pm
index 6692a67..e64ec34 100644
--- a/Java/Object.pm
+++ b/Java/Object.pm
@@ -5,7 +5,7 @@ use strict ;
 use Inline::Java::Protocol ;
 use Carp ;
 
-$Inline::Java::Object::VERSION = '0.47' ;
+$Inline::Java::Object::VERSION = '0.48' ;
 
 # Here we store as keys the knots and as values our blessed private objects
 my $PRIVATES = {} ;
diff --git a/Java/PerlInterpreter/PerlInterpreter.pm b/Java/PerlInterpreter/PerlInterpreter.pm
index 0ff26bd..7b97089 100644
--- a/Java/PerlInterpreter/PerlInterpreter.pm
+++ b/Java/PerlInterpreter/PerlInterpreter.pm
@@ -14,23 +14,4 @@ use Inline (
 ) ;
 
 
-
-sub java_eval {
-	my $code = shift ;
-
-	my $ret = eval $code ;
-	if ($@){
-		die($@) ;
-	}
-
-	return $ret ;
-}
-
-
-sub java_require {
-	my $module = shift ;
-
-	return java_eval("require $module ;") ;
-}
-
 1 ;
diff --git a/Java/PerlInterpreter/t/01_perl_interpreter.pl b/Java/PerlInterpreter/t/01_perl_interpreter.t
similarity index 100%
rename from Java/PerlInterpreter/t/01_perl_interpreter.pl
rename to Java/PerlInterpreter/t/01_perl_interpreter.t
diff --git a/Java/Portable.pm b/Java/Portable.pm
index 04e38c1..e42feff 100644
--- a/Java/Portable.pm
+++ b/Java/Portable.pm
@@ -10,7 +10,7 @@ use Config ;
 use File::Find ;
 use File::Spec ;
 
-$Inline::Java::Portable::VERSION = '0.47' ;
+$Inline::Java::Portable::VERSION = '0.48' ;
 
 # Here is some code to figure out if we are running on command.com
 # shell under Windows.
diff --git a/Java/Protocol.pm b/Java/Protocol.pm
index fac78d4..72c4411 100644
--- a/Java/Protocol.pm
+++ b/Java/Protocol.pm
@@ -5,7 +5,7 @@ use Inline::Java::Object ;
 use Inline::Java::Array ;
 use Carp ;
 
-$Inline::Java::Protocol::VERSION = '0.47' ;
+$Inline::Java::Protocol::VERSION = '0.48' ;
 
 my %CLASSPATH_ENTRIES = () ;
 
@@ -79,6 +79,15 @@ sub ISA {
 
 	my $class = $this->{obj_priv}->{java_class} ;
 
+	return $this->__ISA($proto, $class) ;
+}
+
+
+sub __ISA {
+	my $this = shift ;
+	my $proto = shift ;
+	my $class = shift ;
+
 	Inline::Java::debug(3, "checking if $class is a $proto") ;
 
 	my $data = join(" ", 
@@ -255,22 +264,27 @@ sub ValidateArgs {
 			push @ret, "undef:" ;
 		}
 		elsif (ref($arg)){
-			if ((! UNIVERSAL::isa($arg, "Inline::Java::Object"))&&(! UNIVERSAL::isa($arg, "Inline::Java::Array"))){
+			if ((UNIVERSAL::isa($arg, "Inline::Java::Object"))||(UNIVERSAL::isa($arg, "Inline::Java::Array"))){
+				my $obj = $arg ;
+				if (UNIVERSAL::isa($arg, "Inline::Java::Array")){
+					$obj = $arg->__get_object() ; 
+				}
+				my $class = $obj->__get_private()->{java_class} ;
+				my $id = $obj->__get_private()->{id} ;
+				push @ret, "java_object:$class:$id" ;
+			}
+			elsif ($arg =~ /^(.*?)=/){
+				my $id = Inline::Java::Callback::PutObject($arg) ;
+				push @ret, "perl_object:$1:$id" ;
+			}
+			else {
 				if (! $callback){
-					croak "A Java method or member can only have Java objects, Java arrays or scalars as arguments" ;
+					croak "A Java method or member can only have Java objects, Java arrays, Perl objects or scalars as arguments" ;
 				}
 				else{
-					croak "A Java callback function can only return Java objects, Java arrays or scalars" ;
+					croak "A Java callback function can only return Java objects, Java arrays, Perl objects or scalars" ;
 				}
 			}
-
-			my $obj = $arg ;
-			if (UNIVERSAL::isa($arg, "Inline::Java::Array")){
-				$obj = $arg->__get_object() ; 
-			}
-			my $class = $obj->__get_private()->{java_class} ;
-			my $id = $obj->__get_private()->{id} ;
-			push @ret, "object:$class:$id" ;
 		}
 		else{
 			push @ret, "scalar:" . encode($arg) ;
@@ -324,7 +338,7 @@ sub DeserializeObject {
 	elsif ($resp =~ /^undef:$/){
 		return undef ;
 	}
-	elsif ($resp =~ /^object:([01]):(\d+):(.*)$/){
+	elsif ($resp =~ /^java_object:([01]):(\d+):(.*)$/){
 		# Create the Perl object wrapper and return it.
 		my $thrown = $1 ;
 		my $id = $2 ;
@@ -404,6 +418,12 @@ sub DeserializeObject {
 			}
 		}
 	}
+	elsif ($resp =~ /^perl_object:(\d+):(.*)$/){
+		my $id = $1 ;
+		my $pkg = $2 ;
+
+		return Inline::Java::Callback::GetObject($id) ;
+	}
 	else{
 		croak "Malformed response from server: $resp" ;
 	}
diff --git a/Java/sources/org/perl/inline/java/InlineJavaCallback.java b/Java/sources/org/perl/inline/java/InlineJavaCallback.java
index bd1e1c8..1e56051 100644
--- a/Java/sources/org/perl/inline/java/InlineJavaCallback.java
+++ b/Java/sources/org/perl/inline/java/InlineJavaCallback.java
@@ -10,26 +10,55 @@ import java.io.* ;
 class InlineJavaCallback {
 	private InlineJavaServer ijs = InlineJavaServer.GetInstance() ;
 	private String pkg = null ;
+	private InlineJavaPerlObject obj = null ;
 	private String method = null ;
 	private Object args[] = null ;
-	private String cast = null ;
+	private Class cast = null ;
 	private Object response = null ;
 	private boolean response_set = false ;
 
 
-	InlineJavaCallback(String _pkg, String _method, Object _args[], String _cast) {
+	InlineJavaCallback(String _pkg, String _method, Object _args[], Class _cast) {
+		this(null, _pkg, _method, _args, _cast) ;
+	}
+	
+	
+	InlineJavaCallback(InlineJavaPerlObject _obj, String _method, Object _args[], Class _cast) {
+		this(_obj, null, _method, _args, _cast) ;
+		if (obj == null){
+			throw new NullPointerException() ;
+		}
+	}
+	
+	
+	private InlineJavaCallback(InlineJavaPerlObject _obj, String _pkg, String _method, Object _args[], Class _cast) {
+		obj = _obj ;
 		pkg = _pkg ;
 		method = _method ;
 		args = _args ;
-		cast = _cast ;	
+		cast = _cast ;
+				
+		if (method == null){
+			throw new NullPointerException() ;
+		}
+		if (cast == null){
+			cast = java.lang.Object.class ;
+		}
 	}
 
 
 	private String GetCommand(InlineJavaProtocol ijp) throws InlineJavaException {
-		StringBuffer cmdb = new StringBuffer("callback " + pkg + " " + method + " " + cast) ;
+		String via = null ;
+		if (obj != null){
+			via = "" + obj.GetId() ;
+		}
+		else if (pkg != null){
+			via = pkg ;
+		}
+		StringBuffer cmdb = new StringBuffer("callback " + via + " " + method + " " + cast.getName()) ;
 		if (args != null){
 			for (int i = 0 ; i < args.length ; i++){
-				 cmdb.append(" " + ijp.SerializeObject(args[i])) ;
+				cmdb.append(" " + ijp.SerializeObject(args[i])) ;
 			}
 		}
 		return cmdb.toString() ;
@@ -102,7 +131,7 @@ class InlineJavaCallback {
 					boolean thrown = new Boolean(st.nextToken()).booleanValue() ;
 					String arg = st.nextToken() ;
 					InlineJavaClass ijc = new InlineJavaClass(ijs, ijp) ;
-					ret = ijc.CastArgument(java.lang.Object.class, arg) ;
+					ret = ijc.CastArgument(cast, arg) ;
 
 					if (thrown){
 						throw new InlineJavaPerlException(ret) ;
diff --git a/Java/sources/org/perl/inline/java/InlineJavaClass.java b/Java/sources/org/perl/inline/java/InlineJavaClass.java
index f47e38c..bcfaadf 100644
--- a/Java/sources/org/perl/inline/java/InlineJavaClass.java
+++ b/Java/sources/org/perl/inline/java/InlineJavaClass.java
@@ -215,7 +215,7 @@ class InlineJavaClass {
 					throw new InlineJavaCastException("Can't convert primitive type to " + p.getName()) ;
 				}
 			}
-			else{
+			else if (type.equals("java_object")){
 				// We need an object and we got an object...
 				InlineJavaUtils.debug(4, "class " + p.getName() + " is reference") ;
 
@@ -235,6 +235,21 @@ class InlineJavaClass {
 					throw new InlineJavaCastException("Can't cast a " + c.getName() + " to a " + p.getName()) ;
 				}
 			}
+			else{
+				InlineJavaUtils.debug(4, "class " + p.getName() + " is reference") ;
+
+				String pkg = (String)tokens.get(1) ;
+				String objid = (String)tokens.get(2) ;
+
+				if (DoesExtend(p, org.perl.inline.java.InlineJavaPerlObject.class) > -1){
+					InlineJavaUtils.debug(4, " Perl object is a kind of " + p.getName()) ;
+					int id = Integer.parseInt(objid) ;
+					ret = new InlineJavaPerlObject(pkg, id) ;
+				}
+				else{
+					throw new InlineJavaCastException("Can't cast a Perl object to a " + p.getName()) ;
+				}
+			}
 		}
 
 		return ret ;
diff --git a/Java/sources/org/perl/inline/java/InlineJavaPerlCaller.java b/Java/sources/org/perl/inline/java/InlineJavaPerlCaller.java
index a268739..62cd5f0 100644
--- a/Java/sources/org/perl/inline/java/InlineJavaPerlCaller.java
+++ b/Java/sources/org/perl/inline/java/InlineJavaPerlCaller.java
@@ -32,16 +32,16 @@ public class InlineJavaPerlCaller {
 
 
 	synchronized static protected void init() throws InlineJavaException {
-       if (! inited){
-            try {
-                resources = ResourceBundle.getBundle("InlineJava") ;
+		if (! inited){
+			try {
+				resources = ResourceBundle.getBundle("InlineJava") ;
 
-                inited = true ;
-            }
-            catch (MissingResourceException mre){
-                throw new InlineJavaException("Error loading InlineJava.properties: " + mre.getMessage()) ;
-            }
-        }
+				inited = true ;
+			}
+			catch (MissingResourceException mre){
+				throw new InlineJavaException("Error loading InlineJava.properties: " + mre.getMessage()) ;
+			}
+		}
 	}
 
 
@@ -50,18 +50,89 @@ public class InlineJavaPerlCaller {
 	}
 
 
+	/* Old interface */
 	public Object CallPerl(String pkg, String method, Object args[]) throws InlineJavaException, InlineJavaPerlException {
 		return CallPerl(pkg, method, args, null) ;
 	}
 
 
+	/* Old interface */
 	public Object CallPerl(String pkg, String method, Object args[], String cast) throws InlineJavaException, InlineJavaPerlException {
-		InlineJavaCallback ijc = new InlineJavaCallback(pkg, method, args, cast) ;
+		InlineJavaCallback ijc = new InlineJavaCallback(
+			(String)null, pkg + "::" + method, args, 
+			(cast == null ? null : InlineJavaClass.ValidateClass(cast))) ; 
+		return CallPerl(ijc) ;
+	}
+
+
+	/* New interface */
+	public Object CallPerlSub(String sub, Object args[]) throws InlineJavaException, InlineJavaPerlException {
+		return CallPerlSub(sub, args, null) ;
+	}
+	
+	
+	/* New interface */	
+	public Object CallPerlSub(String sub, Object args[], Class cast) throws InlineJavaException, InlineJavaPerlException {
+		InlineJavaCallback ijc = new InlineJavaCallback(
+			(String)null, sub, args, cast) ; 
+		return CallPerl(ijc) ;
+	}
+	
+	
+	/* New interface */
+	Object CallPerlMethod(InlineJavaPerlObject obj, String method, Object args[]) throws InlineJavaException, InlineJavaPerlException {
+		return CallPerlMethod(obj, method, args, null) ;
+	}
+	
+	
+	/* New interface */	
+	Object CallPerlMethod(InlineJavaPerlObject obj, String method, Object args[], Class cast) throws InlineJavaException, InlineJavaPerlException {
+		InlineJavaCallback ijc = new InlineJavaCallback(
+			obj, method, args, cast) ; 
+		return CallPerl(ijc) ;
+	}
+
+
+	/* New interface */
+	public Object CallPerlStaticMethod(String pkg, String method, Object args[]) throws InlineJavaException, InlineJavaPerlException {
+		return CallPerlStaticMethod(pkg, method, args, null) ;
+	}
+	
+	
+	/* New interface */	
+	public Object CallPerlStaticMethod(String pkg, String method, Object args[], Class cast) throws InlineJavaException, InlineJavaPerlException {
+		InlineJavaCallback ijc = new InlineJavaCallback(
+			pkg, method, args, cast) ; 
 		return CallPerl(ijc) ;
 	}
 
 
-	public Object CallPerl(InlineJavaCallback ijc) throws InlineJavaException, InlineJavaPerlException {
+	public Object eval(String code) throws InlineJavaPerlException, InlineJavaException {
+		return eval(code, null) ;
+	}
+
+
+	public Object eval(String code, Class cast) throws InlineJavaPerlException, InlineJavaException {
+		return CallPerlSub("Inline::Java::Callback::java_eval", new Object [] {code}, cast) ;
+	}
+
+
+	public Object require(String module_or_file) throws InlineJavaPerlException, InlineJavaException {
+		return CallPerlSub("Inline::Java::PerlInterpreter::java_require", new Object [] {module_or_file}) ;
+	}
+
+
+	public Object require_file(String file) throws InlineJavaPerlException, InlineJavaException {
+		return CallPerlSub("Inline::Java::PerlInterpreter::java_require", new Object [] {file, new Boolean("true")}) ;
+	}
+	
+	
+	public Object require_module(String module) throws InlineJavaPerlException, InlineJavaException {
+		return CallPerlSub("Inline::Java::PerlInterpreter::java_require", new Object [] {module, new Boolean("false")}) ;
+	}
+	
+
+	private Object CallPerl(InlineJavaCallback ijc) throws InlineJavaException, InlineJavaPerlException {
 		Thread t = Thread.currentThread() ;
 		if (t == creator){
 			ijc.Process() ;
diff --git a/Java/sources/org/perl/inline/java/InlineJavaPerlInterpreter.java b/Java/sources/org/perl/inline/java/InlineJavaPerlInterpreter.java
index f9b877a..ff11084 100644
--- a/Java/sources/org/perl/inline/java/InlineJavaPerlInterpreter.java
+++ b/Java/sources/org/perl/inline/java/InlineJavaPerlInterpreter.java
@@ -91,16 +91,6 @@ public class InlineJavaPerlInterpreter extends InlineJavaPerlCaller {
 	synchronized static private native void destruct() ;
 
 
-	public Object eval(String code) throws InlineJavaPerlException, InlineJavaException {
-		return CallPerl("Inline::Java::PerlInterpreter", "java_eval", new Object [] {code}) ;
-	}
-
-
-	public Object require(String module) throws InlineJavaPerlException, InlineJavaException {
-		return CallPerl("Inline::Java::PerlInterpreter", "java_require", new Object [] {module}) ;
-	}
-
-
 	synchronized public void destroy() {
 		destruct() ;
 		instance = null ;
diff --git a/Java/sources/org/perl/inline/java/InlineJavaPerlObject.java b/Java/sources/org/perl/inline/java/InlineJavaPerlObject.java
new file mode 100644
index 0000000..b234d93
--- /dev/null
+++ b/Java/sources/org/perl/inline/java/InlineJavaPerlObject.java
@@ -0,0 +1,73 @@
+package org.perl.inline.java ;
+
+
+/*
+	InlineJavaPerlObject
+*/
+public class InlineJavaPerlObject extends InlineJavaPerlCaller {
+	private int id = 0 ;
+	private String pkg = null ;
+
+
+	/* 
+		Creates a Perl Object by calling 
+			pkg->new(args) ;
+	*/
+	public InlineJavaPerlObject(String _pkg, Object args[]) throws InlineJavaPerlException, InlineJavaException {
+		pkg = _pkg ;
+		InlineJavaPerlObject stub = (InlineJavaPerlObject)CallPerlStaticMethod(pkg, "new", args, getClass()) ;
+		id = stub.GetId() ;
+		stub.id = 0 ;
+	}
+
+
+	/*
+		This is just a stub for already existing objects
+	*/
+	InlineJavaPerlObject(String _pkg, int _id) throws InlineJavaException {
+		pkg = _pkg ;
+		id = _id ;
+	}
+
+
+	public int GetId(){
+		return id ;
+	}
+
+
+	public String GetPkg(){
+		return pkg ;
+	}
+
+
+	public Object InvokeMethod(String name, Object args[]) throws InlineJavaPerlException, InlineJavaException {
+		return InvokeMethod(name, args, null) ;
+	}
+
+
+	public Object InvokeMethod(String name, Object args[], Class cast) throws InlineJavaPerlException, InlineJavaException {
+		return CallPerlMethod(this, name, args, cast) ;
+	}
+
+
+	public void Done() throws InlineJavaPerlException, InlineJavaException {
+		Done(false) ;
+	}
+
+
+	protected void Done(boolean gc) throws InlineJavaPerlException, InlineJavaException {
+		if (id != 0){
+			CallPerlSub("Inline::Java::Callback::java_finalize", new Object [] {new Integer(id), new Boolean(gc)}) ;
+		}
+	}
+
+
+	protected void finalize() throws Throwable {
+		try {
+			Done(true) ;
+		}
+		finally {
+			super.finalize() ;
+		}
+	}
+}
diff --git a/Java/sources/org/perl/inline/java/InlineJavaProtocol.java b/Java/sources/org/perl/inline/java/InlineJavaProtocol.java
index 4889a28..1c1118b 100644
--- a/Java/sources/org/perl/inline/java/InlineJavaProtocol.java
+++ b/Java/sources/org/perl/inline/java/InlineJavaProtocol.java
@@ -16,6 +16,7 @@ class InlineJavaProtocol {
 	private String response = null ;
 
 	static private HashMap member_cache = new HashMap() ;
+	static private String report_version = "V2" ;
 
 	InlineJavaProtocol(InlineJavaServer _ijs, String _cmd) {
 		ijs = _ijs ;
@@ -77,7 +78,7 @@ class InlineJavaProtocol {
 		and members
 	*/
 	void Report(StringTokenizer st) throws InlineJavaException {
-		StringBuffer pw = new StringBuffer() ;
+		StringBuffer pw = new StringBuffer(report_version + "\n") ;
 
 		StringTokenizer st2 = new StringTokenizer(st.nextToken(), ":") ;
 		st2.nextToken() ;
@@ -623,16 +624,22 @@ class InlineJavaProtocol {
 			return "scalar:" + Encode((b.equals("true") ? "1" : "0")) ;
 		}
 		else {
-			// Here we need to register the object in order to send
-			// it back to the Perl script.
-			boolean thrown = false ;
-			if (o instanceof InlineJavaThrown){ 
-				thrown = true ;
-				o = ((InlineJavaThrown)o).GetThrowable() ;
-			}			
-			int id = ijs.PutObject(o) ;
-			return "object:" + (thrown ? "1" : "0") + ":" + String.valueOf(id) +
-				":" + o.getClass().getName() ;
+			if (! (o instanceof org.perl.inline.java.InlineJavaPerlObject)){
+				// Here we need to register the object in order to send
+				// it back to the Perl script.
+				boolean thrown = false ;
+				if (o instanceof InlineJavaThrown){ 
+					thrown = true ;
+					o = ((InlineJavaThrown)o).GetThrowable() ;
+				}			
+				int id = ijs.PutObject(o) ;
+				return "java_object:" + (thrown ? "1" : "0") + ":" + String.valueOf(id) +
+					":" + o.getClass().getName() ;
+			}
+			else {
+				return "perl_object:" + ((InlineJavaPerlObject)o).GetId() +
+					":" + ((InlineJavaPerlObject)o).GetPkg() ;
+			}
 		}
 	}
 
diff --git a/Java/sources/org/perl/inline/java/InlineJavaServer.java b/Java/sources/org/perl/inline/java/InlineJavaServer.java
index 1114786..9f2e27b 100644
--- a/Java/sources/org/perl/inline/java/InlineJavaServer.java
+++ b/Java/sources/org/perl/inline/java/InlineJavaServer.java
@@ -287,7 +287,18 @@ public class InlineJavaServer {
 	}
 
 
+	/*
+		With PerlInterpreter this is called twisce, but we don't want to create
+		a new object the second time.
+	*/
 	public static InlineJavaServer jni_main(int debug){
-		return new InlineJavaServer(debug) ;
+		if (instance != null){
+			InlineJavaUtils.debug = debug ;
+			InlineJavaUtils.debug(1, "recycling InlineJavaServer created by PerlInterpreter") ;
+			return instance ;
+		}
+		else{
+			return new InlineJavaServer(debug) ;
+		}
 	}
 }
diff --git a/MANIFEST b/MANIFEST
index 46c3d79..fff56c0 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -44,6 +44,7 @@ Java/Natives/t/02_perl_natives.t
 Java/PerlInterpreter/Makefile.PL
 Java/PerlInterpreter/PerlInterpreter.pm
 Java/PerlInterpreter/PerlInterpreter.xs
+Java/PerlInterpreter/01_perl_interpreter.t
 t/01_init.t
 t/02_primitives.t
 t/03_objects.t
diff --git a/META.yml b/META.yml
index b3e67c3..fb3cd64 100644
--- a/META.yml
+++ b/META.yml
@@ -1,7 +1,7 @@
 # http://module-build.sourceforge.net/META-spec.html
 #XXXXXXX This is a prototype!!!  It will change in the future!!! XXXXX#
 name:         Inline-Java
-version:      0.47
+version:      0.48
 version_from: Java.pm
 installdirs:  site
 requires:
diff --git a/Makefile.PL b/Makefile.PL
index 9a47307..9ac19b4 100644
--- a/Makefile.PL
+++ b/Makefile.PL
@@ -147,6 +147,8 @@ sub expand_macros {
 
 
 # Write the Makefile
+my $natives_test = File::Spec->catdir('Java', 'Natives', '_Inline_test') ;
+my $perlinterp_test = File::Spec->catdir('Java', 'PerlInterpreter', '_Inline_test') ;
 WriteMakefile(
 	NAME => 'Inline::Java',
 	VERSION_FROM => 'Java.pm',
@@ -161,7 +163,7 @@ WriteMakefile(
 		$server_arch => File::Spec->catfile('$(INST_LIBDIR)', $server_arch),
 		$user_arch => File::Spec->catfile('$(INST_LIBDIR)', $user_arch),
 	},
-	clean => {FILES => "$def_jdk _Inline_test $obj_dir $server_arch $user_arch"},
+	clean => {FILES => "$def_jdk _Inline_test $natives_test $perlinterp_test $obj_dir $server_arch $user_arch"},
 ) ;
 
 
diff --git a/TODO b/TODO
index 7c1bf3b..521eaf6 100644
--- a/TODO
+++ b/TODO
@@ -1,13 +1,13 @@
 CODE:
-- Retest under 5.6.1
-- Do more test for CLASSPATH combinations
+- Finish PerlInterpreter test suite
 - Does STDIN still need to be closed in the JVM?
 
+DOCUMENTATION:
+- Redocument Callbacks
+- Document InlineJavaPerlObject and InlineJavaPerlInterpreter`
+
 TEST:
 - Alpha
 - Cygwin
 
-DOCUMENTATION:
-- Recheck all and complete.
-- Comment new code.
 
diff --git a/t/03_objects.t b/t/03_objects.t
index 1be893a..9959cc3 100644
--- a/t/03_objects.t
+++ b/t/03_objects.t
@@ -52,8 +52,8 @@ my $t = new types3() ;
 	# Return a scalar hidden in an object.
 	ok($t->_olong(), 12345) ;
 
-	# Pass a non-Java object.
-	my $d = bless({}, "Inline::Java::dummy") ;
+	# Pass a non-Java object, a hash ref.
+	my $d = {} ;
 	eval {$t->_Object($d)} ; ok($@, qr/Can't convert/) ;
 }
 
diff --git a/t/12_1_callbacks.t b/t/12_1_callbacks.t
index d8aa1c3..8944cf8 100755
--- a/t/12_1_callbacks.t
+++ b/t/12_1_callbacks.t
@@ -14,7 +14,7 @@ use Inline::Java qw(caught) ;
 
 
 BEGIN {
-	my $cnt = 23 ;
+	my $cnt = 24 ;
 	plan(tests => $cnt) ;
 }
 
@@ -42,6 +42,8 @@ my $t = new t15() ;
 
 		ok($t->cat_via_perl("Inline", "Java"), "InlineJava") ;
 
+		ok($t->perl_static(), 'main->static') ;
+
 		ok(twister(20, 0, 0), "return perl twister") ;
 		ok($t->twister(20, 0, 0), "return java twister") ;
 
@@ -195,6 +197,13 @@ sub mt_callback {
 }
 
 
+sub static_method {
+	my $class = shift ;
+
+	return 'main->static' ;
+}
+
+
 __END__
 
 __Java__
@@ -223,7 +232,7 @@ class t15 extends InlineJavaPerlCaller {
 		public void run(){
 			try {
 				if (! error){
-					pc.CallPerl("main", "mt_callback", new Object [] {pc}) ;
+					pc.CallPerlSub("main::mt_callback", new Object [] {pc}) ;
 				}
 				else {
 					new InlineJavaPerlCaller() ;
@@ -266,22 +275,22 @@ class t15 extends InlineJavaPerlCaller {
 	}
 
 	public int add_via_perl(int a, int b) throws InlineJavaException, InlineJavaPerlException {
-		String val = (String)CallPerl("main", "add", 
+		String val = (String)CallPerlSub("main::add", 
 			new Object [] {new Integer(a), new Integer(b)}) ;
 
 		return new Integer(val).intValue() ;
 	}
 
 	public int [] incr_via_perl(int a[]) throws InlineJavaException, InlineJavaPerlException {
-		int [] r = (int [])CallPerl("main", "incr", 
-			new Object [] {a}, "[I") ;
+		int [] r = (int [])CallPerlSub("main::incr", 
+			new Object [] {a}, a.getClass()) ;
 
 		return r ;
 	}
 
 	public void death_via_perl() throws InlineJavaException, InlineJavaPerlException {
 		InlineJavaPerlCaller c = new InlineJavaPerlCaller() ;
-		c.CallPerl("main", "death", null) ;
+		c.CallPerlSub("main::death", null) ;
 	}
 
 	public void except() throws InlineJavaException, InlineJavaPerlException {
@@ -289,14 +298,14 @@ class t15 extends InlineJavaPerlCaller {
 	}
 
 	public int mul_via_perl(int a, int b) throws InlineJavaException, InlineJavaPerlException {
-		String val = (String)CallPerl("main", "mul", 
+		String val = (String)CallPerlSub("main::mul", 
 			new Object [] {new Integer(a), new Integer(b)}) ;
 
 		return new Integer(val).intValue() ;
 	}
 
 	public int add_via_perl_via_java(int a, int b) throws InlineJavaException, InlineJavaPerlException {
-		String val = (String)CallPerl("main", "add_via_java", 
+		String val = (String)CallPerlSub("main::add_via_java", 
 			new Object [] {new Integer(a), new Integer(b)}) ;
 
 		return new Integer(val).intValue() ;
@@ -304,7 +313,7 @@ class t15 extends InlineJavaPerlCaller {
 
 	static public int add_via_perl_via_java_t(t15 t, int a, int b) throws InlineJavaException, InlineJavaPerlException {
 		InlineJavaPerlCaller c = new InlineJavaPerlCaller() ;
-		String val = (String)c.CallPerl("main", "add_via_java_t", 
+		String val = (String)c.CallPerlSub("main::add_via_java_t", 
 			new Object [] {t, new Integer(a), new Integer(b)}) ;
 
 		return new Integer(val).intValue() ;
@@ -314,7 +323,7 @@ class t15 extends InlineJavaPerlCaller {
 	public int silly_mul_via_perl_via_java(int a, int b) throws InlineJavaException, InlineJavaPerlException {
 		int ret = 0 ;
 		for (int i = 0 ; i < b ; i++){
-			String val = (String)CallPerl("main", "add_via_java", 
+			String val = (String)CallPerlSub("main::add_via_java", 
 				new Object [] {new Integer(ret), new Integer(a)}) ;
 			ret = new Integer(val).intValue() ;
 		}
@@ -339,7 +348,7 @@ class t15 extends InlineJavaPerlCaller {
 			}
 		}
 		else{
-			return (String)CallPerl("main", "twister", 
+			return (String)CallPerlSub("twister", 
 				new Object [] {new Integer(max), new Integer(cnt+1), new Integer(explode)}) ;
 		}
 	}
@@ -351,12 +360,17 @@ class t15 extends InlineJavaPerlCaller {
 
 
 	public Object perlt() throws InlineJavaException, InlineJavaPerlException, OwnException {
-		return CallPerl("main", "t", null) ;
+		return CallPerlSub("t", null) ;
+	}
+
+
+	public Object perl_static() throws InlineJavaException, InlineJavaPerlException, OwnException {
+		return CallPerlStaticMethod("main", "static_method", null) ;
 	}
 
 
 	public Object perldummy() throws InlineJavaException, InlineJavaPerlException, OwnException {
-		return CallPerl("main", "dummy", null) ;
+		return CallPerlSub("dummy", null) ;
 	}
 
 	public void mtc_callbacks(int n){
diff --git a/t/12_2_perl_objects.t b/t/12_2_perl_objects.t
new file mode 100755
index 0000000..6f5a0a7
--- /dev/null
+++ b/t/12_2_perl_objects.t
@@ -0,0 +1,151 @@
+use strict ;
+use Test ;
+
+use Inline Config => 
+           DIRECTORY => './_Inline_test';
+
+use Inline (
+	Java => 'DATA',
+) ;
+
+use Inline::Java qw(caught) ;
+use Data::Dumper ;
+
+
+BEGIN {
+	my $cnt = 14 ;
+	plan(tests => $cnt) ;
+}
+
+my $t = new t16() ;
+
+{
+	eval {
+		my $o = new Obj(name => 'toto') ;
+		$t->set($o) ;
+		ok($t->get(), $o) ;
+		ok($t->get()->{name}, 'toto') ;
+		ok($t->round_trip($o), $o) ;
+		ok($o->get("name"), 'toto') ;
+		ok($t->method_call($o, 'get', ['name']), 'toto') ;
+		eval {$t->method_call($o, 'bad', ['bad'])} ; ok($@, qr/Can't locate object method "bad" via package "Obj"/) ;
+		eval {$t->round_trip({})} ; ok($@, qr/^Can't convert (.*?) to object org.perl.inline.java.InlineJavaPerlObject/) ;
+		ok($t->add_eval(5, 6), 11) ;
+		eval {$t->error()} ; ok($@, qr/alone/) ;
+
+		my $cnt = Inline::Java::Callback::ObjectCount() ;
+		$t->clean($o) ;
+		ok($cnt, Inline::Java::Callback::ObjectCount()) ;
+
+		my $jo = $t->create("Obj", ['name', 'titi']) ;
+		ok($jo->get("name"), 'titi') ;
+		$t->have_fun() ;
+		ok($jo->get('shirt'), qr/lousy t-shirt/) ;
+
+		$t->clean(undef) ;
+	} ;
+	if ($@){
+		if (caught("java.lang.Throwable")){
+			$@->printStackTrace() ;
+			die("Caught Java Exception") ;
+		}
+		else{
+			die $@ ;
+		}
+	}
+}
+
+ok($t->__get_private()->{proto}->ObjectCount(), 1) ;
+ok(Inline::Java::Callback::ObjectCount(), 3) ;
+
+
+package Obj ;
+
+sub new {
+	my $class = shift ;
+
+	return bless({@_}, $class) ;
+}
+
+sub get {
+	my $this = shift ;
+	my $attr = shift ;
+
+	return $this->{$attr} ;
+}
+
+sub set {
+	my $this = shift ;
+	my $attr = shift ;
+	my $val = shift ;
+
+	$this->{$attr} = $val ;
+}
+
+package main ;
+
+
+__END__
+
+__Java__
+
+
+import java.io.* ;
+import org.perl.inline.java.* ;
+
+class t16 {
+	InlineJavaPerlObject po = null ;
+
+	public t16(){
+	}
+
+	public void set(InlineJavaPerlObject o){
+		po = o ;
+	}
+
+	public InlineJavaPerlObject get(){
+		return po ;
+	}
+
+	public int add_eval(int a, int b) throws InlineJavaException, InlineJavaPerlException {
+		Integer i = (Integer)po.eval(a + " + " + b, Integer.class) ;
+		return i.intValue() ;
+	}
+
+	public String method_call(InlineJavaPerlObject o, String name, Object args[]) throws InlineJavaException, InlineJavaPerlException {
+		String s = (String)o.InvokeMethod(name, args) ;
+		o.Done() ;
+		return s ;
+	}
+
+	public void error() throws InlineJavaException, InlineJavaPerlException {
+		po.eval("die 'alone'") ;
+	}
+
+	public InlineJavaPerlObject round_trip(InlineJavaPerlObject o) throws InlineJavaException, InlineJavaPerlException {
+		return o ;
+	}
+
+	public void clean(InlineJavaPerlObject o) throws InlineJavaException, InlineJavaPerlException {
+		if (o != null){
+			o.Done() ;
+		}
+		else if (po != null){
+			po.Done() ;
+		}
+	}
+
+	public InlineJavaPerlObject create(String pkg, Object args[]) throws InlineJavaException, InlineJavaPerlException {
+		po = new InlineJavaPerlObject(pkg, args) ;
+		return po ;
+	}
+
+	public void have_fun() throws InlineJavaException, InlineJavaPerlException {
+		po.InvokeMethod("set", new Object [] {"shirt", "I've been to Java and all I got was this lousy t-shirt!"}) ;
+	}
+
+	public void gc(){
+		System.runFinalization() ;
+		System.gc() ;
+	}
+}

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-perl/packages/libinline-java-perl.git



More information about the Pkg-perl-cvs-commits mailing list