[libinline-java-perl] 271/398: 0.45 RC1

Jonas Smedegaard dr at jones.dk
Thu Feb 26 11:43:13 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 0130ffa5b166c52fd2796c130f9126a458ab7fa4
Author: patrick_leb <>
Date:   Tue Jan 20 00:08:12 2004 +0000

    0.45 RC1
---
 CHANGES                                            |  5 ++
 Java.pod                                           | 72 +++++++++++++++++
 Java/Natives/Natives.xs                            | 20 +++--
 .../perl/inline/java/InlineJavaPerlNatives.java    | 81 +++++++++----------
 MANIFEST                                           |  5 ++
 README                                             |  6 ++
 TODO                                               |  2 +
 t/12_1_perl_natives.t                              | 90 ++++++++++++++++------
 8 files changed, 204 insertions(+), 77 deletions(-)

diff --git a/CHANGES b/CHANGES
index 8d0c965..6372803 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,5 +1,10 @@
 Revision history for Perl extension Inline::Java
 ------------------------------------------------
+0.45  Mon Jan 19 20:00:00 EST 2004
+    - Fixed Makefile.PL arguments that were getting lost
+    - Fixed deprecated require call
+	- Fixed support for symbolic links in J2SDK directory
+	- Added new experimental feature: PerlNatives
 
 0.44  Sun Nov 23 15:47:06 EST 2003
     - Callbacks from multiple threads are now supported
diff --git a/Java.pod b/Java.pod
index a90b215..ff4e40e 100644
--- a/Java.pod
+++ b/Java.pod
@@ -732,6 +732,78 @@ StopCallbackLoop methods.
    Z<>
 
 
+=head1 PerlNatives CALLBACKS (EXPERIMENTAL)
+
+Note: PerlNatives requires J2SDK version >= 1.4
+
+As of 0.45, it is now possible to define your callbacks as native Java methods
+that are automatically linked to Perl subroutines. You implement the Perl
+subroutine directly in the package in which C<Inline::Java> binds your class.
+Let's revisit the example from the previous section:
+
+=for comment
+
+   use Inline Java => <<'END' ;
+      import java.util.* ;
+      import org.perl.inline.java.* ;
+      import javax.swing.* ;
+      import java.awt.event.* ;
+
+      class Pod_Button_PN extends InlineJavaPerlNatives
+                          implements ActionListener {
+         public Pod_Button_PN() throws InlineJavaException {
+            JFrame frame = new JFrame("Pod_Button") ;
+            frame.setSize(100,100) ;
+            JButton button = new JButton("Click Me!") ;
+            frame.getContentPane().add(button) ;
+            button.addActionListener(this) ;
+            frame.show() ;
+         }
+
+         public void actionPerformed(ActionEvent e){
+            button_pressed() ;
+         }
+
+         native public void button_pressed() ;
+      }
+   END
+
+   package Pod_Button_PN ;
+   sub button_pressed {
+      print("click!\n") ; # prints click!
+      $b->StopCallbackLoop() ;
+   }
+
+   package main ;
+   my $b = new Pod_Button_PN() ;
+   $b->StartCallbackLoop() ;
+
+=for comment
+
+Extending InlineJavaPerlNatives tells C<Inline::Java> that all native methods 
+declared in that class should be linked to Perl subroutines implemented in the 
+approriate package. You can then call these methods from Java just like regular 
+methods. You can even call them from Perl if they are public. However, here are 
+a few things to remember:
+
+  - You cannot declare 2 native methods with the same name in a class (even if
+    they have different signatures)
+  - Native methods can have arguments of any type, but they must return either
+    void or an Object (use wrappers like Integer and Double to return primitive
+    types)
+  - Even if you do not declare them, InlineJavaException and 
+    InlineJavaPerlException exceptions (as well as others) may be thrown from
+    within the native methods
+
+StopCallbackLoop method on any InlineJavaPerlCaller object that has been created
+by that same thread.
+
+Also, only threads that communicate with Perl through C<Inline::Java> are allowed
+to create InlineJavaPerlCaller objects and invoke their StartCallbackLoop /
+StopCallbackLoop methods.
+   Z<>
+
+
 =head1 STUDYING
 
 As of version 0.21, C<Inline::Java> can learn about other Java classes
diff --git a/Java/Natives/Natives.xs b/Java/Natives/Natives.xs
index b376c9c..a4c119b 100644
--- a/Java/Natives/Natives.xs
+++ b/Java/Natives/Natives.xs
@@ -74,42 +74,40 @@ jobject extract_va_arg(JNIEnv *env, va_list *list, char f){
 
 	/*
 		A bit of voodoo going on for J and F, but the rest I think is pretty
-		kosher...
+		kosher (on a 32 bit machine at least)
 	*/
 	switch(f){
 		case 'B':
-			val.i = (jbyte)va_arg(*list, jint) ;
+			val.i = (jbyte)va_arg(*list, int) ;
 			ret = create_primitive_object(env, f, "java/lang/Byte", val) ;
 			break ;
 		case 'S':
-			val.i = (jshort)va_arg(*list, jint) ;
+			val.i = (jshort)va_arg(*list, int) ;
 			ret = create_primitive_object(env, f, "java/lang/Short", val) ;
 			break ;
 		case 'I':
-			val.i = (jint)va_arg(*list, jint) ;
+			val.i = (jint)va_arg(*list, int) ;
 			ret = create_primitive_object(env, f, "java/lang/Integer", val) ;
 			break ;
 		case 'J':
-			val.d = (jdouble)va_arg(*list, jdouble) ;
+			val.d = (jdouble)va_arg(*list, double) ;
 			ret = create_primitive_object(env, f, "java/lang/Long", val) ;
 			break ;
 		case 'F':
 			/* Seems float is not properly promoted to double... */
-			fi = (int)va_arg(*list, int) ;
-			ff = (float *)&fi ;
-			val.f = *ff ;
+			val.i = (jint)va_arg(*list, int) ;
 			ret = create_primitive_object(env, f, "java/lang/Float", val) ;
 			break ;
 		case 'D':
-			val.d = (jdouble)va_arg(*list, jdouble) ;
+			val.d = (jdouble)va_arg(*list, double) ;
 			ret = create_primitive_object(env, f, "java/lang/Double", val) ;
 			break ;
 		case 'Z':
-			val.i = (jint)va_arg(*list, jint) ;
+			val.i = (jint)va_arg(*list, int) ;
 			ret = create_primitive_object(env, f, "java/lang/Boolean", val) ;
 			break ;
 		case 'C':
-			val.i = (jchar)va_arg(*list, jint) ;
+			val.i = (jchar)va_arg(*list, int) ;
 			ret = create_primitive_object(env, f, "java/lang/Character", val) ;
 			break ;
 	}
diff --git a/Java/sources/org/perl/inline/java/InlineJavaPerlNatives.java b/Java/sources/org/perl/inline/java/InlineJavaPerlNatives.java
index 2f3bbd7..10d4046 100644
--- a/Java/sources/org/perl/inline/java/InlineJavaPerlNatives.java
+++ b/Java/sources/org/perl/inline/java/InlineJavaPerlNatives.java
@@ -7,14 +7,13 @@ import java.io.* ;
 
 public class InlineJavaPerlNatives extends InlineJavaPerlCaller {
 	static private boolean inited = false ;
-    static private ResourceBundle resources = null ;
 	static private HashMap registered_classes = new HashMap() ;
 	static private HashMap registered_methods = new HashMap() ;
 
 
 	protected InlineJavaPerlNatives() throws InlineJavaException {
 		init() ;
-		RegisterPerlNatives(new Caller().getCaller()) ;
+		RegisterPerlNatives(this.getClass()) ;
 	}
 
 
@@ -24,34 +23,32 @@ public class InlineJavaPerlNatives extends InlineJavaPerlCaller {
 
 
 	synchronized static protected void init(String mode) throws InlineJavaException {
+		InlineJavaPerlCaller.init() ;
 		if (! inited){
 			try {
-				resources = ResourceBundle.getBundle("InlineJava") ;
-
-				String jni_so_built = resources.getString("jni_so_built") ;
-				if (! jni_so_built.equals("true")){
-					throw new InlineJavaException("Can't use the PerlNatives " +
-						"functionnality because the JNI extension was not built " +
-						"when Inline::Java was installed.") ;
-				}
-
-				boolean load_libperl_so = true ;
-				InlineJavaServer ijs = InlineJavaServer.GetInstance() ;
-				if ((ijs != null)&&(ijs.IsJNI())){
-					// InlineJavaServer is loaded and in JNI mode, no need to load Perl.
-					load_libperl_so = false ;
+				String natives_so = GetBundle().getString("inline_java_natives_so_" + mode) ;
+				File f = new File(natives_so) ;
+				if (! f.exists()){
+					throw new InlineJavaException("Can't initialize PerlNatives " +
+						"functionnality: Natives extension (" + natives_so + 
+						") can't be found") ;
 				}
 
-				if (load_libperl_so){
-					// Load the perl shared object			
-					load_so_from_property("libperl_so") ;
+				try {
+					Class ste_class = Class.forName("java.lang.StackTraceElement") ;
 				}
+				catch (ClassNotFoundException cnfe){
+					throw new InlineJavaException("Can't initialize PerlNatives " +
+                        "functionnality: Java 1.4 or higher required (current is " +
+						System.getProperty("java.version") + ").") ;
+				}      	
 
-				// Load the JNI shared object
-				load_so_from_property("inline_java_jni_so_" + mode) ;
+				// Load the Natives shared object
+				InlineJavaUtils.debug(2, "loading shared library " + natives_so) ;
+				System.load(natives_so) ;
 
 				inited = true ;
-			}
+			}                                   
 			catch (MissingResourceException mre){
 				throw new InlineJavaException("Error loading InlineJava.properties resource: " + mre.getMessage()) ;
 			}
@@ -59,15 +56,8 @@ public class InlineJavaPerlNatives extends InlineJavaPerlCaller {
 	}
 
 
-	synchronized static private void load_so_from_property(String prop) throws MissingResourceException, InlineJavaException {
-		String so = resources.getString(prop) ;
-		InlineJavaUtils.debug(2, "loading shared library " + so) ;
-		System.load(so) ;
-	}
-
-
 	// This method actually does the real work of registering the methods.
-	synchronized public void RegisterPerlNatives(Class c) throws InlineJavaException {
+	synchronized private void RegisterPerlNatives(Class c) throws InlineJavaException {
 		if (registered_classes.get(c) == null){
 			InlineJavaUtils.debug(3, "registering natives for class " + c.getName()) ;
 
@@ -105,11 +95,15 @@ public class InlineJavaPerlNatives extends InlineJavaPerlCaller {
 		StringBuffer fmt = new StringBuffer("L") ;
 		StringBuffer sign = new StringBuffer("(") ;
 		for (int i = 0 ; i < params.length ; i++){
-			if (! Object.class.isAssignableFrom(params[i])){
-				throw new InlineJavaException("Perl native method " + mname + " of class " + cname + " can only have Object arguments (not " + params[i].getName() + ")") ;
+			String code = InlineJavaClass.FindJNICode(params[i]) ;
+			sign.append(code) ;
+			char ch = code.charAt(0) ;
+			char f = ch ;
+			if (f == '['){
+				// Arrays are Objects...
+				f = 'L' ;
 			}
-			sign.append(InlineJavaClass.FindJNICode(params[i])) ;
-			fmt.append("L") ;
+			fmt.append(new String(new char [] {f})) ;
 		}
 		sign.append(")") ;
 
@@ -118,7 +112,12 @@ public class InlineJavaPerlNatives extends InlineJavaPerlCaller {
 		InlineJavaUtils.debug(3, "format is " + fmt) ;
 
 		// For now, no method overloading so no signature necessary
-		registered_methods.put(cname + "." + mname, fmt.toString()) ;
+		String meth = cname + "." + mname ;
+		String prev = (String)registered_methods.get(meth) ;
+		if (prev != null){
+			throw new InlineJavaException("There already is a native method '" + mname + "' registered for class '" + cname + "'") ;
+		}
+		registered_methods.put(meth, fmt.toString()) ;
 
 		// call the native method to hook it up
 		RegisterMethod(c, mname, sign.toString()) ;
@@ -160,8 +159,9 @@ public class InlineJavaPerlNatives extends InlineJavaPerlCaller {
 		// Transform the Java class name into the Perl package name
 		StringTokenizer st = new StringTokenizer(pkg, ".") ;
 		StringBuffer perl_pkg = new StringBuffer() ;
+		// Starting with "::" means that the package is relative to the caller package
 		while (st.hasMoreTokens()){
-			perl_pkg.append(st.nextToken() + "::") ;
+			perl_pkg.append("::" + st.nextToken()) ;
 		}
 
 		for (int i = 0 ; i < args.length ; i++){
@@ -170,7 +170,7 @@ public class InlineJavaPerlNatives extends InlineJavaPerlCaller {
 
 		InlineJavaUtils.debug(3, "exiting InvokePerlMethod") ;
 
-		return CallPerl(perl_pkg + "perl", method, args) ;
+		return CallPerl(perl_pkg.toString(), method, args) ;
 	}
 
 
@@ -225,11 +225,4 @@ public class InlineJavaPerlNatives extends InlineJavaPerlCaller {
 				ite.getTargetException()) ;
 		}
 	}
-
-
-	class Caller extends SecurityManager {
-		public Class getCaller(){
-			return getClassContext()[2] ;
-		}
-	}
 }
diff --git a/MANIFEST b/MANIFEST
index d740005..d5fe4b5 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -33,6 +33,10 @@ Java/sources/org/perl/inline/java/InlineJavaUserClassLoader.java
 Java/sources/org/perl/inline/java/InlineJavaUtils.java
 Java/sources/org/perl/inline/java/InlineJavaCallback.java
 Java/sources/org/perl/inline/java/InlineJavaCallbackQueue.java
+Java/sources/org/perl/inline/java/InlineJavaPerlNatives.java
+Java/Natives/Makefile.PL
+Java/Natives/Natives.pm
+Java/Natives/Natives.xs
 t/01_init.t
 t/02_primitives.t
 t/03_objects.t
@@ -50,6 +54,7 @@ t/10_5_shared_fork.t
 t/10_6_shared_sim.t
 t/11_exceptions.t
 t/12_callbacks.t
+t/12_1_perl_natives.t
 t/13_end.t
 t/types.java
 t/types.class
diff --git a/README b/README
index e412225..7d0c0d5 100644
--- a/README
+++ b/README
@@ -66,6 +66,12 @@ second time you test loading of an already built module.
 -------------------------------------------------------------------------------
 FEATURES:
 
+Inline::Java version 0.45 is a major upgrade that includes:
++ Fixed Makefile.PL arguments that were getting lost
++ Fixed deprecated require call
++ Fixed support for symbolic links in J2SDK directory
++ Added new experimental feature: PerlNatives
+
 Inline::Java version 0.44 is a major upgrade that includes:
 + Callbacks from multiple threads are now supported
 + Refactored (again...) studying/.jdat/cache stuff
diff --git a/TODO b/TODO
index db838c5..0b02387 100644
--- a/TODO
+++ b/TODO
@@ -1,6 +1,8 @@
 CODE:
 - Do more test for CLASSPATH combinations
 - Does STDIN still need to be closed in the JVM?
+- Review all changes for 0.45 (PerlNatives)
+- Document PerlNatives
 
 TEST:
 - Alpha
diff --git a/t/12_1_perl_natives.t b/t/12_1_perl_natives.t
index d39d087..ba2257f 100644
--- a/t/12_1_perl_natives.t
+++ b/t/12_1_perl_natives.t
@@ -1,32 +1,53 @@
 use strict ;
 use Test ;
 
+
 use Inline Config =>
-           DIRECTORY => './_Inline_test';
+           DIRECTORY => './_Inline_test' ;
 
-use Inline (
-	Java => 'DATA',
-) ;
 
 use Inline::Java qw(caught) ;
 
+use Inline (
+	Java => 'DATA',
+) ;
 
 BEGIN {
-	my $cnt = 1 ;
-	if (! $ENV{PERL_INLINE_JAVA_JNI}){
-		$cnt = 0 ;
+	print STDERR 
+		"\nNote: PerlNatives is still experimental and errors here can safely\n" .
+		"be ignored if you don't plan on using this feature. However, the\n" .
+		"author would appreciate if errors encountered here were reported\n" .
+		"to the mailing list (inline\@perl.org) along with your hardware/OS\n". 
+		"detail. Thank you.\n" ;
+} ;
+
+eval {
+	t121->init() ;
+} ;
+if ($@){
+	if ($@ =~ /Can\'t initialize PerlNatives/){
+		plan(tests => 0) ;
+		exit ;
+	}
+	else{
+		die($@) ;
 	}
-	plan(tests => $cnt) ;
 }
 
+
+plan(tests => 5) ;
+
+
 eval {
 	t121->init() ;
 	my $t = new t121() ;
-	print $t->yo("!!!!!") . "\n" ;
+	ok($t->types_stub(1, 2, 3, 4, 5, 6, 1, 2, "1000"), 1024) ;
+	ok($t->array_stub([34, 56], ["toto", "789"]), 789 + 34) ;
 
 	my $t2 = new t1212() ;
-	print $t2->yo("!!!!!") . "\n" ;
+	ok($t2->types_stub(1, 2, 3, 4, 5, 6, 1, 2, "1000"), 1024) ;
 
+	ok($t->callback_stub(), "toto") ;
 	ok($t->__get_private()->{proto}->ObjectCount(), 2) ;
 } ;
 if ($@){
@@ -42,25 +63,34 @@ if ($@){
 
 ##################################
 
-
-sub t121::perl::yo {
+package t121 ;
+sub types {
 	my $this = shift ;
-	my $s = shift ;
-	print "$s\n" ;
 
-	$this->pub_hello() ;
+	my $sum = 0 ;
+	map {$sum += $_} @_ ;
+	return $sum ;
+
+}
+
+
+sub array {
+	my $this = shift ;
+	my $i = shift ;
+	my $str = shift ;
 
-	return $s ;
+	return $i->[0] + $str->[1] ;
 }
 
 
-sub t121::perl::hello {
+sub callback {
 	my $this = shift ;
 
-	print "HELLO\n" ;
+	return $this->get_name() ;
 }
 
 
+package main ;
 __END__
 
 __Java__
@@ -70,6 +100,9 @@ import java.io.* ;
 import org.perl.inline.java.* ;
 
 class t121 extends InlineJavaPerlNatives {
+    static public boolean got14(){
+        return System.getProperty("java.version").startsWith("1.4") ;
+    }
 
 	public t121() throws InlineJavaException {
 	}
@@ -78,13 +111,26 @@ class t121 extends InlineJavaPerlNatives {
 		init("test") ;
 	}
 
-	public native String yo(String s) ;
+	public String types_stub(byte b, short s, int i, long j, float f, double d,
+        boolean x, char c, String str){
+		return types(b, s, i, j, f, d, x, c, str) ;
+	}
+	public native String types(byte b, short s, int i, long j, float f, double d,
+		boolean x, char c, String str) ;
 
-	public void pub_hello(){
-		hello();
+	public String array_stub(int i[], String str[]){
+		return array(i, str) ;
 	}
+	private native String array(int i[], String str[]) ;
 
-	protected native void hello() ;
+	public String callback_stub(){
+		return callback() ;
+	}
+	public native String callback() ;
+
+	public String get_name(){
+		return "toto" ;
+	}
 } ;
 
 

-- 
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