[libinline-java-perl] 309/398: ok
Jonas Smedegaard
dr at jones.dk
Thu Feb 26 11:43:17 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 ae3ddedab08ba26c1c2623574716b5290a7be66e
Author: patrick_leb <>
Date: Mon Apr 19 16:28:20 2004 +0000
ok
---
Java/Callbacks.pod | 1074 ++++++++++++++++++++++++++++++
Java/PerlInterpreter/PerlInterpreter.pod | 132 ++++
Java/PerlNatives/Makefile.PL | 13 +
Java/PerlNatives/PerlNatives.pm | 7 +
Java/PerlNatives/PerlNatives.pod | 1074 ++++++++++++++++++++++++++++++
Java/PerlNatives/PerlNatives.xs | 254 +++++++
6 files changed, 2554 insertions(+)
diff --git a/Java/Callbacks.pod b/Java/Callbacks.pod
new file mode 100644
index 0000000..5aa37d8
--- /dev/null
+++ b/Java/Callbacks.pod
@@ -0,0 +1,1074 @@
+=head1 NAME
+
+Inline::Java::Callbacks - Callback into Perl from Java.
+
+=head1 SYNOPSIS
+
+=for comment
+
+ use Inline Java => <<'END_OF_JAVA_CODE' ;
+ 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
+
+ my $alu = new Pod_alu() ;
+ print($alu->add(9, 16) . "\n") ; # prints 25
+ print($alu->subtract(9, 16) . "\n") ; # prints -7
+
+=for comment
+
+
+=head1 DESCRIPTION
+
+The C<Inline::Java> module allows you to put Java source code
+directly "inline" in a Perl script or module. A Java compiler
+is launched and the Java code is compiled. Then Perl asks the
+Java classes what public methods have been defined. These classes
+and methods are available to the Perl program as if they had been
+written in Perl.
+
+The process of interrogating the Java classes for public methods
+occurs the first time you run your Java code. The namespace is
+cached, and subsequent calls use the cached version.
+ Z<>
+
+
+=head1 USING THE Inline::Java MODULE
+
+C<Inline::Java> is driven by fundamentally the same idea as other
+C<Inline> language modules, like C<Inline::C> or C<Inline::CPP>.
+Because Java is both compiled and interpreted, the method of getting
+your code is different, but overall, using C<Inline::Java> is very similar
+to any other C<Inline> language module.
+
+This section will explain the different ways to C<use> Inline::Java.
+For more details on C<Inline>, see 'perldoc Inline'.
+
+B<Basic Usage>
+
+The most basic form for using C<Inline::Java> is:
+
+ use Inline Java => 'Java source code' ;
+
+Of course, you can use Perl's "here document" style of quoting to make
+the code slightly easier to read:
+
+ use Inline Java => <<'END';
+
+ Java source code goes here.
+
+ END
+
+The source code can also be specified as a filename, a subroutine
+reference (sub routine should return source code), or an array
+reference (array contains lines of source code). This information
+is detailed in 'perldoc Inline'.
+
+In order for C<Inline::Java> to function properly, it needs to know
+where to find a Java 2 SDK on your machine. This is done using one
+of the following techniques:
+
+ - set the J2SDK configuration option to the correct directory
+ - set the PERL_INLINE_JAVA_J2SDK environment variable to the
+ correct directory
+
+If none of these are specified, C<Inline::Java> will use the Java
+2 SDK that was specified a install time (see below).
+
+
+=head1 DEFAULT JAVA 2 SDK
+
+When C<Inline::Java> was installed, the path to the Java 2 SDK that was
+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=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.
+If you wish use a different Java 2 SDK temporarily, see the J2SDK
+configuration option described below.
+
+
+=head1 CONFIGURATION OPTIONS
+
+There are a number of configuration options that dictate the
+behavior of C<Inline::Java>:
+
+ J2SDK:
+ Specifies the path to your Java 2 SDK.
+ Ex: J2SDK => '/my/java/2/sdk/path'
+ 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.
+
+ PORT:
+ Specifies the starting port number for the server. If many
+ C<Inline::Java> blocks are declared, the port number is
+ incremented each time.
+ Default is 0 (next available port number).
+ Default for SHARED_JVM mode is 7890.
+ Ex: PORT => 4567
+ 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.
+
+ STARTUP_DELAY:
+ Specifies the maximum number of seconds that the Perl script
+ will try to connect to the Java server. In other this is the
+ delay that Perl gives to the Java server to start.
+ Default is 15 seconds.
+ Ex: STARTUP_DELAY => 20
+ 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.
+
+ 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'
+
+ JNI:
+ Toggles the execution mode. The default is to use the client/server
+ mode. To use the JNI extension (you must have built it at install
+ time though. See README and README.JNI for more information), set
+ JNI to 1.
+ Ex: JNI => 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. Use with caution as some options may
+ alter normal C<Inline::Java> behavior.
+ 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: 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
+ make use of the same JVM.
+
+ SHARED_JVM:
+ This mode enables mutiple processes to share the same JVM. It was
+ created mainly in order to be able to use C<Inline::Java> under
+ mod_perl.
+ Ex: SHARED_JVM => 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.
+
+ PRIVATE:
+ In SHARED_JVM mode, makes every connection to the JVM use a different
+ classloader so that each connection is isolated from the others.
+ Ex: PRIVATE => 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.
+
+ DEBUG:
+ Enables debugging info. Debugging now uses levels (1 through 5)
+ that (loosely) follow these definitions:
+ 1 = Major program steps
+ 2 = Object creation/destruction
+ 3 = Method/member accesses + packet dumps
+ 4 = Everything else
+ 5 = Data structure dumps
+ Ex: DEBUG => 2
+
+ DEBUGGER:
+ Starts jdb, (the Java debugger) instead of the regular Java JVM.
+ This option will also cause the Java code to be compiled using the
+ '-g' switch for extra debugging information. EXTRA_JAVA_ARGS can
+ be used use to pass extra options to the debugger.
+ Ex: DEBUGGER => 1
+
+ WARN_METHOD_SELECT:
+ Throws a warning when C<Inline::Java> has to 'choose' between
+ different method signatures. The warning states the possible
+ choices and the signature chosen.
+ Ex: WARN_METHOD_SELECT => 1
+
+ STUDY:
+ Takes an array of Java classes that you wish to have
+ C<Inline::Java> learn about so that you can use them inside Perl.
+ Ex: STUDY => ['java.lang.HashMap', 'my.class']
+
+ AUTOSTUDY:
+ Makes C<Inline::Java> automatically study unknown classes it
+ encounters them.
+ Ex: AUTOSTUDY => 1
+
+
+=head1 ENVIRONMENT VARIABLES
+
+Every configuration option listed above, with the exception of STUDY,
+can be specified using an environment variable named using the
+following convention:
+
+ PERL_INLINE_JAVA_<option name>
+
+For example, your can specified the JNI option usng the
+PERL_INLINE_JAVA_JNI environment variable.
+
+Note that environment variables take precedence over options specified
+in the script itself.
+
+Under Win32, you can also use set the PERL_INLINE_JAVA_COMMAND_COM
+environment variable to a true value to indicate that you are using
+the command.com shell. However, C<Inline::Java> should normally be
+able to determine this on its own.
+
+
+=head1 CLASSES AND OBJECTS
+
+Because Java is object oriented, any interface between Perl and Java
+needs to support Java classes adequately.
+
+Example:
+
+=for comment
+
+ use Inline Java => <<'END' ;
+ class Pod_1 {
+ String data = "data" ;
+ static String sdata = "static data" ;
+
+ public Pod_1(){
+ }
+
+ public String get_data(){
+ return data ;
+ }
+
+ public static String get_static_data(){
+ return sdata ;
+ }
+
+ public void set_data(String d){
+ data = d ;
+ }
+
+ private void priv(){
+ }
+ }
+ END
+
+ my $obj = new Pod_1 ;
+ print($obj->get_data() . "\n") ; # prints data
+ $obj->set_data("new data") ;
+ print($obj->get_data() . "\n") ; # prints new data
+
+=for comment
+
+C<Inline::Java> created a new namespace called C<main::Pod_1> and
+created the following functions:
+
+ sub main::Pod_::new { ... }
+ sub main::Pod_::Pod_1 { ... }
+ sub main::Pod_::get_data { ... }
+ sub main::Pod_::get_sdata { ... }
+ sub main::Pod_::set_data { ... }
+ sub main::Pod_::DESTROY { ... }
+
+Note that only the public methods are exported to Perl.
+
+Inner classes are also supported, you simply need to supply a reference
+to an outer class object as the first parameter of the constructor:
+
+=for comment
+
+ use Inline Java => <<'END' ;
+ class Pod_2 {
+ public Pod_2(){
+ }
+
+ public class Pod_2_Inner {
+ public String name = "Pod_2_Inner" ;
+
+ public Pod_2_Inner(){
+ }
+ }
+ }
+ END
+
+ my $obj = new Pod_2() ;
+ my $obj2 = new Pod_2::Pod_2_Inner($obj) ;
+ print($obj2->{name} . "\n") ; # prints Pod_2_Inner
+
+=for comment
+
+=head1 METHODS
+
+In the previous example we have seen how to call a method. You can also
+call static methods in the following manner:
+
+ print Pod_1->get_sdata() . "\n" ; # prints static data
+ # or
+ my $obj = new Pod_1() ;
+ print $obj->get_sdata() . "\n" ; # prints static data
+
+You can pass any kind of Perl scalar or any Java object to a method. It
+will be automatically converted to the correct type:
+
+=for comment
+
+ use Inline Java => <<'END' ;
+ class Pod_3_arg {
+ public Pod_3_arg(){
+ }
+ }
+ class Pod_3 {
+ public int n ;
+
+ public Pod_3(int i, String j, Pod_3_arg k) {
+ n = i ;
+ }
+ }
+ END
+
+ my $obj = new Pod_3_arg() ;
+ my $obj2 = new Pod_3(5, "toto", $obj) ;
+ print($obj2->{n} . "\n") ; # prints 5
+
+=for comment
+
+will work fine. These objects can be of any type, even if these types
+are not known to C<Inline::Java>. This is also true for return types:
+
+=for comment
+
+ use Inline Java => <<'END' ;
+ import java.util.* ;
+
+ class Pod_4 {
+ public Pod_4(){
+ }
+
+ public HashMap get_hash(){
+ HashMap h = new HashMap() ;
+ h.put("key", "value") ;
+
+ return h ;
+ }
+
+ public String do_stuff_to_hash(HashMap h){
+ return (String)h.get("key") ;
+ }
+ }
+ END
+
+ my $obj = new Pod_4() ;
+ my $h = $obj->get_hash() ;
+ print($obj->do_stuff_to_hash($h) . "\n") ; # prints value
+
+=for comment
+
+Objects of types unknown to Perl can exist in the Perl space, you just
+can't call any of their methods. See the STUDYING section for more
+information on how to tell C<Inline::Java> to learn about these classes.
+ Z<>
+
+
+=head1 MEMBER VARIABLES
+
+You can also access all public member variables (static or not) from Perl.
+As with method arguments, the types of these variables does not need to
+be known to Perl:
+
+=for comment
+
+ use Inline Java => <<'END' ;
+ import java.util.* ;
+
+ class Pod_5 {
+ public int i ;
+ public static HashMap hm ;
+
+ public Pod_5(){
+ }
+ }
+ END
+
+ my $obj = new Pod_5() ;
+ $obj->{i} = 2 ;
+ print($obj->{i} . "\n") ; # prints 2
+ my $hm1 = $obj->{hm} ; # instance way
+ my $hm2 = $Pod_4::hm ; # static way
+
+=for comment
+
+Note: Watch out for typos when accessing members in the static fashion,
+'use strict' will not catch them since they have a package name...
+ Z<>
+
+
+=head1 ARRAYS
+
+You can also send, receive and modify arrays. This is done simply by
+using Perl lists:
+
+=for comment
+
+ use Inline Java => <<'END' ;
+ import java.util.* ;
+
+ class Pod_6 {
+ public int i[] = {5, 6, 7} ;
+
+ public Pod_6(){
+ }
+
+ public String [] f(String a[]){
+ return a ;
+ }
+
+ public String [][] f(String a[][]){
+ return a ;
+ }
+ }
+ END
+
+ my $obj = new Pod_6() ;
+ my $i_2 = $obj->{i}->[2] ; # 7
+ print($i_2 . "\n") ; # prints 7
+
+ my $a1 = $obj->f(["a", "b", "c"]) ; # String []
+ my $a2 = $obj->f([
+ ["00", "01"],
+ ["10", "11"],
+ ]) ; # String [][]
+ print($a2->[1]->[0] . "\n") ; # prints 10
+
+=for comment
+
+=head1 TYPE CASTING
+
+Sometimes when a class as many signatures for the same method,
+C<Inline::Java> will have to select one of the signatures based on
+the arguments that are passed:
+
+=for comment
+
+ use Inline Java => <<'END' ;
+ class Pod_7 {
+ public Pod_7(){
+ }
+
+ public String f(int i){
+ return "int" ;
+ }
+
+ public String f(char c){
+ return "char" ;
+ }
+ }
+ END
+
+ my $obj = new Pod_7() ;
+ print($obj->f('5') . "\n") ; # prints int
+
+=for comment
+
+In this case, C<Inline::Java> will call f(int i), because '5' is an integer.
+But '5' is a valid char as well. So to force the call of f(char c), do the
+following:
+
+ use Inline::Java qw(cast) ;
+ $obj->f(cast('char', '5')) ;
+ # or
+ $obj->f(Inline::Java::cast('char', '5')) ;
+
+The cast function forces the selection of the matching signature. Note that
+the cast must match the argument type exactly. Casting to a class that
+extends the argument type will not work.
+
+Another case where type casting is need is when one wants to pass an array
+as a java.lang.Object:
+
+ use Inline Java => <<'END';
+ class Pod_8 {
+ public Object o ;
+ int a[] = {1, 2, 3} ;
+
+ public Pod_8() {
+ }
+ }
+ END
+
+ my $obj = new Pod_8() ;
+ $obj->{o} = [1, 2, 3] ; # No!
+
+The reason why this will not work is simple. When C<Inline::Java> sees an
+array, it checks the Java type you are trying to match it against to validate
+the construction of your Perl list. But in this case, it can't validate
+the array because you're assigning it to an Object. You must use the 3
+parameter version of the cast function to do this:
+
+ $obj->{o} = Inline::Java::cast(
+ "java.lang.Object",
+ [1, 2, 3],
+ "[Ljava.lang.String;") ;
+
+This tells C<Inline::Java> to validate your Perl list as a String [], and
+then cast it as an Object.
+
+Here is how to construct the array type representations:
+
+ [<type> -> 1 dimensional <type> array
+ [[<type> -> 2 dimensional <type> array
+ ...
+
+ where <type> is one of:
+ B byte S short I int J long
+ F float D double C char Z boolean
+
+ L<class>; array of <class> objects
+
+This is described in more detail in most Java books that talk about
+reflection.
+
+But you only need to do this if you have a Perl list. If you already have a
+Java array reference obtained from elsewhere, you don't even need to cast:
+
+ $obj->{o} = $obj->{a} ;
+
+
+=head1 EXCEPTIONS
+
+You can now (as of 0.31) catch exceptions as objects when they are thrown
+from Java. To do this you use the regular Perl exception tools: eval and
+$@. A helper function named 'caught' is provided to help determine the
+type of the exception. Here is a example of a typical use:
+
+=for comment
+
+ use Inline Java => <<'END' ;
+ import java.util.* ;
+
+ class Pod_9 {
+ public Pod_9(boolean t) throws Exception {
+ if (t){
+ throw new Exception("ouch!") ;
+ }
+ }
+ }
+ END
+
+ use Inline::Java qw(caught) ;
+
+ eval {
+ my $obj = new Pod_9(1) ;
+ } ;
+ if ($@){
+ if (caught("java.lang.Exception")){
+ my $msg = $@->getMessage() ;
+ print($msg . "\n") ; # prints ouch!
+ }
+ else{
+ # It wasn't a Java exception after all...
+ die $@ ;
+ }
+ }
+
+=for comment
+
+What's important to understand is that $@ actually contains a reference
+to the Throwable object that was thrown by Java. The getMessage() function
+is really a method of the java.lang.Exception class. So if Java is throwing
+a custom exception you have in your code, you will have access to that
+exception object's public methods just like any other Java object in
+C<Inline::Java>. It is also probably a good idea to undef $@ once you have
+treated a Java exception, or else the object still has a reference until
+$@ is reset by the next eval.
+ Z<>
+
+
+=head1 CALLBACKS
+
+You can now (as of 0.31), call Perl functions from Java. To do this you
+need to create an org.perl.inline.java.InlinePerlJavaCaller object. You
+can then use the CallPerl method to call your Perl function. You pass the
+parameters using an array of Objects. The method will return the result in
+an Object, which you must then cast as a String (if your Perl method
+returns a Perl scalar), or anything else if your Perl function returns
+an "Inline::Java" object. Here is a example of a typical use:
+
+=for comment
+
+ use Inline Java => <<'END' ;
+ import java.util.* ;
+ import org.perl.inline.java.* ;
+
+ class Pod_regexp extends InlineJavaPerlCaller {
+ public Pod_regexp() throws InlineJavaException {
+ }
+
+ public boolean match(String target, String pattern)
+ throws InlineJavaException {
+ try {
+ String m = (String)CallPerl("main", "regexp",
+ new Object [] {target, pattern}) ;
+
+ if (m.equals("1")){
+ return true ;
+ }
+ }
+ catch (InlineJavaPerlException pe){
+ // $@ is in pe.GetObject()
+ }
+
+ return false ;
+ }
+ }
+ END
+
+ my $re = new Pod_regexp() ;
+ my $match = $re->match("Inline::Java", "^Inline") ;
+ print($match . "\n") ; # prints 1
+
+ sub regexp {
+ my $target = shift ;
+ my $pattern = shift ;
+
+ return ($target =~ /$pattern/) ;
+ }
+
+=for comment
+
+The CallPerl method can throw 2 types of exceptions: InlineJavaException and
+InlineJavaPerlException (both of these belong to the org.perl.inline.java
+package). The former designates an internal C<Inline::Java> errorand the
+latter indicates that the Perl callback threw an exception (die() or croak()).
+The value of $@ (this can be a scalar or any valid "Inline::Java" object) can
+be retreived using the GetObject method of the InlineJavaPerlException object
+(if you are certain that $@ was a Perl scalar, you can use the GetString
+method).
+ Z<>
+
+
+=head1 CALLBACK LOOPS
+
+As of 0.44, it is now possible to use callbacks from differents Java threads.
+One of the big advantages of this is that you can now handle, for example,
+SWING events in Perl. Here's an example:
+
+=for comment
+
+ use Inline Java => <<'END' ;
+ import java.util.* ;
+ import org.perl.inline.java.* ;
+ import javax.swing.* ;
+ import java.awt.event.* ;
+
+ class Pod_Button extends InlineJavaPerlCaller
+ implements ActionListener {
+ public Pod_Button() 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){
+ try {
+ CallPerl("main", "button_pressed", new Object [] {}) ;
+ }
+ catch (InlineJavaPerlException pe){
+ // $@ is in pe.GetObject()
+ }
+ catch (InlineJavaException pe) {
+ pe.printStackTrace() ;
+ }
+ }
+ }
+ END
+
+ my $b = new Pod_Button() ;
+ $b->StartCallbackLoop() ;
+
+ sub button_pressed {
+ print("click!\n") ; # prints click!
+ $b->StopCallbackLoop() ;
+ }
+
+=for comment
+
+The StartCallbackLoop method can be called on any InlineJavaPerlCaller object
+and will block the current thread and allow the reception of callbacks through
+any InlineJavaPerlCaller that has been created by the same (current) thread.
+The only way to interrupt such a StartCallbackLoop method is to call the
+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 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
+ Z<>
+
+
+=head1 STUDYING
+
+As of version 0.21, C<Inline::Java> can learn about other Java classes
+and use them just like the Java code you write inside your Perl script.
+In fact you are not even required to write Java code inside your Perl
+script anymore. Here's how to use the 'studying' function:
+
+=for comment
+
+ use Inline (
+ Java => 'STUDY',
+ STUDY => ['java.util.HashMap'],
+ ) ;
+
+ my $hm = new java::util::HashMap() ;
+ $hm->put("key", "value") ;
+ my $val = $hm->get("key") ;
+ print($val . "\n") ; # prints value
+
+=for comment
+
+If you do not wish to put any Java code inside you Perl script, you must
+use the string 'STUDY' as your code. This will skip the build section.
+
+You can also use the AUTOSTUDY option to tell C<Inline::Java> that you wish
+to study all classes that it comes across:
+
+=for comment
+
+ use Inline Java => <<'END', AUTOSTUDY => 1 ;
+ import java.util.* ;
+
+ class Pod_10 {
+ public Pod_10(){
+ }
+
+ public HashMap get_hm(){
+ HashMap hm = new HashMap() ;
+ return hm ;
+ }
+ }
+ END
+
+ my $obj = new Pod_10() ;
+ my $hm = $obj->get_hm() ;
+ $hm->put("key", "value") ;
+ my $val = $hm->get("key") ;
+ print($val . "\n") ; # prints value
+
+=for comment
+
+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<>
+
+
+=head1 JNI vs CLIENT/SERVER MODES
+
+Starting in version 0.20, it is possible to use the JNI (Java Native
+Interface) extension. This enables C<Inline::Java> to load the Java virtual
+machine as a shared object instead of running it as a stand-alone server.
+This brings an improvement in performance.
+
+If you have built the JNI extension, you must enable it explicitely by doing
+one of the following:
+
+ - set the JNI configuration option to 1
+ - set the PERL_INLINE_JAVA_JNI environment variable to 1
+
+Note: C<Inline::Java> only creates one virtual machine instance. Therefore
+you can't use JNI for some sections and client/server for others. The first
+section determines the execution mode.
+
+See README.JNI for more information about the JNI extension.
+ Z<>
+
+
+=head1 SHARED_JVM
+
+Starting with version 0.30, the C<Inline::Java> JVM can now be shared between
+multiple processes. The first process to start creates the JVM but does not
+shut it down on exit. All other processes can then connect as needed to the JVM.
+If any of these other processes where created by forking the parent process,
+the Inline::Java->reconnect_JVM() function must be called in the child to get
+a fresh connection to the JVM. Ex:
+
+=for comment
+
+ use Inline (
+ Java => <<'END',
+ class Pod_11 {
+ public static int i = 0 ;
+ public Pod_11(){
+ i++ ;
+ }
+ }
+ END
+ SHARED_JVM => 1,
+ ) ;
+
+ my $nb = 5 ;
+ for (my $i = 0 ; $i < $nb ; $i++){
+ if (! fork()){
+ Inline::Java::reconnect_JVM() ;
+ my $f = new Pod_11() ;
+ exit ;
+ }
+ }
+ sleep(5) ;
+
+ my $f = new Pod_11() ;
+ print($f->{i} . "\n") ; # prints 6
+
+=for comment
+
+Once this code was run, each of the 6 processes will have created a different
+instance of the 't' class. Data can be shared between the processes by using
+static members in the Java code.
+
+Note: The Java System.out stream is closed in SHARED_JVM mode.
+ Z<>
+
+
+=head1 USING Inline::Java IN A CGI
+
+If you want to use C<Inline::Java> in a CGI script, do the following:
+
+=for comment
+
+ use CGI ;
+ use Inline (
+ Java => <<'END',
+ class Pod_counter {
+ public static int cnt = 0 ;
+ public Pod_counter(){
+ cnt++ ;
+ }
+ }
+ END
+ SHARED_JVM => 1,
+ DIRECTORY => '/somewhere/your/web/server/can/write',
+ ) ;
+
+ my $c = new Pod_counter() ;
+ my $q = new CGI() ;
+ print
+ $q->start_html() .
+ "This page has been accessed " . $c->{cnt} . " times." .
+ $q->end_html() ;
+
+=for comment
+
+In this scenario, the first CGI to execute will start the JVM, but does
+not shut it down on exit. Subsequent CGI, since they have the SHARED_JVM
+option enabled, will try to connect to the already existing JVM before
+trying to start a new one. Therefore if the JVM happens to crash or is
+killed, the next CGI that runs will start a new one. The JVM will be
+killed when Apache is shut down.
+ Z<>
+
+
+=head1 USING Inline::Java UNDER MOD_PERL
+
+Here is an example of how to use C<Inline::Java> under mod_perl:
+
+ use Apache::Constants ;
+ use Inline (
+ Java => <<'END',
+ class Pod_counter {
+ public static int cnt = 0 ;
+ public Pod_counter(){
+ cnt++ ;
+ }
+ }
+ END
+ SHARED_JVM => 1,
+ DIRECTORY => '/somewhere/your/web/server/can/write',
+ ) ;
+
+ my $c = new Pod_counter() ;
+
+ sub handler {
+ my $r = shift ;
+
+ my $q = new CGI ;
+ print
+ $q->start_html() .
+ "This page has been accessed " . $c->{cnt} . " times." .
+ $q->end_html() ;
+
+ return Apache::Constants::OK() ;
+ }
+
+See USING Inline::Java IN A CGI for more details.
+ Z<>
+
+
+=head1 SEE ALSO
+
+L<Inline::Java>, L<Inline::Java::PerlInterpreter>.
+ Z<>
+
+
+=head1 BUGS AND DEFICIENCIES
+
+When reporting a bug, please do the following:
+
+ - Put "use Inline REPORTBUG;" at the top of your code, or
+ use the command line option "perl -MInline=REPORTBUG ...".
+ - Run your code.
+ - Follow the printed instructions.
+
+Here are some things to watch out for:
+
+=over 4
+
+=item 1
+
+You shouldn't name any of your classes 'B', 'S', 'I', 'J', 'F', 'D',
+'C', 'Z' or 'L'. These classes seem to be used internally by Java to
+represent the primitive types.
+
+=item 2
+
+If you upgrade C<Inline::Java> from a previous version, be sure to delete
+your _Inline directory so that C<Inline::Java>'s own Java classes get
+rebuilt to match the Perl code.
+
+=back
+
+=head1 AUTHOR
+
+Patrick LeBoutillier <patl at cpan.org> is the author of Inline::Java.
+
+Brian Ingerson <ingy at cpan.org> is the author of Inline.
+ Z<>
+
+
+=head1 COPYRIGHT
+
+Copyright (c) 2001-2004, Patrick LeBoutillier.
+
+All Rights Reserved. This module is free software. It may be used,
+redistributed and/or modified under the terms of the Perl Artistic
+License. See http://www.perl.com/perl/misc/Artistic.html for more
+details.
+
+=cut
diff --git a/Java/PerlInterpreter/PerlInterpreter.pod b/Java/PerlInterpreter/PerlInterpreter.pod
new file mode 100644
index 0000000..85d4731
--- /dev/null
+++ b/Java/PerlInterpreter/PerlInterpreter.pod
@@ -0,0 +1,132 @@
+=head1 NAME
+
+Inline::Java::PerlInterpreter - How to call Perl from Java using Inline::Java.
+
+=head1 SYNOPSIS
+
+=for comment
+
+ import org.perl.inline.java.* ;
+
+ class HelpMePerl {
+ InlineJavaPerlInterpreter pi = null ;
+
+ public HelpMePerl() throws InlineJavaException {
+ }
+
+ private boolean matches(String target, String pattern){
+ Boolean b = (Boolean)pi.eval("'" + target + "' =~ /" + pattern + "/", Boolean.class) ;
+ return b.booleanValue() ;
+ }
+
+ public static void main(String args[])
+ throws InlineJavaPerlException, InlineJavaException {
+ pi = InlineJavaPerlInterpreter.getInstance() ;
+
+ String target = "aaabbbccc" ;
+ String pattern = "ab+" ;
+ boolean ret = matches(target, pattern) ;
+
+ System.out.println(
+ target + (ret ? " matches " : " doesn't match ") + pattern) ;
+ }
+ }
+
+=for comment
+
+
+=head1 DESCRIPTION
+
+The C<org.perl.inline.java.InlineJavaPerlInterpreter> Java class allows
+you to call or evaluate Perl code from a Java program. It is implemented
+using C<Inline::Java> JNI callbacks. No preprocessing of the Java source
+code is required.
+
+
+=head1 USING THE org.perl.inline.java.InlineJavaPerlInterpreter CLASS
+
+B<Installation>
+
+Before using C<org.perl.inline.java.InlineJavaPerlInterpreter>, you must
+have installed C<Inline::Java> as well as the JNI extension. Additionally,
+the PerlInterpreter extension must also have been installed.
+
+B<>
+
+This section will explain the different ways to C<use> Inline::Java.
+For more details on C<Inline>, see 'perldoc Inline'.
+
+B<Basic Usage>
+
+The most basic form for using C<Inline::Java> is:
+
+ use Inline Java => 'Java source code' ;
+
+Of course, you can use Perl's "here document" style of quoting to make
+the code slightly easier to read:
+
+ use Inline Java => <<'END';
+
+ Java source code goes here.
+
+ END
+
+The source code can also be specified as a filename, a subroutine
+reference (sub routine should return source code), or an array
+reference (array contains lines of source code). This information
+is detailed in 'perldoc Inline'.
+
+In order for C<Inline::Java> to function properly, it needs to know
+where to find a Java 2 SDK on your machine. This is done using one
+of the following techniques:
+
+ - set the J2SDK configuration option to the correct directory
+ - set the PERL_INLINE_JAVA_J2SDK environment variable to the
+ correct directory
+
+If none of these are specified, C<Inline::Java> will use the Java
+2 SDK that was specified a install time (see below).
+
+
+=head1 SEE ALSO
+
+L<Inline::Java>, L<Inline::Java::Callbacks>.
+ Z<>
+
+
+=head1 BUGS AND DEFICIENCIES
+
+Here are some things to watch out for:
+
+=over 4
+
+=item 1
+
+You shouldn't name any of your classes 'B', 'S', 'I', 'J', 'F', 'D',
+'C', 'Z' or 'L'. These classes seem to be used internally by Java to
+represent the primitive types.
+
+=item 2
+
+If you upgrade C<Inline::Java> from a previous version, be sure to delete
+your _Inline directory so that C<Inline::Java>'s own Java classes get
+rebuilt to match the Perl code.
+
+=back
+
+=head1 AUTHOR
+
+Patrick LeBoutillier <patl at cpan.org> is the author of Inline::Java.
+ Z<>
+
+
+=head1 COPYRIGHT
+
+Copyright (c) 2001-2004, Patrick LeBoutillier.
+
+All Rights Reserved. This module is free software. It may be used,
+redistributed and/or modified under the terms of the Perl Artistic
+License. See http://www.perl.com/perl/misc/Artistic.html for more
+details.
+
+=cut
diff --git a/Java/PerlNatives/Makefile.PL b/Java/PerlNatives/Makefile.PL
new file mode 100644
index 0000000..bd05903
--- /dev/null
+++ b/Java/PerlNatives/Makefile.PL
@@ -0,0 +1,13 @@
+use ExtUtils::MakeMaker ;
+
+use strict ;
+
+WriteMakefile(
+ NAME => 'Inline::Java::PerlNatives',
+ VERSION_FROM => 'PerlNatives.pm',
+ INC => join(' ', @main::I),
+ LIBS => [join(' ', @main::L) . " -ljvm"],
+ # CCFLAGS => '-D_REENTRANT',
+ clean => {FILES => "_Inline_test"},
+) ;
+
diff --git a/Java/PerlNatives/PerlNatives.pm b/Java/PerlNatives/PerlNatives.pm
new file mode 100644
index 0000000..b246d28
--- /dev/null
+++ b/Java/PerlNatives/PerlNatives.pm
@@ -0,0 +1,7 @@
+package Inline::Java::PerlNatives ;
+
+use strict ;
+
+$Inline::Java::PerlNatives::VERSION = '0.48_01' ;
+
+1 ;
diff --git a/Java/PerlNatives/PerlNatives.pod b/Java/PerlNatives/PerlNatives.pod
new file mode 100644
index 0000000..5aa37d8
--- /dev/null
+++ b/Java/PerlNatives/PerlNatives.pod
@@ -0,0 +1,1074 @@
+=head1 NAME
+
+Inline::Java::Callbacks - Callback into Perl from Java.
+
+=head1 SYNOPSIS
+
+=for comment
+
+ use Inline Java => <<'END_OF_JAVA_CODE' ;
+ 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
+
+ my $alu = new Pod_alu() ;
+ print($alu->add(9, 16) . "\n") ; # prints 25
+ print($alu->subtract(9, 16) . "\n") ; # prints -7
+
+=for comment
+
+
+=head1 DESCRIPTION
+
+The C<Inline::Java> module allows you to put Java source code
+directly "inline" in a Perl script or module. A Java compiler
+is launched and the Java code is compiled. Then Perl asks the
+Java classes what public methods have been defined. These classes
+and methods are available to the Perl program as if they had been
+written in Perl.
+
+The process of interrogating the Java classes for public methods
+occurs the first time you run your Java code. The namespace is
+cached, and subsequent calls use the cached version.
+ Z<>
+
+
+=head1 USING THE Inline::Java MODULE
+
+C<Inline::Java> is driven by fundamentally the same idea as other
+C<Inline> language modules, like C<Inline::C> or C<Inline::CPP>.
+Because Java is both compiled and interpreted, the method of getting
+your code is different, but overall, using C<Inline::Java> is very similar
+to any other C<Inline> language module.
+
+This section will explain the different ways to C<use> Inline::Java.
+For more details on C<Inline>, see 'perldoc Inline'.
+
+B<Basic Usage>
+
+The most basic form for using C<Inline::Java> is:
+
+ use Inline Java => 'Java source code' ;
+
+Of course, you can use Perl's "here document" style of quoting to make
+the code slightly easier to read:
+
+ use Inline Java => <<'END';
+
+ Java source code goes here.
+
+ END
+
+The source code can also be specified as a filename, a subroutine
+reference (sub routine should return source code), or an array
+reference (array contains lines of source code). This information
+is detailed in 'perldoc Inline'.
+
+In order for C<Inline::Java> to function properly, it needs to know
+where to find a Java 2 SDK on your machine. This is done using one
+of the following techniques:
+
+ - set the J2SDK configuration option to the correct directory
+ - set the PERL_INLINE_JAVA_J2SDK environment variable to the
+ correct directory
+
+If none of these are specified, C<Inline::Java> will use the Java
+2 SDK that was specified a install time (see below).
+
+
+=head1 DEFAULT JAVA 2 SDK
+
+When C<Inline::Java> was installed, the path to the Java 2 SDK that was
+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=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.
+If you wish use a different Java 2 SDK temporarily, see the J2SDK
+configuration option described below.
+
+
+=head1 CONFIGURATION OPTIONS
+
+There are a number of configuration options that dictate the
+behavior of C<Inline::Java>:
+
+ J2SDK:
+ Specifies the path to your Java 2 SDK.
+ Ex: J2SDK => '/my/java/2/sdk/path'
+ 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.
+
+ PORT:
+ Specifies the starting port number for the server. If many
+ C<Inline::Java> blocks are declared, the port number is
+ incremented each time.
+ Default is 0 (next available port number).
+ Default for SHARED_JVM mode is 7890.
+ Ex: PORT => 4567
+ 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.
+
+ STARTUP_DELAY:
+ Specifies the maximum number of seconds that the Perl script
+ will try to connect to the Java server. In other this is the
+ delay that Perl gives to the Java server to start.
+ Default is 15 seconds.
+ Ex: STARTUP_DELAY => 20
+ 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.
+
+ 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'
+
+ JNI:
+ Toggles the execution mode. The default is to use the client/server
+ mode. To use the JNI extension (you must have built it at install
+ time though. See README and README.JNI for more information), set
+ JNI to 1.
+ Ex: JNI => 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. Use with caution as some options may
+ alter normal C<Inline::Java> behavior.
+ 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: 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
+ make use of the same JVM.
+
+ SHARED_JVM:
+ This mode enables mutiple processes to share the same JVM. It was
+ created mainly in order to be able to use C<Inline::Java> under
+ mod_perl.
+ Ex: SHARED_JVM => 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.
+
+ PRIVATE:
+ In SHARED_JVM mode, makes every connection to the JVM use a different
+ classloader so that each connection is isolated from the others.
+ Ex: PRIVATE => 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.
+
+ DEBUG:
+ Enables debugging info. Debugging now uses levels (1 through 5)
+ that (loosely) follow these definitions:
+ 1 = Major program steps
+ 2 = Object creation/destruction
+ 3 = Method/member accesses + packet dumps
+ 4 = Everything else
+ 5 = Data structure dumps
+ Ex: DEBUG => 2
+
+ DEBUGGER:
+ Starts jdb, (the Java debugger) instead of the regular Java JVM.
+ This option will also cause the Java code to be compiled using the
+ '-g' switch for extra debugging information. EXTRA_JAVA_ARGS can
+ be used use to pass extra options to the debugger.
+ Ex: DEBUGGER => 1
+
+ WARN_METHOD_SELECT:
+ Throws a warning when C<Inline::Java> has to 'choose' between
+ different method signatures. The warning states the possible
+ choices and the signature chosen.
+ Ex: WARN_METHOD_SELECT => 1
+
+ STUDY:
+ Takes an array of Java classes that you wish to have
+ C<Inline::Java> learn about so that you can use them inside Perl.
+ Ex: STUDY => ['java.lang.HashMap', 'my.class']
+
+ AUTOSTUDY:
+ Makes C<Inline::Java> automatically study unknown classes it
+ encounters them.
+ Ex: AUTOSTUDY => 1
+
+
+=head1 ENVIRONMENT VARIABLES
+
+Every configuration option listed above, with the exception of STUDY,
+can be specified using an environment variable named using the
+following convention:
+
+ PERL_INLINE_JAVA_<option name>
+
+For example, your can specified the JNI option usng the
+PERL_INLINE_JAVA_JNI environment variable.
+
+Note that environment variables take precedence over options specified
+in the script itself.
+
+Under Win32, you can also use set the PERL_INLINE_JAVA_COMMAND_COM
+environment variable to a true value to indicate that you are using
+the command.com shell. However, C<Inline::Java> should normally be
+able to determine this on its own.
+
+
+=head1 CLASSES AND OBJECTS
+
+Because Java is object oriented, any interface between Perl and Java
+needs to support Java classes adequately.
+
+Example:
+
+=for comment
+
+ use Inline Java => <<'END' ;
+ class Pod_1 {
+ String data = "data" ;
+ static String sdata = "static data" ;
+
+ public Pod_1(){
+ }
+
+ public String get_data(){
+ return data ;
+ }
+
+ public static String get_static_data(){
+ return sdata ;
+ }
+
+ public void set_data(String d){
+ data = d ;
+ }
+
+ private void priv(){
+ }
+ }
+ END
+
+ my $obj = new Pod_1 ;
+ print($obj->get_data() . "\n") ; # prints data
+ $obj->set_data("new data") ;
+ print($obj->get_data() . "\n") ; # prints new data
+
+=for comment
+
+C<Inline::Java> created a new namespace called C<main::Pod_1> and
+created the following functions:
+
+ sub main::Pod_::new { ... }
+ sub main::Pod_::Pod_1 { ... }
+ sub main::Pod_::get_data { ... }
+ sub main::Pod_::get_sdata { ... }
+ sub main::Pod_::set_data { ... }
+ sub main::Pod_::DESTROY { ... }
+
+Note that only the public methods are exported to Perl.
+
+Inner classes are also supported, you simply need to supply a reference
+to an outer class object as the first parameter of the constructor:
+
+=for comment
+
+ use Inline Java => <<'END' ;
+ class Pod_2 {
+ public Pod_2(){
+ }
+
+ public class Pod_2_Inner {
+ public String name = "Pod_2_Inner" ;
+
+ public Pod_2_Inner(){
+ }
+ }
+ }
+ END
+
+ my $obj = new Pod_2() ;
+ my $obj2 = new Pod_2::Pod_2_Inner($obj) ;
+ print($obj2->{name} . "\n") ; # prints Pod_2_Inner
+
+=for comment
+
+=head1 METHODS
+
+In the previous example we have seen how to call a method. You can also
+call static methods in the following manner:
+
+ print Pod_1->get_sdata() . "\n" ; # prints static data
+ # or
+ my $obj = new Pod_1() ;
+ print $obj->get_sdata() . "\n" ; # prints static data
+
+You can pass any kind of Perl scalar or any Java object to a method. It
+will be automatically converted to the correct type:
+
+=for comment
+
+ use Inline Java => <<'END' ;
+ class Pod_3_arg {
+ public Pod_3_arg(){
+ }
+ }
+ class Pod_3 {
+ public int n ;
+
+ public Pod_3(int i, String j, Pod_3_arg k) {
+ n = i ;
+ }
+ }
+ END
+
+ my $obj = new Pod_3_arg() ;
+ my $obj2 = new Pod_3(5, "toto", $obj) ;
+ print($obj2->{n} . "\n") ; # prints 5
+
+=for comment
+
+will work fine. These objects can be of any type, even if these types
+are not known to C<Inline::Java>. This is also true for return types:
+
+=for comment
+
+ use Inline Java => <<'END' ;
+ import java.util.* ;
+
+ class Pod_4 {
+ public Pod_4(){
+ }
+
+ public HashMap get_hash(){
+ HashMap h = new HashMap() ;
+ h.put("key", "value") ;
+
+ return h ;
+ }
+
+ public String do_stuff_to_hash(HashMap h){
+ return (String)h.get("key") ;
+ }
+ }
+ END
+
+ my $obj = new Pod_4() ;
+ my $h = $obj->get_hash() ;
+ print($obj->do_stuff_to_hash($h) . "\n") ; # prints value
+
+=for comment
+
+Objects of types unknown to Perl can exist in the Perl space, you just
+can't call any of their methods. See the STUDYING section for more
+information on how to tell C<Inline::Java> to learn about these classes.
+ Z<>
+
+
+=head1 MEMBER VARIABLES
+
+You can also access all public member variables (static or not) from Perl.
+As with method arguments, the types of these variables does not need to
+be known to Perl:
+
+=for comment
+
+ use Inline Java => <<'END' ;
+ import java.util.* ;
+
+ class Pod_5 {
+ public int i ;
+ public static HashMap hm ;
+
+ public Pod_5(){
+ }
+ }
+ END
+
+ my $obj = new Pod_5() ;
+ $obj->{i} = 2 ;
+ print($obj->{i} . "\n") ; # prints 2
+ my $hm1 = $obj->{hm} ; # instance way
+ my $hm2 = $Pod_4::hm ; # static way
+
+=for comment
+
+Note: Watch out for typos when accessing members in the static fashion,
+'use strict' will not catch them since they have a package name...
+ Z<>
+
+
+=head1 ARRAYS
+
+You can also send, receive and modify arrays. This is done simply by
+using Perl lists:
+
+=for comment
+
+ use Inline Java => <<'END' ;
+ import java.util.* ;
+
+ class Pod_6 {
+ public int i[] = {5, 6, 7} ;
+
+ public Pod_6(){
+ }
+
+ public String [] f(String a[]){
+ return a ;
+ }
+
+ public String [][] f(String a[][]){
+ return a ;
+ }
+ }
+ END
+
+ my $obj = new Pod_6() ;
+ my $i_2 = $obj->{i}->[2] ; # 7
+ print($i_2 . "\n") ; # prints 7
+
+ my $a1 = $obj->f(["a", "b", "c"]) ; # String []
+ my $a2 = $obj->f([
+ ["00", "01"],
+ ["10", "11"],
+ ]) ; # String [][]
+ print($a2->[1]->[0] . "\n") ; # prints 10
+
+=for comment
+
+=head1 TYPE CASTING
+
+Sometimes when a class as many signatures for the same method,
+C<Inline::Java> will have to select one of the signatures based on
+the arguments that are passed:
+
+=for comment
+
+ use Inline Java => <<'END' ;
+ class Pod_7 {
+ public Pod_7(){
+ }
+
+ public String f(int i){
+ return "int" ;
+ }
+
+ public String f(char c){
+ return "char" ;
+ }
+ }
+ END
+
+ my $obj = new Pod_7() ;
+ print($obj->f('5') . "\n") ; # prints int
+
+=for comment
+
+In this case, C<Inline::Java> will call f(int i), because '5' is an integer.
+But '5' is a valid char as well. So to force the call of f(char c), do the
+following:
+
+ use Inline::Java qw(cast) ;
+ $obj->f(cast('char', '5')) ;
+ # or
+ $obj->f(Inline::Java::cast('char', '5')) ;
+
+The cast function forces the selection of the matching signature. Note that
+the cast must match the argument type exactly. Casting to a class that
+extends the argument type will not work.
+
+Another case where type casting is need is when one wants to pass an array
+as a java.lang.Object:
+
+ use Inline Java => <<'END';
+ class Pod_8 {
+ public Object o ;
+ int a[] = {1, 2, 3} ;
+
+ public Pod_8() {
+ }
+ }
+ END
+
+ my $obj = new Pod_8() ;
+ $obj->{o} = [1, 2, 3] ; # No!
+
+The reason why this will not work is simple. When C<Inline::Java> sees an
+array, it checks the Java type you are trying to match it against to validate
+the construction of your Perl list. But in this case, it can't validate
+the array because you're assigning it to an Object. You must use the 3
+parameter version of the cast function to do this:
+
+ $obj->{o} = Inline::Java::cast(
+ "java.lang.Object",
+ [1, 2, 3],
+ "[Ljava.lang.String;") ;
+
+This tells C<Inline::Java> to validate your Perl list as a String [], and
+then cast it as an Object.
+
+Here is how to construct the array type representations:
+
+ [<type> -> 1 dimensional <type> array
+ [[<type> -> 2 dimensional <type> array
+ ...
+
+ where <type> is one of:
+ B byte S short I int J long
+ F float D double C char Z boolean
+
+ L<class>; array of <class> objects
+
+This is described in more detail in most Java books that talk about
+reflection.
+
+But you only need to do this if you have a Perl list. If you already have a
+Java array reference obtained from elsewhere, you don't even need to cast:
+
+ $obj->{o} = $obj->{a} ;
+
+
+=head1 EXCEPTIONS
+
+You can now (as of 0.31) catch exceptions as objects when they are thrown
+from Java. To do this you use the regular Perl exception tools: eval and
+$@. A helper function named 'caught' is provided to help determine the
+type of the exception. Here is a example of a typical use:
+
+=for comment
+
+ use Inline Java => <<'END' ;
+ import java.util.* ;
+
+ class Pod_9 {
+ public Pod_9(boolean t) throws Exception {
+ if (t){
+ throw new Exception("ouch!") ;
+ }
+ }
+ }
+ END
+
+ use Inline::Java qw(caught) ;
+
+ eval {
+ my $obj = new Pod_9(1) ;
+ } ;
+ if ($@){
+ if (caught("java.lang.Exception")){
+ my $msg = $@->getMessage() ;
+ print($msg . "\n") ; # prints ouch!
+ }
+ else{
+ # It wasn't a Java exception after all...
+ die $@ ;
+ }
+ }
+
+=for comment
+
+What's important to understand is that $@ actually contains a reference
+to the Throwable object that was thrown by Java. The getMessage() function
+is really a method of the java.lang.Exception class. So if Java is throwing
+a custom exception you have in your code, you will have access to that
+exception object's public methods just like any other Java object in
+C<Inline::Java>. It is also probably a good idea to undef $@ once you have
+treated a Java exception, or else the object still has a reference until
+$@ is reset by the next eval.
+ Z<>
+
+
+=head1 CALLBACKS
+
+You can now (as of 0.31), call Perl functions from Java. To do this you
+need to create an org.perl.inline.java.InlinePerlJavaCaller object. You
+can then use the CallPerl method to call your Perl function. You pass the
+parameters using an array of Objects. The method will return the result in
+an Object, which you must then cast as a String (if your Perl method
+returns a Perl scalar), or anything else if your Perl function returns
+an "Inline::Java" object. Here is a example of a typical use:
+
+=for comment
+
+ use Inline Java => <<'END' ;
+ import java.util.* ;
+ import org.perl.inline.java.* ;
+
+ class Pod_regexp extends InlineJavaPerlCaller {
+ public Pod_regexp() throws InlineJavaException {
+ }
+
+ public boolean match(String target, String pattern)
+ throws InlineJavaException {
+ try {
+ String m = (String)CallPerl("main", "regexp",
+ new Object [] {target, pattern}) ;
+
+ if (m.equals("1")){
+ return true ;
+ }
+ }
+ catch (InlineJavaPerlException pe){
+ // $@ is in pe.GetObject()
+ }
+
+ return false ;
+ }
+ }
+ END
+
+ my $re = new Pod_regexp() ;
+ my $match = $re->match("Inline::Java", "^Inline") ;
+ print($match . "\n") ; # prints 1
+
+ sub regexp {
+ my $target = shift ;
+ my $pattern = shift ;
+
+ return ($target =~ /$pattern/) ;
+ }
+
+=for comment
+
+The CallPerl method can throw 2 types of exceptions: InlineJavaException and
+InlineJavaPerlException (both of these belong to the org.perl.inline.java
+package). The former designates an internal C<Inline::Java> errorand the
+latter indicates that the Perl callback threw an exception (die() or croak()).
+The value of $@ (this can be a scalar or any valid "Inline::Java" object) can
+be retreived using the GetObject method of the InlineJavaPerlException object
+(if you are certain that $@ was a Perl scalar, you can use the GetString
+method).
+ Z<>
+
+
+=head1 CALLBACK LOOPS
+
+As of 0.44, it is now possible to use callbacks from differents Java threads.
+One of the big advantages of this is that you can now handle, for example,
+SWING events in Perl. Here's an example:
+
+=for comment
+
+ use Inline Java => <<'END' ;
+ import java.util.* ;
+ import org.perl.inline.java.* ;
+ import javax.swing.* ;
+ import java.awt.event.* ;
+
+ class Pod_Button extends InlineJavaPerlCaller
+ implements ActionListener {
+ public Pod_Button() 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){
+ try {
+ CallPerl("main", "button_pressed", new Object [] {}) ;
+ }
+ catch (InlineJavaPerlException pe){
+ // $@ is in pe.GetObject()
+ }
+ catch (InlineJavaException pe) {
+ pe.printStackTrace() ;
+ }
+ }
+ }
+ END
+
+ my $b = new Pod_Button() ;
+ $b->StartCallbackLoop() ;
+
+ sub button_pressed {
+ print("click!\n") ; # prints click!
+ $b->StopCallbackLoop() ;
+ }
+
+=for comment
+
+The StartCallbackLoop method can be called on any InlineJavaPerlCaller object
+and will block the current thread and allow the reception of callbacks through
+any InlineJavaPerlCaller that has been created by the same (current) thread.
+The only way to interrupt such a StartCallbackLoop method is to call the
+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 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
+ Z<>
+
+
+=head1 STUDYING
+
+As of version 0.21, C<Inline::Java> can learn about other Java classes
+and use them just like the Java code you write inside your Perl script.
+In fact you are not even required to write Java code inside your Perl
+script anymore. Here's how to use the 'studying' function:
+
+=for comment
+
+ use Inline (
+ Java => 'STUDY',
+ STUDY => ['java.util.HashMap'],
+ ) ;
+
+ my $hm = new java::util::HashMap() ;
+ $hm->put("key", "value") ;
+ my $val = $hm->get("key") ;
+ print($val . "\n") ; # prints value
+
+=for comment
+
+If you do not wish to put any Java code inside you Perl script, you must
+use the string 'STUDY' as your code. This will skip the build section.
+
+You can also use the AUTOSTUDY option to tell C<Inline::Java> that you wish
+to study all classes that it comes across:
+
+=for comment
+
+ use Inline Java => <<'END', AUTOSTUDY => 1 ;
+ import java.util.* ;
+
+ class Pod_10 {
+ public Pod_10(){
+ }
+
+ public HashMap get_hm(){
+ HashMap hm = new HashMap() ;
+ return hm ;
+ }
+ }
+ END
+
+ my $obj = new Pod_10() ;
+ my $hm = $obj->get_hm() ;
+ $hm->put("key", "value") ;
+ my $val = $hm->get("key") ;
+ print($val . "\n") ; # prints value
+
+=for comment
+
+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<>
+
+
+=head1 JNI vs CLIENT/SERVER MODES
+
+Starting in version 0.20, it is possible to use the JNI (Java Native
+Interface) extension. This enables C<Inline::Java> to load the Java virtual
+machine as a shared object instead of running it as a stand-alone server.
+This brings an improvement in performance.
+
+If you have built the JNI extension, you must enable it explicitely by doing
+one of the following:
+
+ - set the JNI configuration option to 1
+ - set the PERL_INLINE_JAVA_JNI environment variable to 1
+
+Note: C<Inline::Java> only creates one virtual machine instance. Therefore
+you can't use JNI for some sections and client/server for others. The first
+section determines the execution mode.
+
+See README.JNI for more information about the JNI extension.
+ Z<>
+
+
+=head1 SHARED_JVM
+
+Starting with version 0.30, the C<Inline::Java> JVM can now be shared between
+multiple processes. The first process to start creates the JVM but does not
+shut it down on exit. All other processes can then connect as needed to the JVM.
+If any of these other processes where created by forking the parent process,
+the Inline::Java->reconnect_JVM() function must be called in the child to get
+a fresh connection to the JVM. Ex:
+
+=for comment
+
+ use Inline (
+ Java => <<'END',
+ class Pod_11 {
+ public static int i = 0 ;
+ public Pod_11(){
+ i++ ;
+ }
+ }
+ END
+ SHARED_JVM => 1,
+ ) ;
+
+ my $nb = 5 ;
+ for (my $i = 0 ; $i < $nb ; $i++){
+ if (! fork()){
+ Inline::Java::reconnect_JVM() ;
+ my $f = new Pod_11() ;
+ exit ;
+ }
+ }
+ sleep(5) ;
+
+ my $f = new Pod_11() ;
+ print($f->{i} . "\n") ; # prints 6
+
+=for comment
+
+Once this code was run, each of the 6 processes will have created a different
+instance of the 't' class. Data can be shared between the processes by using
+static members in the Java code.
+
+Note: The Java System.out stream is closed in SHARED_JVM mode.
+ Z<>
+
+
+=head1 USING Inline::Java IN A CGI
+
+If you want to use C<Inline::Java> in a CGI script, do the following:
+
+=for comment
+
+ use CGI ;
+ use Inline (
+ Java => <<'END',
+ class Pod_counter {
+ public static int cnt = 0 ;
+ public Pod_counter(){
+ cnt++ ;
+ }
+ }
+ END
+ SHARED_JVM => 1,
+ DIRECTORY => '/somewhere/your/web/server/can/write',
+ ) ;
+
+ my $c = new Pod_counter() ;
+ my $q = new CGI() ;
+ print
+ $q->start_html() .
+ "This page has been accessed " . $c->{cnt} . " times." .
+ $q->end_html() ;
+
+=for comment
+
+In this scenario, the first CGI to execute will start the JVM, but does
+not shut it down on exit. Subsequent CGI, since they have the SHARED_JVM
+option enabled, will try to connect to the already existing JVM before
+trying to start a new one. Therefore if the JVM happens to crash or is
+killed, the next CGI that runs will start a new one. The JVM will be
+killed when Apache is shut down.
+ Z<>
+
+
+=head1 USING Inline::Java UNDER MOD_PERL
+
+Here is an example of how to use C<Inline::Java> under mod_perl:
+
+ use Apache::Constants ;
+ use Inline (
+ Java => <<'END',
+ class Pod_counter {
+ public static int cnt = 0 ;
+ public Pod_counter(){
+ cnt++ ;
+ }
+ }
+ END
+ SHARED_JVM => 1,
+ DIRECTORY => '/somewhere/your/web/server/can/write',
+ ) ;
+
+ my $c = new Pod_counter() ;
+
+ sub handler {
+ my $r = shift ;
+
+ my $q = new CGI ;
+ print
+ $q->start_html() .
+ "This page has been accessed " . $c->{cnt} . " times." .
+ $q->end_html() ;
+
+ return Apache::Constants::OK() ;
+ }
+
+See USING Inline::Java IN A CGI for more details.
+ Z<>
+
+
+=head1 SEE ALSO
+
+L<Inline::Java>, L<Inline::Java::PerlInterpreter>.
+ Z<>
+
+
+=head1 BUGS AND DEFICIENCIES
+
+When reporting a bug, please do the following:
+
+ - Put "use Inline REPORTBUG;" at the top of your code, or
+ use the command line option "perl -MInline=REPORTBUG ...".
+ - Run your code.
+ - Follow the printed instructions.
+
+Here are some things to watch out for:
+
+=over 4
+
+=item 1
+
+You shouldn't name any of your classes 'B', 'S', 'I', 'J', 'F', 'D',
+'C', 'Z' or 'L'. These classes seem to be used internally by Java to
+represent the primitive types.
+
+=item 2
+
+If you upgrade C<Inline::Java> from a previous version, be sure to delete
+your _Inline directory so that C<Inline::Java>'s own Java classes get
+rebuilt to match the Perl code.
+
+=back
+
+=head1 AUTHOR
+
+Patrick LeBoutillier <patl at cpan.org> is the author of Inline::Java.
+
+Brian Ingerson <ingy at cpan.org> is the author of Inline.
+ Z<>
+
+
+=head1 COPYRIGHT
+
+Copyright (c) 2001-2004, Patrick LeBoutillier.
+
+All Rights Reserved. This module is free software. It may be used,
+redistributed and/or modified under the terms of the Perl Artistic
+License. See http://www.perl.com/perl/misc/Artistic.html for more
+details.
+
+=cut
diff --git a/Java/PerlNatives/PerlNatives.xs b/Java/PerlNatives/PerlNatives.xs
new file mode 100644
index 0000000..81348e0
--- /dev/null
+++ b/Java/PerlNatives/PerlNatives.xs
@@ -0,0 +1,254 @@
+#include "stdlib.h"
+#include "string.h"
+#include "stdio.h"
+#include "stdarg.h"
+
+
+
+/* Include the JNI header file */
+#include "jni.h"
+
+
+void throw_ije(JNIEnv *env, char *msg){
+ jclass ije ;
+
+ ije = (*(env))->FindClass(env, "org/perl/inline/java/InlineJavaException") ;
+ if ((*(env))->ExceptionCheck(env)){
+ (*(env))->ExceptionDescribe(env) ;
+ (*(env))->ExceptionClear(env) ;
+ (*(env))->FatalError(env, "Can't find class InlineJavaException: exiting...") ;
+ }
+ (*(env))->ThrowNew(env, ije, msg) ;
+}
+
+
+/*
+ Here we simply check if an exception is pending an re-throw it
+*/
+int check_exception_from_java(JNIEnv *env){
+ jthrowable exc ;
+ int ret = 0 ;
+
+ exc = (*(env))->ExceptionOccurred(env) ;
+ if (exc != NULL){
+ /* (*(env))->ExceptionDescribe(env) ; */
+ (*(env))->ExceptionClear(env) ;
+ if ((*(env))->Throw(env, exc)){
+ (*(env))->FatalError(env, "Throw of InlineJava*Exception failed: exiting...") ;
+ }
+ ret = 1 ;
+ }
+
+ return ret ;
+}
+
+
+jobject create_primitive_object(JNIEnv *env, char f, char *cls_name, jvalue val){
+ jclass arg_cls ;
+ jmethodID mid ;
+ jobject ret = NULL ;
+ char sign[64] ;
+
+ arg_cls = (*(env))->FindClass(env, cls_name) ;
+ if (check_exception_from_java(env)){
+ return NULL ;
+ }
+ sprintf(sign, "(%c)V", f) ;
+ mid = (*(env))->GetMethodID(env, arg_cls, "<init>", sign) ;
+ if (check_exception_from_java(env)){
+ return NULL ;
+ }
+ ret = (*(env))->NewObjectA(env, arg_cls, mid, &val) ;
+ if (check_exception_from_java(env)){
+ return NULL ;
+ }
+
+ return ret ;
+}
+
+
+jobject extract_va_arg(JNIEnv *env, va_list *list, char f){
+ jobject ret = NULL ;
+ jvalue val ;
+
+ /*
+ A bit of voodoo going on for J and F, but the rest I think is pretty
+ kosher (on a 32 bit machine at least)
+ */
+ switch(f){
+ case 'B':
+ val.b = (jbyte)va_arg(*list, int) ;
+ ret = create_primitive_object(env, f, "java/lang/Byte", val) ;
+ break ;
+ case 'S':
+ val.s = (jshort)va_arg(*list, int) ;
+ ret = create_primitive_object(env, f, "java/lang/Short", val) ;
+ break ;
+ case 'I':
+ 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, double) ;
+ ret = create_primitive_object(env, f, "java/lang/Long", val) ;
+ break ;
+ case 'F':
+ /* Seems float is not properly promoted to double... */
+ 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, double) ;
+ ret = create_primitive_object(env, f, "java/lang/Double", val) ;
+ break ;
+ case 'Z':
+ val.z = (jint)va_arg(*list, int) ;
+ ret = create_primitive_object(env, f, "java/lang/Boolean", val) ;
+ break ;
+ case 'C':
+ val.c = (jchar)va_arg(*list, int) ;
+ ret = create_primitive_object(env, f, "java/lang/Character", val) ;
+ break ;
+ }
+
+ return ret ;
+}
+
+
+/*
+ This is the generic native function that callback java to call the proper
+ perl method.
+*/
+jobject JNICALL generic_perl_native(JNIEnv *env, jobject obj, ...){
+ va_list list ;
+ jclass cls ;
+ jmethodID mid ;
+ jstring jfmt ;
+ char *fmt ;
+ int fmt_len ;
+ jclass obj_cls ;
+ jobjectArray obj_array ;
+ jobject arg ;
+ int i ;
+ jobject ret = NULL ;
+
+ cls = (*(env))->GetObjectClass(env, obj) ;
+ mid = (*(env))->GetMethodID(env, cls, "LookupMethod", "()Ljava/lang/String;") ;
+ if (check_exception_from_java(env)){
+ return NULL ;
+ }
+
+ /* Call obj.LookupMethod to get the format string */
+ jfmt = (*(env))->CallObjectMethod(env, obj, mid) ;
+ if (check_exception_from_java(env)){
+ return NULL ;
+ }
+
+ fmt = (char *)((*(env))->GetStringUTFChars(env, jfmt, NULL)) ;
+ fmt_len = strlen(fmt) ;
+
+ obj_cls = (*(env))->FindClass(env, "java/lang/Object") ;
+ if (check_exception_from_java(env)){
+ return NULL ;
+ }
+
+ obj_array = (*(env))->NewObjectArray(env, fmt_len, obj_cls, NULL) ;
+ if (check_exception_from_java(env)){
+ return NULL ;
+ }
+
+ (*(env))->SetObjectArrayElement(env, obj_array, 0, obj) ;
+ if (check_exception_from_java(env)){
+ return NULL ;
+ }
+ va_start(list, obj) ;
+ for (i = 1 ; i < fmt_len ; i++){
+ if (fmt[i] != 'L'){
+ arg = extract_va_arg(env, &list, fmt[i]) ;
+ if (arg == NULL){
+ return NULL ;
+ }
+ }
+ else{
+ arg = (jobject)va_arg(list, jobject) ;
+ }
+ (*(env))->SetObjectArrayElement(env, obj_array, i, arg) ;
+ if (check_exception_from_java(env)){
+ return NULL ;
+ }
+ }
+ va_end(list) ;
+
+ /* Call obj.InvokePerlMethod and grab the returned object and return it */
+ mid = (*(env))->GetMethodID(env, cls, "InvokePerlMethod", "([Ljava/lang/Object;)Ljava/lang/Object;") ;
+ if (check_exception_from_java(env)){
+ return NULL ;
+ }
+
+ ret = (*(env))->CallObjectMethod(env, obj, mid, obj_array) ;
+ if (check_exception_from_java(env)){
+ return NULL ;
+ }
+
+ return ret ;
+}
+
+
+/*
+ This function is used to register the specified native method and associate it with our magic
+ method that trap and redirects all the Perl native calls.
+*/
+JNIEXPORT void JNICALL Java_org_perl_inline_java_InlineJavaPerlNatives_RegisterMethod(JNIEnv *env, jobject obj, jclass cls, jstring name, jstring signature){
+ JNINativeMethod nm ;
+
+ /* Register the function */
+ nm.name = (char *)((*(env))->GetStringUTFChars(env, name, NULL)) ;
+ nm.signature = (char *)((*(env))->GetStringUTFChars(env, signature, NULL)) ;
+ nm.fnPtr = generic_perl_native ;
+
+ (*(env))->RegisterNatives(env, cls, &nm, 1) ;
+ (*(env))->ReleaseStringUTFChars(env, name, nm.name) ;
+ (*(env))->ReleaseStringUTFChars(env, signature, nm.signature) ;
+ if (check_exception_from_java(env)){
+ return ;
+ }
+}
+
+
+
+/*****************************************************************************/
+
+/*
+XS(boot_Inline__Java__PerlNatives);
+XS(boot_Inline__Java__PerlNatives)
+{
+ dXSARGS;
+
+ XS_VERSION_BOOTCHECK ;
+
+ XSRETURN_YES;
+}
+*/
+
+/*
+ xsubpp doesn't like it when we don't specify a MODULE=... PACKAGE=...
+ line. But doing this results in calling function from libperl and we
+ don't want that or else we will need to load that to. So we simply let
+ xsubpp do it's substitutions and define macros that cancel out the effect.
+ Anyways that code will NEVER be called.
+*/
+
+void noop(){
+}
+
+#define XS(n) void n()
+#define dXSARGS int dummy_dxargs = 0
+#define XS_VERSION_BOOTCHECK noop()
+#define XSRETURN_YES noop()
+
+#define PERL_UNUSED_VAR(var) noop()
+
+MODULE = Inline::Java::PerlNatives PACKAGE = Inline::Java::PerlNatives
+
+PROTOTYPES: DISABLE
+
--
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