[libinline-java-perl] 236/398: ok 0.42

Jonas Smedegaard dr at jones.dk
Thu Feb 26 11:43:08 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 c43a2175ce4858073d6847b635da97d820c8ac96
Author: patrick_leb <>
Date:   Wed Sep 3 12:22:31 2003 +0000

    ok 0.42
---
 Java.pm                                     | 64 +++++++++------------
 Java.pod                                    | 46 ++++++++++++---
 Java/JNI.pm                                 |  2 +-
 Java/JNI.xs                                 | 17 ++++--
 Java/JVM.pm                                 |  4 +-
 Java/sources/InlineJavaProtocol.java        | 89 ++++++++++++++++++-----------
 Java/sources/InlineJavaUserClassLoader.java |  1 +
 README                                      |  7 +++
 README.JNI                                  |  6 +-
 TODO                                        |  3 +-
 t/08_study.t                                |  8 +--
 t/t1.pl                                     | 45 +++++++++------
 12 files changed, 177 insertions(+), 115 deletions(-)

diff --git a/Java.pm b/Java.pm
index 253fb77..3bf12bb 100644
--- a/Java.pm
+++ b/Java.pm
@@ -7,7 +7,7 @@ package Inline::Java ;
 
 use strict ;
 
-$Inline::Java::VERSION = '0.41' ;
+$Inline::Java::VERSION = '0.42' ;
 
 
 # DEBUG is set via the DEBUG config
@@ -124,6 +124,9 @@ sub validate {
 	$o->set_option('STUDY',					undef,	'a', 0, \%opts) ;
 	$o->set_option('AUTOSTUDY',				0,		'b', 1, \%opts) ;
 
+	$o->set_option('EXTRA_JAVA_ARGS',		'',		's', 1, \%opts) ;
+	$o->set_option('EXTRA_JAVAC_ARGS',		'',		's', 1, \%opts) ;
+
 	my @left_overs = keys(%opts) ;
 	if (scalar(@left_overs)){
 		croak "'$left_overs[0]' is not a valid configuration option for Inline::Java" ;
@@ -305,7 +308,8 @@ sub build {
 		my $cp = $ENV{CLASSPATH} || '' ;
 		$ENV{CLASSPATH} = make_classpath($o->get_java_config('CLASSPATH'), $server_jar, @prev_install_dirs) ;
 		Inline::Java::debug(2, "classpath: $ENV{CLASSPATH}") ;
-		my $cmd = portable("SUB_FIX_CMD_QUOTES", "\"$javac\" -d \"$install_dir\" $source > cmd.out $redir") ;
+		my $args = $o->get_java_config('EXTRA_JAVAC_ARGS') ;
+		my $cmd = portable("SUB_FIX_CMD_QUOTES", "\"$javac\" $args -d \"$install_dir\" $source > cmd.out $redir") ;
 		if ($o->get_config('UNTAINT')){
 			($cmd) = $cmd =~ /(.*)/ ;
 		}
@@ -399,18 +403,16 @@ sub load {
 		'auto', $o->get_api('modpname')) ;
 
 	# If the JVM is not running, we need to start it here.
+	my $cp = $ENV{CLASSPATH} || '' ;
 	if (! $JVM){
-		my $cp = $ENV{CLASSPATH} || '' ;
-		$ENV{CLASSPATH} = portable("SUB_FIX_CLASSPATH", get_server_jar()) ;
+		$ENV{CLASSPATH} = make_classpath(get_server_jar()) ;
 		Inline::Java::debug(2, "classpath: $ENV{CLASSPATH}") ;
 		$JVM = new Inline::Java::JVM($o) ;
 		$ENV{CLASSPATH}	= $cp ;
 		Inline::Java::debug(2, "classpath: $ENV{CLASSPATH}") ;
 
-		# Add CLASSPATH entries + user jar + $install_dir to the JVM classpath
-		my @cp = make_classpath($o->get_java_config('CLASSPATH'), get_user_jar()) ;
 		my $pc = new Inline::Java::Protocol(undef, $o) ;
-		$pc->AddClassPath(@cp, portable("SUB_FIX_CLASSPATH", $install_dir)) ;
+		$pc->AddClassPath(portable("SUB_FIX_CLASSPATH", get_user_jar())) ;
 
 		my $st = $pc->ServerType() ;
 		if ((($st eq "shared")&&(! $o->get_java_config('SHARED_JVM')))||
@@ -418,11 +420,14 @@ sub load {
 			croak "JVM type mismatch on port " . $JVM->{port} ;
 		}
 	}
-	else{
-		# Add $install_dir entry to the JVM classpath.
-		my $pc = new Inline::Java::Protocol(undef, $o) ;
-		$pc->AddClassPath(portable("SUB_FIX_CLASSPATH", $install_dir)) ;
-	}
+
+	$ENV{CLASSPATH}	= '' ;
+	my @cp = make_classpath(
+		$o->get_java_config('CLASSPATH'), $install_dir) ;
+	$ENV{CLASSPATH}	= $cp ;
+	
+	my $pc = new Inline::Java::Protocol(undef, $o) ;
+	$pc->AddClassPath(@cp) ;
 
 	# Add our Inline object to the list.
 	push @INLINES, $o ;
@@ -997,42 +1002,29 @@ sub cast {
 
 sub study_classes {
 	my $classes = shift ;
+	my $package = shift || caller() ;
 
-	# Here we will look to find an Inline object that is in the same 
-	# package as the caller. That way the classes can be used directly
-	# without having to use symbolic references.
-	my ($cur_pkg) = caller() ;
 	my $o = undef ;
 	foreach (@INLINES){
 		my $i = $_ ;
-		my $pkg = $i->get_api('pkg') ;
-		if ($pkg eq $cur_pkg){
+		my $pkg = $i->get_api('pkg') || 'main' ;
+		if ($pkg eq $package){
 			$o = $i ;
 			last ;
 		}
 	}
 
-	my $no_pkg = 1 ;
-	if (! defined($o)){
-		srand() ;
-		$o = @INLINES[int(rand(@INLINES))] ;
-		$no_pkg = 0 ;
-	}
-
-	$o->_study($classes, 0) ;
-
-	my $pkg = undef ;
-	if ($no_pkg){
-		return $pkg ;
+	if (defined($o)){
+		$o->_study($classes, 0) ;
 	}
-	else{
-		my $pkg = $o->get_api('pkg') ;
-		if (! $pkg){
-			$pkg = "main" ;
+	else {
+		my $msg = "Can't place studied classes under package since Inline::Java was not used there. Valid packages are:\n" ;
+		foreach (@INLINES){
+			my $i = $_ ;
+			my $pkg = $i->get_api('pkg') || 'main' ;
+			$msg .= "  $pkg\n" ;
 		}
 	}
-
-	return $pkg ;
 }
 
 
diff --git a/Java.pod b/Java.pod
index f0262a3..0c95bbe 100644
--- a/Java.pod
+++ b/Java.pod
@@ -142,11 +142,10 @@ behavior of C<Inline::Java>:
       make use of the same JVM.
 
    CLASSPATH:
-      Adds the specified CLASSPATH to the environment CLASSPATH.
+      Adds the specified CLASSPATH. This CLASSPATH will only be available
+      threw the use classloader. To set the CLASSPATH globally, use the 
+      CLASSPATH environment variable.
       Ex: CLASSPATH => '/my/other/java/classses'
-      Note: This configuration option only has an effect on the first
-      'use Inline Java' call inside a Perl script, since all other calls 
-      make use of the same JVM.
 
    JNI:
       Toggles the execution mode. The default is to use the client/server
@@ -154,20 +153,25 @@ behavior of C<Inline::Java>:
       time though. See README and README.JNI for more information), set 
       JNI to 1. 
       Ex: JNI => 1
-      Note: This can also be set globally by setting the 
-      PERL_INLINE_JAVA_JNI environment variable to 1.
       Note: This configuration option only has an effect on the first
       'use Inline Java' call inside a Perl script, since all other calls 
       make use of the same JVM.
 
+   EXTRA_JAVA_ARGS:
+   EXTRA_JAVAC_ARGS:
+      Specify extra command line parameters to be passed to, respectively,  
+      the JVM and the Java compiler.
+      Ex: EXTRA_JAVA_ARGS => '-Xmx96m'
+      Note: EXTRA_JAVA_ARGS only has an effect on the first
+      'use Inline Java' call inside a Perl script, since all other calls 
+      make use of the same JVM.
+
    EMBEDDED_JNI:
       Same as JNI, except C<Inline::Java> expects the JVM to already be
       loaded and to have loaded the Perl interpreter that is running the
       script. This is an advanced feature that should only be need in
       very specific circumstances.
       Ex: EMBEDDED_JNI => 1
-      Note: This can also be set globally by setting the 
-      PERL_INLINE_JAVA_EMBEDDED_JNI environment variable to 1.
       Note: The EMBEDDED_JNI option sets the JNI option.
       Note: This configuration option only has an effect on the first
       'use Inline Java' call inside a Perl script, since all other calls 
@@ -716,6 +720,32 @@ In this case C<Inline::Java> intercepts the return value of the get_hm()
 method, sees that it's of a type that it doesn't know about 
 (java.lang.HashMap), and immediately studies the class. After that call 
 the java::lang::HashMap class is available to use through Perl.
+
+In some cases you may not know which classes to study until runtime. In 
+these cases you can use the study_classes() function:
+
+=for comment
+
+   use Inline (
+      Java => 'STUDY',
+      STUDY => [],
+   ) ;
+   use Inline::Java qw(study_classes) ;
+
+   study_classes(['java.util.HashMap'], undef) ;
+   my $hm = new java::util::HashMap() ;
+   $hm->put("key", "value") ;
+   my $val = $hm->get("key") ;
+   print($val . "\n") ; # prints value
+
+=for comment
+
+The study_classes() function takes 2 arguments, a reference to an array of
+class names (like the STUDY configuration option) and the name of the 
+package in which to bind those classes. If the name of the package is 
+undefined, the classes will be bound to the current (caller) package.
+Note: You can only specify the names of packages in which you have 
+previously "used" C<Inline::Java>.
    Z<>
 
 
diff --git a/Java/JNI.pm b/Java/JNI.pm
index b232cb1..668d8ab 100644
--- a/Java/JNI.pm
+++ b/Java/JNI.pm
@@ -4,7 +4,7 @@ package Inline::Java::JNI ;
 
 use strict ;
 
-$Inline::Java::JNI::VERSION = '0.40' ;
+$Inline::Java::JNI::VERSION = '0.42' ;
 
 use DynaLoader ;
 use Carp ;
diff --git a/Java/JNI.xs b/Java/JNI.xs
index 521ac64..4edb3bd 100644
--- a/Java/JNI.xs
+++ b/Java/JNI.xs
@@ -117,9 +117,10 @@ PROTOTYPES: DISABLE
 
 
 InlineJavaJNIVM * 
-new(CLASS, classpath, embedded, debug)
+new(CLASS, classpath, args, embedded, debug)
 	char * CLASS
 	char * classpath
+	char * args
 	int	embedded
 	int	debug
 
@@ -141,16 +142,20 @@ new(CLASS, classpath, embedded, debug)
 	RETVAL->debug = debug ;
 	RETVAL->destroyed = 0 ;
 
-	options[0].optionString = ((RETVAL->debug > 5) ? "-verbose" : "-verbose:") ;
-	cp = (char *)malloc((strlen(classpath) + 128) * sizeof(char)) ;
-	sprintf(cp, "-Djava.class.path=%s", classpath) ;
-	options[1].optionString = cp ;
-
 	vm_args.version = JNI_VERSION_1_2 ;
 	vm_args.options = options ;
 	vm_args.nOptions = 2 ;
 	vm_args.ignoreUnrecognized = JNI_FALSE ;
 
+	options[0].optionString = ((RETVAL->debug > 5) ? "-verbose" : "-verbose:") ;
+	cp = (char *)malloc((strlen(classpath) + 128) * sizeof(char)) ;
+	sprintf(cp, "-Djava.class.path=%s", classpath, args) ;
+	options[1].optionString = cp ;
+	if (strlen(args) > 0){
+		options[2].optionString = args ;
+		vm_args.nOptions++ ;
+	}
+
 	/* Embedded patch and idea by Doug MacEachern */
 	if (RETVAL->embedded) {
 		/* We are already inside a JVM */
diff --git a/Java/JVM.pm b/Java/JVM.pm
index ab37af6..8d03f8b 100644
--- a/Java/JVM.pm
+++ b/Java/JVM.pm
@@ -39,11 +39,13 @@ sub new {
 		Inline::Java::debug(1, "starting JVM...") ;
 	}
 
+	my $args = $o->get_java_config('EXTRA_JAVA_ARGS') ;
 	if ($o->get_java_config('JNI')){
 		Inline::Java::debug(1, "JNI mode") ;
 
 		my $jni = new Inline::Java::JNI(
 			$ENV{CLASSPATH} || '',
+			$args || '',
 			$this->{embedded},
 			Inline::Java::get_DEBUG(),
 		) ;
@@ -101,7 +103,7 @@ sub new {
 			"java" . Inline::Java::portable("EXE_EXTENSION")) ;
 
 		my $shared = ($this->{shared} ? "true" : "false") ;
-		my $cmd = Inline::Java::portable("SUB_FIX_CMD_QUOTES", "\"$java\" org.perl.inline.java.InlineJavaServer $debug $this->{port} $shared") ;
+		my $cmd = Inline::Java::portable("SUB_FIX_CMD_QUOTES", "\"$java\" $args org.perl.inline.java.InlineJavaServer $debug $this->{port} $shared") ;
 		Inline::Java::debug(2, $cmd) ;
 		if ($o->get_config('UNTAINT')){
 			($cmd) = $cmd =~ /(.*)/ ;
diff --git a/Java/sources/InlineJavaProtocol.java b/Java/sources/InlineJavaProtocol.java
index 0a4c45f..b16eea6 100644
--- a/Java/sources/InlineJavaProtocol.java
+++ b/Java/sources/InlineJavaProtocol.java
@@ -15,6 +15,7 @@ class InlineJavaProtocol {
 	private String cmd ;
 	private String response = null ;
 
+	static private HashMap member_cache = new HashMap() ;
 
 	InlineJavaProtocol(InlineJavaServer _ijs, String _cmd) {
 		ijs = _ijs ;
@@ -423,7 +424,6 @@ class InlineJavaProtocol {
 		Makes sure a method exists
 	*/
 	ArrayList ValidateMethod(boolean constructor, Class c, String name, StringTokenizer st) throws InlineJavaException {
-		Member ma[] = (constructor ? (Member [])c.getConstructors() : (Member [])c.getMethods()) ;
 		ArrayList ret = new ArrayList() ;
 
 		// Extract signature
@@ -435,34 +435,45 @@ class InlineJavaProtocol {
 			args.add(args.size(), st.nextToken()) ;
 		}
 
-		ArrayList ml = new ArrayList(ma.length) ;
+		String key = c.getName() + "." + name + signature ;
+		ArrayList ml = new ArrayList() ;
 		Class params[] = null ;
-		for (int i = 0 ; i < ma.length ; i++){
-			Member m = ma[i] ;
 
-			if (m.getName().equals(name)){
-				InlineJavaUtils.debug(3, "found a " + name + (constructor ? " constructor" : " method")) ;
-
-				if (constructor){
-					params = ((Constructor)m).getParameterTypes() ;
-				}
-				else{
-					params = ((Method)m).getParameterTypes() ;
-				}
-
-				// Now we check if the signatures match
-				String sign = InlineJavaUtils.CreateSignature(params, ",") ;
-				InlineJavaUtils.debug(3, sign + " = " + signature + "?") ;
+		Member cached = (Member)member_cache.get(key) ;
+		if (cached != null){
+				InlineJavaUtils.debug(3, "method was cached") ;
+				ml.add(ml.size(), cached) ;
+		}
+		else{
+			Member ma[] = (constructor ? (Member [])c.getConstructors() : (Member [])c.getMethods()) ;
+			for (int i = 0 ; i < ma.length ; i++){
+				Member m = ma[i] ;
 
-				if (signature.equals(sign)){
-					InlineJavaUtils.debug(3, "has matching signature " + sign) ;
-					ml.add(ml.size(), m) ;
-					break ;
+				if (m.getName().equals(name)){
+					InlineJavaUtils.debug(3, "found a " + name + (constructor ? " constructor" : " method")) ;
+	
+					if (constructor){
+						params = ((Constructor)m).getParameterTypes() ;
+					}
+					else{
+						params = ((Method)m).getParameterTypes() ;
+					}
+
+					// Now we check if the signatures match
+					String sign = InlineJavaUtils.CreateSignature(params, ",") ;
+					InlineJavaUtils.debug(3, sign + " = " + signature + "?") ;
+
+					if (signature.equals(sign)){
+						InlineJavaUtils.debug(3, "has matching signature " + sign) ;
+						ml.add(ml.size(), m) ;
+						member_cache.put(key, m) ;
+						break ;
+					}
 				}
 			}
 		}
 
-		// Now we got a list of matching methods. 
+		// Now we got a list of matching methods (actually 0 or 1). 
 		// We have to figure out which one we will call.
 		if (ml.size() == 0){
 			// Nothing matched. Maybe we got a default constructor
@@ -511,7 +522,6 @@ class InlineJavaProtocol {
 		Makes sure a member exists
 	*/
 	ArrayList ValidateMember(Class c, String name, StringTokenizer st) throws InlineJavaException {
-		Field fa[] = c.getFields() ;
 		ArrayList ret = new ArrayList() ;
 
 		// Extract member type
@@ -520,19 +530,29 @@ class InlineJavaProtocol {
 		// Extract the argument
 		String arg = st.nextToken() ;
 
-		ArrayList fl = new ArrayList(fa.length) ;
+		String key = type + " " + c.getName() + "." + name ;
+		ArrayList fl = new ArrayList() ;
 		Class param = null ;
-		for (int i = 0 ; i < fa.length ; i++){
-			Field f = fa[(InlineJavaUtils.ReverseMembers() ? (fa.length - 1 - i) : i)] ;
-
-			if (f.getName().equals(name)){
-				InlineJavaUtils.debug(3, "found a " + name + " member") ;
 
-				param = f.getType() ;
-				String t = param.getName() ;
-				if (type.equals(t)){
-					InlineJavaUtils.debug(3, "has matching type " + t) ;
-					fl.add(fl.size(), f) ;
+		Member cached = (Member)member_cache.get(key) ;
+		if (cached != null){
+			InlineJavaUtils.debug(3, "member was cached") ;
+			fl.add(fl.size(), cached) ;
+		}
+		else {
+			Field fa[] = c.getFields() ;
+			for (int i = 0 ; i < fa.length ; i++){
+				Field f = fa[(InlineJavaUtils.ReverseMembers() ? (fa.length - 1 - i) : i)] ;
+
+				if (f.getName().equals(name)){
+					InlineJavaUtils.debug(3, "found a " + name + " member") ;
+
+					param = f.getType() ;
+					String t = param.getName() ;
+					if (type.equals(t)){
+						InlineJavaUtils.debug(3, "has matching type " + t) ;
+						fl.add(fl.size(), f) ;
+					}
 				}
 			}
 		}
@@ -551,6 +571,7 @@ class InlineJavaProtocol {
 			// If we have more that one, we use the last one, which is the most
 			// specialized
 			Field f = (Field)fl.get(fl.size() - 1) ;
+			member_cache.put(key, f) ;
 			param = f.getType() ;
 
 			String msg = "For member " + name + " of class " + c.getName() + ": " ;
diff --git a/Java/sources/InlineJavaUserClassLoader.java b/Java/sources/InlineJavaUserClassLoader.java
index b46b0e2..2b2756d 100644
--- a/Java/sources/InlineJavaUserClassLoader.java
+++ b/Java/sources/InlineJavaUserClassLoader.java
@@ -35,6 +35,7 @@ class InlineJavaUserClassLoader extends URLClassLoader {
 			if (urls.get(u) == null){
 	            urls.put(u, "1") ;
 	            addURL(u) ;
+				InlineJavaUtils.debug(2, "added " + u + " to classpath") ;
 	        }
 		}
 		catch (MalformedURLException e){
diff --git a/README b/README
index fd5797c..fd88bff 100644
--- a/README
+++ b/README
@@ -70,6 +70,13 @@ WARNING: THIS IS ALPHA SOFTWARE. It is incomplete and possibly unreliable.
          It is also possible that some elements of the interface (API) will 
          change in future releases.
 
+Inline::Java version 0.42 is a minor upgrade that includes:
++ Fixed more CLASSPATH issues. CLASSPATH now works like this:
+   - CLASSPATH environment variable is global.
+   - CLASSPATH configuration option is local to the current script.
++ Added method cache to increase performance and decrease reflection 
+  API calls.
+
 Inline::Java version 0.41 is a minor upgrade that includes:
 + Fixed CLASSPATH bug
 + Possibly (!) fixed test suite problems under heavy load
diff --git a/README.JNI b/README.JNI
index e91503d..82fa40a 100644
--- a/README.JNI
+++ b/README.JNI
@@ -31,7 +31,7 @@ objects cannot be located at runtime.
 OVERVIEW
 --------
               +----------+----------+----------+
-              | JDK1.2.2 | JDK1.3.1 | JDK1.4.0 |
+              | JDK1.2.2 | JDK1.3.1 | JDK1.4.2 |
 +-------------+----------+----------+----------+
 | Win32       |    ok    |    ok    |    ok    |
 +-------------+----------+----------+----------+
@@ -50,7 +50,7 @@ Java 2 SDK 1.2.2:
 Java 2 SDK 1.3.1:
 	The JNI extension runs without problems.
 
-Java 2 SDK 1.4.0:
+Java 2 SDK 1.4.2:
 	The JNI extension runs without problems.
 
 
@@ -81,7 +81,7 @@ Also, make sure you use do not use 'classic' VM. This one should only
 be used with 'green threads', which don't seem to work with JNI. Use either 
 the 'client' or the 'server' VMs.
 
-Java 2 SDK 1.4.0:
+Java 2 SDK 1.4.2:
     The same as Java 2 SDK 1.3.1 applies.
 
 	
diff --git a/TODO b/TODO
index 3ce0de4..b130a25 100644
--- a/TODO
+++ b/TODO
@@ -1,6 +1,5 @@
 CODE:
-- Check John's bug #5. It seems if two modules have the same
-  module name some stuff gets screwed up.
+- Do more test for CLASSPATH combinations
 
 TEST:
 - Alpha
diff --git a/t/08_study.t b/t/08_study.t
index 8ef7211..9333f34 100644
--- a/t/08_study.t
+++ b/t/08_study.t
@@ -43,17 +43,13 @@ use Inline::Java qw(study_classes) ;
 
 
 BEGIN {
-	plan(tests => 10) ;
+	plan(tests => 9) ;
 }
 
-my $pkg = study_classes([
+study_classes([
 	't.no_const'
 ]) ;
 
-# There is a 'use Inline Java' somewhere in the current 
-# package, so we can call the classes directly.
-ok(! defined($pkg)) ;
-
 my $t = new study::t::types() ;
 
 {
diff --git a/t/t1.pl b/t/t1.pl
index 2fe3b73..d37c79f 100755
--- a/t/t1.pl
+++ b/t/t1.pl
@@ -5,25 +5,34 @@ use blib ;
 
 use Inline Java => <<'END_OF_JAVA_CODE' ;
 
-package test1.test2.test3 ;
- 
-public class Pod_alu {
-      public Pod_alu(){
-      }
-
-      public int add(int i, int j){
-         return i + j ;
-      }
-
-      public int subtract(int i, int j){
-         return i - j ;
-      }
-   }   
-END_OF_JAVA_CODE
+public class cache {
+	public int i = 0 ;
+
+	public cache(){
+	}
+
+	public void m1(int j){
+		i++ ;
+	}
+
+	public void m2(int i){
+	}
 
+	public void m3(int i){
+	}
+
+	public void m4(int i){
+	}
+
+	public void m5(int i){
+	}
+}   
+END_OF_JAVA_CODE
 
-my $alu = new test1::test2::test3::Pod_alu() ;
-print($alu->add(9, 16) . "\n") ; # prints 25
-print($alu->subtract(9, 16) . "\n") ; # prints -7
 
+my $c = new cache() ;
+for (my $i = 0 ; $i < 10000 ; $i++){
+	$c->m1($i) ;
+}
+print $c->{i} . "\n" ;
 

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