[libinline-java-perl] 215/398: First step towards re-factoring.
Jonas Smedegaard
dr at jones.dk
Thu Feb 26 11:43:05 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 3ae432211c1f37588d692325c3fe0e22c01625b9
Author: patrick_leb <>
Date: Sat Mar 15 02:57:04 2003 +0000
First step towards re-factoring.
---
Java.pm | 673 ++++++---------------
Java.pod | 6 +-
Java/Array.pm | 112 +---
Java/Callback.pm | 70 +--
Java/Class.pm | 462 +-------------
Java/Init.pm | 486 ---------------
Java/JNI.pm | 2 +-
Java/JVM.pm | 15 +-
Java/Makefile.PL | 77 +--
Java/Object.pm | 10 +-
Java/Portable.pm | 75 ++-
Java/Protocol.pm | 665 ++------------------
Java/sources/InlineJavaArray.java | 98 +++
Java/sources/InlineJavaCastException.java | 5 +
Java/sources/InlineJavaClass.java | 455 ++++++++++++++
Java/sources/InlineJavaException.java | 5 +
.../InlineJavaInvocationTargetException.java | 13 +
Java/sources/InlineJavaPerlCaller.java | 19 +
Java/sources/InlineJavaPerlException.java | 21 +
.../InlineJavaProtocol.java} | 506 ++--------------
Java/sources/InlineJavaServer.java | 288 +++++++++
Java/sources/InlineJavaServerThread.java | 48 ++
Java/sources/InlineJavaTest.java | 8 +
Java/sources/InlineJavaThrown.java | 11 +
Java/sources/InlineJavaUserClassLoader.java | 20 +
Java/sources/InlineJavaUtils.java | 47 ++
MANIFEST | 1 -
Makefile.PL | 121 +++-
TODO | 4 +
t/01_init.t | 6 +-
t/no_const.class | Bin 231 -> 231 bytes
t/types.class | Bin 489 -> 15 bytes
32 files changed, 1536 insertions(+), 2793 deletions(-)
diff --git a/Java.pm b/Java.pm
index db46841..71fb12b 100644
--- a/Java.pm
+++ b/Java.pm
@@ -7,7 +7,7 @@ package Inline::Java ;
use strict ;
-$Inline::Java::VERSION = '0.34' ;
+$Inline::Java::VERSION = '0.40' ;
# DEBUG is set via the DEBUG config
@@ -24,12 +24,10 @@ require Inline ;
use Carp ;
use Config ;
use File::Copy ;
+use File::Spec ;
use Cwd ;
use Data::Dumper ;
-use IO::Socket ;
-use File::Spec ;
-
use Inline::Java::Portable ;
use Inline::Java::Class ;
use Inline::Java::Object ;
@@ -37,8 +35,9 @@ use Inline::Java::Array ;
use Inline::Java::Protocol ;
use Inline::Java::Callback ;
# Must be last.
-use Inline::Java::Init ;
use Inline::Java::JVM ;
+# Our default J2SK
+require File::Spec->catfile('Java', 'DefaultJ2SDK.pl') ;
# This is set when the script is over.
@@ -53,6 +52,10 @@ my $JVM = undef ;
my $INLINES = {} ;
+# Add the directory where our jar file is to the classpath
+$ENV{CLASSPATH} = Inline::Java::Portable::make_classpath(get_jar()) ;
+
+
# This stuff is to control the termination of the Java Interpreter
sub done {
my $signal = shift ;
@@ -71,9 +74,7 @@ sub done {
}
shutdown_JVM() ;
-
Inline::Java::debug(1, "exiting with $ec") ;
-
CORE::exit($ec) ;
}
@@ -112,131 +113,87 @@ sub register {
sub validate {
my $o = shift ;
- if (! exists($o->{ILSM}->{PORT})){
- $o->{ILSM}->{PORT} = 7890 ;
- }
- if (! exists($o->{ILSM}->{STARTUP_DELAY})){
- $o->{ILSM}->{STARTUP_DELAY} = 15 ;
- }
- if (! exists($o->{ILSM}->{SHARED_JVM})){
- $o->{ILSM}->{SHARED_JVM} = 0 ;
- }
- if (! exists($o->{ILSM}->{DEBUG})){
- $o->{ILSM}->{DEBUG} = 0 ;
- }
- if (! exists($o->{ILSM}->{JNI})){
- $o->{ILSM}->{JNI} = 0 ;
- }
- if (! exists($o->{ILSM}->{EMBEDDED_JNI})){
- $o->{ILSM}->{EMBEDDED_JNI} = 0 ;
- }
- if (! exists($o->{ILSM}->{CLASSPATH})){
- $o->{ILSM}->{CLASSPATH} = '' ;
- }
- if (! exists($o->{ILSM}->{WARN_METHOD_SELECT})){
- $o->{ILSM}->{WARN_METHOD_SELECT} = '' ;
- }
- if (! exists($o->{ILSM}->{AUTOSTUDY})){
- $o->{ILSM}->{AUTOSTUDY} = 0 ;
- }
+ # This might not print since debug is set further down...
+ Inline::Java::debug(1, "Starting validate.") ;
+
+ my $jdk = Inline::Java::get_default_j2sdk() ;
+ my %opts = @_ ;
+ $o->set_option('DEBUG', 0, 'i', 1, \%opts) ;
+ $o->set_option('J2SDK', $jdk, 's', 1, \%opts) ;
+ $o->set_option('CLASSPATH', '', 's', 1, \%opts) ;
- while (@_) {
- my ($key, $value) = (shift, shift) ;
- if ($key eq 'BIN'){
- $o->{ILSM}->{$key} = $value ;
- }
- elsif ($key eq 'CLASSPATH'){
- $o->{ILSM}->{$key} = $value ;
- }
- elsif ($key eq 'WARN_METHOD_SELECT'){
- $o->{ILSM}->{$key} = $value ;
- }
- elsif (
- ($key eq 'PORT')||
- ($key eq 'STARTUP_DELAY')){
+ $o->set_option('PORT', 7890, 'i', 1, \%opts) ;
+ $o->set_option('STARTUP_DELAY', 15, 'i', 1, \%opts) ;
+ $o->set_option('SHARED_JVM', 0, 'b', 1, \%opts) ;
+ $o->set_option('JNI', 0, 'b', 1, \%opts) ;
+ $o->set_option('EMBEDDED_JNI', 0, 'b', 1, \%opts) ;
- if ($value !~ /^\d+$/){
- croak "config '$key' must be an integer" ;
- }
- if (! $value){
- croak "config '$key' can't be zero" ;
- }
- $o->{ILSM}->{$key} = $value ;
- }
- elsif ($key eq 'SHARED_JVM'){
- $o->{ILSM}->{$key} = $value ;
- }
- elsif ($key eq 'DEBUG'){
- $o->{ILSM}->{$key} = $value ;
- $Inline::Java::DEBUG = $value ;
- }
- elsif ($key eq 'JNI'){
- $o->{ILSM}->{$key} = $value ;
- }
- elsif ($key eq 'AUTOSTUDY'){
- $o->{ILSM}->{$key} = $value ;
- }
- elsif ($key eq 'STUDY'){
- $o->{ILSM}->{$key} = $o->check_config_array(
- $key, $value,
- "Java class names") ;
- }
- }
+ $o->set_option('WARN_METHOD_SELECT', 0, 'b', 1, \%opts) ;
+ $o->set_option('STUDY', undef, 'a', 0, \%opts) ;
+ $o->set_option('AUTOSTUDY', 0, 'b', 1, \%opts) ;
- if (defined($ENV{PERL_INLINE_JAVA_DEBUG})){
- $Inline::Java::DEBUG = $ENV{PERL_INLINE_JAVA_DEBUG} ;
+ my @left_overs = keys(%opts) ;
+ if (scalar(@left_overs)){
+ croak "'$left_overs[0]' is not a valid configuration option for Inline::Java" ;
}
- $Inline::Java::DEBUG = int($Inline::Java::DEBUG) ;
- if (defined($ENV{PERL_INLINE_JAVA_JNI})){
- $o->{ILSM}->{JNI} = $ENV{PERL_INLINE_JAVA_JNI} ;
- }
-
- if (defined($ENV{PERL_INLINE_JAVA_EMBEDDED_JNI})){
- $o->{ILSM}->{EMBEDDED_JNI} = $ENV{PERL_INLINE_JAVA_EMBEDDED_JNI} ;
- }
+ # Now for the post processing
+ $Inline::Java::DEBUG = $o->get_java_config('DEBUG') ;
# Embedded JNI turns on regular JNI
- if ($o->{ILSM}->{EMBEDDED_JNI}){
- $o->{ILSM}->{JNI} = $o->{ILSM}->{EMBEDDED_JNI} ;
- }
-
- if (defined($ENV{PERL_INLINE_JAVA_SHARED_JVM})){
- $o->{ILSM}->{SHARED_JVM} = $ENV{PERL_INLINE_JAVA_SHARED_JVM} ;
+ if ($o->get_java_config('EMBEDDED_JNI')){
+ $o->set_java_config('JNI', 1) ;
}
- if (($o->{ILSM}->{JNI})&&($o->{ILSM}->{SHARED_JVM})){
+ if (($o->get_java_config('JNI'))&&($o->get_java_config('SHARED_JVM'))){
croak("You can't use the 'SHARED_JVM' option in 'JNI' mode") ;
}
- $o->set_java_bin() ;
-
- if ($o->{ILSM}->{JNI}){
+ if ($o->get_java_config('JNI')){
require Inline::Java::JNI ;
}
+ my $study = $o->get_java_config('STUDY') ;
+ if ((defined($study))&&(ref($study) ne 'ARRAY')){
+ croak "Configuration option 'STUDY' must be an array of Java class names" ;
+ }
+
Inline::Java::debug(1, "validate done.") ;
}
-sub check_config_array {
+sub set_option {
my $o = shift ;
- my $key = shift ;
- my $value = shift ;
+ my $name = shift ;
+ my $default = shift ;
+ my $type = shift ;
+ my $env_or = shift ;
+ my $opts = shift ;
my $desc = shift ;
- if (ref($value) eq 'ARRAY'){
- foreach my $c (@{$value}){
- if (ref($c)){
- croak "config '$key' must be an array of $desc" ;
- }
+ if (! exists($o->{ILSM}->{$name})){
+ my $val = undef ;
+ if (($env_or)&&(exists($ENV{"PERL_INLINE_JAVA_$name"}))){
+ $val = $ENV{"PERL_INLINE_JAVA_$name"} || '' ;
}
- }
- else{
- croak "config '$key' must be an array of $desc" ;
+ elsif (exists($opts->{$name})){
+ $val = $opts->{$name} || '' ;
+ }
+ else{
+ $val = $default ;
+ }
+
+ if ($type eq 'b'){
+ $val = ($val ? 1 : 0) ;
+ }
+ elsif ($type eq 'i'){
+ $val = int($val) ;
+ }
+
+ $o->set_java_config($name, $val) ;
}
- return $value ;
+ delete $opts->{$name} ;
}
@@ -248,101 +205,30 @@ sub get_java_config {
}
-# In theory we shouldn't need to use this, but it seems
-# it's not all accessible by the API yet.
-sub get_config {
+sub set_java_config {
my $o = shift ;
my $param = shift ;
+ my $value = shift ;
- if (defined($param)){
- return $o->{CONFIG}->{$param} ;
- }
- else{
- return %{$o->{CONFIG}} ;
- }
+ return $o->{ILSM}->{$param} = $value ;
}
-sub get_api {
+# In theory we shouldn't need to use this, but it seems
+# it's not all accessible by the API yet.
+sub get_config {
my $o = shift ;
my $param = shift ;
- return $o->{API}->{$param} ;
+ return $o->{CONFIG}->{$param} ;
}
-sub set_java_bin {
- my $o = shift ;
-
- my $cjb = $o->{ILSM}->{BIN} ;
- my $ejb = $ENV{PERL_INLINE_JAVA_BIN} ;
- if ($cjb){
- return $o->find_java_bin([$cjb]) ;
- }
- elsif ($ejb) {
- $o->{ILSM}->{BIN} = $ejb ;
- return $o->find_java_bin([$ejb]) ;
- }
-
- # Java binaries are assumed to be in $ENV{PATH} ;
- return $o->find_java_bin() ;
-}
-
-
-sub find_java_bin {
- my $o = shift ;
- my $paths = shift ;
-
- my $java = "java" . portable("EXE_EXTENSION") ;
- my $javac = "javac" . portable("EXE_EXTENSION") ;
-
- my $path = $o->find_file_in_path([$java, $javac], $paths) ;
- if (defined($path)){
- $o->{ILSM}->{BIN} = $path ;
- }
- else{
- croak
- "Can't locate your java binaries ('$java' and '$javac'). Please set one of the following to the proper directory:\n" .
- " - The BIN config option;\n" .
- " - The PERL_INLINE_JAVA_BIN environment variable;\n" .
- " - The PATH environment variable.\n" ;
- }
-}
-
-
-sub find_file_in_path {
+sub get_api {
my $o = shift ;
- my $files = shift ;
- my $paths = shift ;
-
- if (! defined($paths)){
- $paths = [File::Spec->path()] ;
- }
-
- Inline::Java::debug_obj($paths) ;
-
- foreach my $p (@{$paths}){
- $p =~ s/^\s+// ;
- $p =~ s/\s+$// ;
- Inline::Java::debug(4, "path element: $p") ;
- if ($p !~ /^\s*$/){
- my $found = 0 ;
- foreach my $file (@{$files}){
- my $f = File::Spec->catfile($p, $file) ;
- Inline::Java::debug(4, " candidate: $f\n") ;
-
- if (-f $f){
- Inline::Java::debug(4, " found file $file in $p") ;
- $found++ ;
- }
- }
- if ($found == scalar(@{$files})){
- return $p ;
- }
- }
- }
+ my $param = shift ;
- return undef ;
+ return $o->{API}->{$param} ;
}
@@ -350,139 +236,85 @@ sub find_file_in_path {
sub build {
my $o = shift ;
- if ($o->{ILSM}->{built}){
+ if ($o->get_java_config('built')){
return ;
}
- my $code = $o->get_api('code') ;
- my $study_only = ($code =~ /^(STUDY|SERVER)$/) ;
-
- $o->write_java($study_only, $code) ;
- $o->compile($study_only) ;
-
- $o->{ILSM}->{built} = 1 ;
-}
-
+ Inline::Java::debug(1, "Starting build.") ;
-# Writes the java code.
-sub write_java {
- my $o = shift ;
- my $study_only = shift ;
- my $code = shift ;
-
- my $build_dir = $o->get_api('build_dir') ;
- my $modfname = $o->get_api('modfname') ;
-
- Inline::Java::Portable::mkpath($o, $build_dir) ;
-
- if (! $study_only){
- my $p = File::Spec->catfile($build_dir, "$modfname.java") ;
- open(Inline::Java::JAVA, ">$p") or
- croak "Can't open $p: $!" ;
- Inline::Java::Init::DumpUserJavaCode(\*Inline::Java::JAVA, $code) ;
- close(Inline::Java::JAVA) ;
+ # Grab and untaint the current directory
+ my $cwd = Cwd::cwd() ;
+ if ($o->get_config('UNTAINT')){
+ ($cwd) = $cwd =~ /(.*)/ ;
}
- my $p = File::Spec->catfile($build_dir, "InlineJavaServer.java") ;
- open(Inline::Java::JAVA, ">$p") or
- croak "Can't open $p: $!" ;
- Inline::Java::Init::DumpServerJavaCode(\*Inline::Java::JAVA) ;
- close(Inline::Java::JAVA) ;
-
- $p = File::Spec->catfile($build_dir, "InlineJavaPerlCaller.java") ;
- open(Inline::Java::JAVA, ">$p") or
- croak "Can't open $p: $!" ;
- Inline::Java::Init::DumpCallbackJavaCode(\*Inline::Java::JAVA) ;
- close(Inline::Java::JAVA) ;
-
- Inline::Java::debug(1, "write_java done.") ;
-}
-
-
-# Run the build process.
-sub compile {
- my $o = shift ;
- my $study_only = shift ;
-
+ # Create the build dir and go there
my $build_dir = $o->get_api('build_dir') ;
- my $modpname = $o->get_api('modpname') ;
- my $modfname = $o->get_api('modfname') ;
- my $suffix = $o->get_api('suffix') ;
- my $install_lib = $o->get_api('install_lib') ;
-
- my $install = File::Spec->catdir($install_lib, "auto", $modpname) ;
+ $o->mkpath($build_dir) ;
+ chdir $build_dir ;
- Inline::Java::Portable::mkpath($o, $install) ;
- $o->set_classpath($install) ;
+ my $code = $o->get_api('code') ;
+ my $study_only = ($code =~ /^(STUDY|SERVER)$/) ;
+ my $source = ($study_only ? '' : $o->get_api('modfname') . ".java") ;
+ my $install_dir = File::Spec->catdir($o->get_api('install_lib'),
+ 'auto', $o->get_api('modpname')) ;
+ $o->mkpath($install_dir) ;
+
+ if ($source){
+ # Dump the source code...
+ open(Inline::Java::JAVA, ">$source") or
+ croak "Can't open $source: $!" ;
+ print Inline::Java::JAVA $code ;
+ close(Inline::Java::JAVA) ;
- my $javac = File::Spec->catfile($o->{ILSM}->{BIN},
+ # ... and compile it.
+ my $javac = File::Spec->catfile($o->get_java_config('J2SDK'), 'bin',
"javac" . portable("EXE_EXTENSION")) ;
+ my $redir = portable("IO_REDIR") ;
- my $predir = portable("IO_REDIR") ;
-
- my $cwd = Cwd::cwd() ;
- if ($o->get_config('UNTAINT')){
- ($cwd) = $cwd =~ /(.*)/ ;
- }
-
- my $source = ($study_only ? '' : "$modfname.java") ;
-
- # When we run the commands, we quote them because in WIN32 you need it if
- # the programs are in directories which contain spaces. Unfortunately, in
- # WIN9x, when you quote a command, it masks it's exit value, and 0 is always
- # returned. Therefore a command failure is not detected.
- # copy_classes will take care of checking whether there are actually files
- # to be copied, and if not will exit the script.
- foreach my $cmd (
- "\"$javac\" InlineJavaServer.java $source > cmd.out $predir",
- ["copy_classes", $o, $install],
- ["touch_file", $o, File::Spec->catfile($install, "$modfname.$suffix")],
- ) {
-
- if ($cmd){
-
- chdir $build_dir ;
- if (ref($cmd)){
- Inline::Java::debug_obj($cmd) ;
- my $func = shift @{$cmd} ;
- my @args = @{$cmd} ;
-
- Inline::Java::debug(3, "$func" . "(" . join(", ", @args) . ")") ;
-
- no strict 'refs' ;
- my $ret = $func->(@args) ;
- if ($ret){
- croak $ret ;
- }
+ my $cmd = "\"$javac\" -d \"$install_dir\" $source > cmd.out $redir" ;
+ if ($o->get_config('UNTAINT')){
+ ($cmd) = $cmd =~ /(.*)/ ;
+ }
+ Inline::Java::debug(2, "$cmd") ;
+ my $res = system($cmd) ;
+ $res and do {
+ croak $o->compile_error_msg($cmd) ;
+ } ;
+
+ # When we run the commands, we quote them because in WIN32 you need it if
+ # the programs are in directories which contain spaces. Unfortunately, in
+ # WIN9x, when you quote a command, it masks it's exit value, and 0 is always
+ # returned. Therefore a command failure is not detected.
+ # We need to take care of checking whether there are actually files
+ # to be copied, and if not will exit the script.
+ if (portable('COMMAND_COM')){
+ my @flist= Inline::Java::Portable::find_classes_in_dir($install_dir) ;
+ if (! scalar(@flist)){
+ croak "No class files produced. Previous command failed under command.com?" ;
}
- else{
- if ($o->get_config('UNTAINT')){
- ($cmd) = $cmd =~ /(.*)/ ;
+ foreach my $file (@flist){
+ if (! (-s $file)){
+ croak "File $file has size zero. Previous command failed under command.com?" ;
}
-
- Inline::Java::debug(3, "$cmd") ;
- my $res = system($cmd) ;
- $res and do {
- croak $o->compile_error_msg($cmd, $cwd) ;
- } ;
}
-
- chdir $cwd ;
}
}
+ # Go back and clean up
+ chdir $cwd ;
if ($o->get_api('cleanup')){
- Inline::Java::Portable::rmpath($o, '', $build_dir) ;
+ $o->rmpath('', $build_dir) ;
}
- Inline::Java::debug(1, "compile done.") ;
+ $o->set_java_config('built', 1) ;
+ Inline::Java::debug(1, "build done.") ;
}
sub compile_error_msg {
my $o = shift ;
my $cmd = shift ;
- my $cwd = shift ;
my $build_dir = $o->get_api('build_dir') ;
my $error = '' ;
@@ -511,78 +343,29 @@ MSG
}
-sub copy_classes {
- my $o = shift ;
- my $install = shift ;
-
- my $build_dir = $o->get_api('build_dir') ;
- my $modpname = $o->get_api('modpname') ;
- my $install_lib = $o->get_api('install_lib') ;
-
- my $src_dir = $build_dir ;
- my $dest_dir = $install ;
-
- my @flist = Inline::Java::Portable::find_classes_in_dir(".") ;
- if (portable('COMMAND_COM')){
- if (! scalar(@flist)){
- croak "No files to copy. Previous command failed under command.com?" ;
- }
- foreach my $file (@flist){
- if (! (-s $file)){
- croak "File $file has size zero. Previous command failed under command.com?" ;
- }
- }
- }
-
- foreach my $file (@flist){
- if ($o->get_config('UNTAINT')){
- ($file) = $file =~ /(.*)/ ;
- }
- my $f = File::Spec->catfile($src_dir, $file) ;
- my $t = File::Spec->catfile($dest_dir, $file) ;
- Inline::Java::debug(4, "copy_classes: $file, $t") ;
- if (! File::Copy::copy($file, $t)){
- return "Can't copy $f to $t: $!" ;
- }
- }
-
- return '' ;
-}
-
-
-sub touch_file {
- my $o = shift ;
- my $file = shift ;
-
- if (! open(Inline::Java::TOUCH, ">$file")){
- croak "Can't create file $file" ;
- }
- close(Inline::Java::TOUCH) ;
-
- return '' ;
-}
-
-
# Load and Run the Java Code.
sub load {
my $o = shift ;
- if ($o->{ILSM}->{loaded}){
+ if ($o->get_java_config('loaded')){
return ;
}
- my $install_lib = $o->get_api('install_lib') ;
- my $modfname = $o->get_api('modfname') ;
- my $modpname = $o->get_api('modpname') ;
- my $install = File::Spec->catdir($install_lib, "auto", $modpname) ;
+ Inline::Java::debug(1, "Starting load.") ;
- # Make sure the default options are set.
- # $o->_validate(1, $o->get_config()) ;
+ my $modfname = $o->get_api('modfname') ;
+ my $install_dir = File::Spec->catdir($o->get_api('install_lib'),
+ 'auto', $o->get_api('modpname')) ;
# If the JVM is not running, we need to start it here.
+ my $cp = $ENV{CLASSPATH} ;
+ my @cp = make_classpath() ;
if (! $JVM){
- $o->set_classpath($install) ;
+ $ENV{CLASSPATH} = '' ;
+ $ENV{CLASSPATH} = make_classpath(get_jar()) ;
$JVM = new Inline::Java::JVM($o) ;
+
+ # Add classpath entries + install to the JVM
my $pc = new Inline::Java::Protocol(undef, $o) ;
my $st = $pc->ServerType() ;
@@ -591,6 +374,9 @@ sub load {
croak "JVM type mismatch on port " . $o->get_java_config('PORT') ;
}
}
+ else{
+ # Add $install entry to the JVM.
+ }
# Add our Inline object to the list.
my $prev_o = $INLINES->{$modfname} ;
@@ -604,83 +390,17 @@ sub load {
$INLINES->{$modfname} = $o ;
- $o->_study() ;
- if ((defined($o->{ILSM}->{STUDY}))&&(scalar($o->{ILSM}->{STUDY}))){
- $o->_study($o->{ILSM}->{STUDY}) ;
- }
-
- $o->{ILSM}->{loaded} = 1 ;
-}
-
-
-# This function builds the CLASSPATH environment variable for the JVM
-sub set_classpath {
- my $o = shift ;
- my $path = shift ;
-
- my @list = () ;
- if (defined($ENV{CLASSPATH})){
- push @list, $ENV{CLASSPATH} ;
- }
- if (defined($o->{ILSM}->{CLASSPATH})){
- push @list, $o->{ILSM}->{CLASSPATH} ;
+ my $classes = [] ;
+ if ((defined($o->get_java_config('STUDY')))&&(scalar($o->get_java_config('STUDY')))){
+ $classes = $o->_study($o->get_java_config('STUDY')) ;
}
- if (defined($path)){
- push @list, portable("SUB_FIX_CLASSPATH", $path) ;
- }
-
- my $sep = portable("ENV_VAR_PATH_SEP_CP") ;
- my $cpall = join($sep, @list) ;
-
-
- $cpall =~ s/\s*\[PERL_INLINE_JAVA\s*=\s*(.*?)\s*\]\s*/{
- my $modules = $1 ;
- Inline::Java::debug(1, "found special CLASSPATH entry: $modules") ;
-
- my @modules = split(m#\s*,\s*#, $modules) ;
- my $dir = File::Spec->catdir($o->get_config('DIRECTORY'), "lib", "auto") ;
-
- my %paths = () ;
- foreach my $m (@modules){
- $m = File::Spec->catdir(split(m#::#, $m)) ;
-
- # Here we must make sure that the directory exists, or
- # else it is removed from the CLASSPATH by Java
- my $path = File::Spec->catdir($dir, $m) ;
- Inline::Java::Portable::mkpath($o, $path) ;
-
- $paths{portable("SUB_FIX_CLASSPATH", $path)} = 1 ;
- }
-
- join($sep, keys %paths) ;
- }/ge ;
+ $o->_study($classes, 1) ;
- my @cp = split(/$sep+/, $cpall) ;
-
- # Add dot to CLASSPATH, required when building
- push @cp, '.' ;
-
- foreach my $p (@cp){
- $p =~ s/^\s+// ;
- $p =~ s/\s+$// ;
- }
-
- my @fcp = () ;
- my %cp = map {$_ => 1} @cp ;
- foreach my $p (@cp){
- if ($cp{$p}){
- push @fcp, $p ;
- delete $cp{$p} ;
- }
- }
-
- $ENV{CLASSPATH} = join($sep, @fcp) ;
-
- Inline::Java::debug(1, "classpath: " . $ENV{CLASSPATH}) ;
+ $o->set_java_config('loaded', 1) ;
+ Inline::Java::debug(1, "load done.") ;
}
-
# This function 'studies' the specified classes and binds them to
# Perl
sub _study {
@@ -692,9 +412,7 @@ sub _study {
my @lines = $o->report($classes) ;
# Now we read up the symbols and bind them to Perl.
- $o->bind_jdat(
- $o->load_jdat(@lines)
- ) ;
+ $o->bind_jdat($o->load_jdat(@lines)) ;
}
@@ -703,27 +421,38 @@ sub _study {
sub report {
my $o = shift ;
my $classes = shift ;
+ my $load = shift || 0 ;
- my $install_lib = $o->get_api('install_lib') ;
- my $modpname = $o->get_api('modpname') ;
- my $modfname = $o->get_api('modfname') ;
- my $suffix = $o->get_api('suffix') ;
- my $install = File::Spec->catdir($install_lib, "auto", $modpname) ;
-
- my $use_cache = 0 ;
- if (! defined($classes)){
- $classes = [] ;
+ my $install_dir = File::Spec->catdir($o->get_api('install_lib'),
+ 'auto', $o->get_api('modpname')) ;
+ my $cache = $o->get_api('modfname') . '.' . $o->get_api('suffix') ;
- $use_cache = 1 ;
+ # If search_dir is valid that means that we are really at module load time,
+ # or else we are just studying a specific class via AUTOSTUDY.
+ if (($load)&&(! $o->get_java_config('built'))){
+ # Since we didn't build the module, this means that
+ # it was up to date. We can therefore use the data
+ # from the cache
+ Inline::Java::debug(1, "using jdat cache") ;
+ my $p = File::Spec->catfile($install_dir, $cache) ;
+ if (open(Inline::Java::CACHE, "<$p")){
+ my $resp = join("", <Inline::Java::CACHE>) ;
+ close(Inline::Java::CACHE) ;
+ return split("\n", $resp) ;
+ }
+ else{
+ croak "Can't open $p for reading: $!" ;
+ }
+ }
- # We need to take the classes that are in the directory...
- my @cl = Inline::Java::Portable::find_classes_in_dir($install) ;
+ # Ok, we really have some classes to study.
+ if ($load){
+ # We need to add the classes that are in the directory or under...
+ my @cl = Inline::Java::Portable::find_classes_in_dir($install_dir) ;
foreach my $class (@cl){
if ($class =~ s/([\w\$]+)\.class$/$1/){
my $f = $1 ;
- if ($f !~ /^InlineJava(Server|Perl)/){
- push @{$classes}, $f ;
- }
+ push @{$classes}, $f ;
}
}
}
@@ -731,49 +460,28 @@ sub report {
my @new_classes = () ;
foreach my $class (@{$classes}){
$class = Inline::Java::Class::ValidateClass($class) ;
-
if (! Inline::Java::known_to_perl($o->get_api('pkg'), $class)){
push @new_classes, $class ;
}
}
-
if (! scalar(@new_classes)){
return () ;
}
- my $resp = undef ;
- if (($use_cache)&&(! $o->{ILSM}->{built})){
- # Since we didn't build the module, this means that
- # it was up to date. We can therefore use the data
- # from the cache
- Inline::Java::debug(1, "using jdat cache") ;
- my $p = File::Spec->catfile($install, "$modfname.$suffix") ;
- my $size = (-s $p) || 0 ;
- if ($size > 0){
- if (open(Inline::Java::CACHE, "<$p")){
- $resp = join("", <Inline::Java::CACHE>) ;
- close(Inline::Java::CACHE) ;
- }
- else{
- croak "Can't open $modfname.$suffix file for reading" ;
- }
- }
- }
-
- if (! defined($resp)){
- my $pc = new Inline::Java::Protocol(undef, $o) ;
- $resp = $pc->Report(join(" ", @new_classes)) ;
- }
+ # Ask for the info on the classes
+ my $pc = new Inline::Java::Protocol(undef, $o) ;
+ my $resp = $pc->Report(join(" ", @new_classes)) ;
- if (($use_cache)&&($o->{ILSM}->{built})){
+ if (($load)&&($o->get_java_config('built'))){
# Update the cache.
Inline::Java::debug(1, "updating jdat cache") ;
- if (open(Inline::Java::CACHE, ">$install/$modfname.$suffix")){
+ my $p = File::Spec->catfile($install_dir, $cache) ;
+ if (open(Inline::Java::CACHE, ">$p")){
print Inline::Java::CACHE $resp ;
close(Inline::Java::CACHE) ;
}
else{
- croak "Can't open $modfname.$suffix file for writing" ;
+ croak "Can't open $p file for writing" ;
}
}
@@ -781,7 +489,6 @@ sub report {
}
-
# Load the jdat code information file.
sub load_jdat {
my $o = shift ;
@@ -1031,12 +738,12 @@ sub get_fields {
sub info {
my $o = shift ;
- if (! (($o->{INLINE}->{object_ready})||($o->{ILSM}->{built}))){
- $o->build ;
+ if (! (($o->{INLINE}->{object_ready})||($o->get_java_config('built')))){
+ $o->build() ;
}
- if (! $o->{ILSM}->{loaded}){
- $o->load ;
+ if (! $o->get_java_config('loaded')){
+ $o->load() ;
}
my $info = '' ;
@@ -1146,6 +853,11 @@ sub get_INLINE_nb {
}
+sub get_INLINE_modules {
+ return keys %{$INLINES} ;
+}
+
+
sub get_DEBUG {
return $Inline::Java::DEBUG ;
}
@@ -1288,7 +1000,4 @@ sub caught {
}
-1 ;
-
-__END__
-
+1 ;
\ No newline at end of file
diff --git a/Java.pod b/Java.pod
index 0b1e7cb..bc26ff0 100644
--- a/Java.pod
+++ b/Java.pod
@@ -176,12 +176,12 @@ behavior of C<Inline::Java>:
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'] ;
+ Ex: STUDY => ['java.lang.HashMap', 'my.class']
AUTOSTUDY:
Makes C<Inline::Java> automatically study unknown classes it
- encounters.
- Ex: STUDY => ['java.lang.HashMap', 'my.class'] ;
+ encounters them.
+ Ex: AUTOSTUDY => 1
=head1 ENVIRONMENT VARIABLES
diff --git a/Java/Array.pm b/Java/Array.pm
index 3df6480..81f3f78 100644
--- a/Java/Array.pm
+++ b/Java/Array.pm
@@ -4,7 +4,7 @@ package Inline::Java::Array ;
use strict ;
-$Inline::Java::Array::VERSION = '0.31' ;
+$Inline::Java::Array::VERSION = '0.40' ;
use Carp ;
@@ -631,112 +631,4 @@ sub MakeElementList {
}
-
-package Inline::Java::Array ;
-
-
-1 ;
-
-
-__DATA__
-
-
-class InlineJavaArray {
- private InlineJavaServer ijs ;
- private InlineJavaClass ijc ;
-
-
- InlineJavaArray(InlineJavaServer _ijs, InlineJavaClass _ijc){
- ijs = _ijs ;
- ijc = _ijc ;
- }
-
-
- Object CreateArray(Class c, StringTokenizer st) throws InlineJavaException {
- StringBuffer sb = new StringBuffer(st.nextToken()) ;
- sb.replace(0, 1, "") ;
- sb.replace(sb.length() - 1, sb.length(), "") ;
-
- StringTokenizer st2 = new StringTokenizer(sb.toString(), ",") ;
- ArrayList al = new ArrayList() ;
- while (st2.hasMoreTokens()){
- al.add(al.size(), st2.nextToken()) ;
- }
-
- int size = al.size() ;
- int dims[] = new int[size] ;
- for (int i = 0 ; i < size ; i++){
- dims[i] = Integer.parseInt((String)al.get(i)) ;
- ijs.debug(4, "array dimension: " + (String)al.get(i)) ;
- }
-
- Object array = null ;
- try {
- array = Array.newInstance(c, dims) ;
-
- ArrayList args = new ArrayList() ;
- while (st.hasMoreTokens()){
- args.add(args.size(), st.nextToken()) ;
- }
-
- // Now we need to fill it. Since we have an arbitrary number
- // of dimensions, we can do this recursively.
-
- PopulateArray(array, c, dims, args) ;
- }
- catch (IllegalArgumentException e){
- throw new InlineJavaException("Arguments to array constructor for class " + c.getName() + " are incompatible: " + e.getMessage()) ;
- }
-
- return array ;
- }
-
-
- void PopulateArray (Object array, Class elem, int dims[], ArrayList args) throws InlineJavaException {
- if (dims.length > 1){
- int nb_args = args.size() ;
- int nb_sub_dims = dims[0] ;
- int nb_args_per_sub_dim = nb_args / nb_sub_dims ;
-
- int sub_dims[] = new int[dims.length - 1] ;
- for (int i = 1 ; i < dims.length ; i++){
- sub_dims[i - 1] = dims[i] ;
- }
-
- for (int i = 0 ; i < nb_sub_dims ; i++){
- // We want the args from i*nb_args_per_sub_dim ->
- ArrayList sub_args = new ArrayList() ;
- for (int j = (i * nb_args_per_sub_dim) ; j < ((i + 1) * nb_args_per_sub_dim) ; j++){
- sub_args.add(sub_args.size(), (String)args.get(j)) ;
- }
- PopulateArray(((Object [])array)[i], elem, sub_dims, sub_args) ;
- }
- }
- else{
- String msg = "In creation of array of " + elem.getName() + ": " ;
- try {
- for (int i = 0 ; i < dims[0] ; i++){
- String arg = (String)args.get(i) ;
-
- Object o = ijc.CastArgument(elem, arg) ;
- Array.set(array, i, o) ;
- if (o != null){
- ijs.debug(4, "setting array element " + String.valueOf(i) + " to " + o.toString()) ;
- }
- else{
- ijs.debug(4, "setting array element " + String.valueOf(i) + " to " + o) ;
- }
- }
- }
- catch (InlineJavaCastException e){
- throw new InlineJavaCastException(msg + e.getMessage()) ;
- }
- catch (InlineJavaException e){
- throw new InlineJavaException(msg + e.getMessage()) ;
- }
- }
- }
-}
-
-
-
+1 ;
\ No newline at end of file
diff --git a/Java/Callback.pm b/Java/Callback.pm
index 97a5f6a..90936b8 100644
--- a/Java/Callback.pm
+++ b/Java/Callback.pm
@@ -3,7 +3,7 @@ package Inline::Java::Callback ;
use strict ;
-$Inline::Java::Callback::VERSION = '0.31' ;
+$Inline::Java::Callback::VERSION = '0.40' ;
use Carp ;
@@ -84,70 +84,4 @@ sub ProcessCallback {
-1 ;
-
-
-__DATA__
-
-/*
- Callback to Perl...
-*/
-public class InlineJavaPerlCaller {
- public InlineJavaPerlCaller(){
- }
-
-
- class InlineJavaException extends Exception {
- private InlineJavaServer.InlineJavaException ije = null ;
-
- InlineJavaException(InlineJavaServer.InlineJavaException e) {
- ije = e ;
- }
-
- public InlineJavaServer.InlineJavaException GetException(){
- return ije ;
- }
- }
-
-
- class PerlException extends Exception {
- private Object obj = null ;
-
- PerlException(Object o) {
- obj = o ;
- }
-
- public Object GetObject(){
- return obj ;
- }
-
- public String GetString(){
- return (String)obj ;
- }
- }
-
-
- public Object CallPerl(String pkg, String method, Object args[]) throws InlineJavaException, PerlException {
- return CallPerl(pkg, method, args, null) ;
- }
-
-
- public Object CallPerl(String pkg, String method, Object args[], String cast) throws InlineJavaException, PerlException {
- if (InlineJavaServer.instance == null){
- System.err.println("Can't use InlineJavaPerlCaller outside of an Inline::Java context") ;
- System.err.flush() ;
- System.exit(1) ;
- }
-
- try {
- return InlineJavaServer.instance.Callback(pkg, method, args, cast) ;
- }
- catch (InlineJavaServer.InlineJavaException e){
- throw new InlineJavaException(e) ;
- }
- catch (InlineJavaServer.InlineJavaPerlException e){
- throw new PerlException(e.GetObject()) ;
- }
- }
-}
-
+1 ;
\ No newline at end of file
diff --git a/Java/Class.pm b/Java/Class.pm
index 28e0ed3..ee7a19b 100644
--- a/Java/Class.pm
+++ b/Java/Class.pm
@@ -3,7 +3,7 @@ package Inline::Java::Class ;
use strict ;
-$Inline::Java::Class::VERSION = '0.31' ;
+$Inline::Java::Class::VERSION = '0.40' ;
$Inline::Java::Class::MAX_SCORE = 10 ;
@@ -484,464 +484,4 @@ sub matches {
}
-package Inline::Java::Class ;
-
-
1 ;
-
-
-__DATA__
-
-class InlineJavaClass {
- private InlineJavaServer ijs ;
- private InlineJavaProtocol ijp ;
-
- InlineJavaClass(InlineJavaServer _ijs, InlineJavaProtocol _ijp){
- ijs = _ijs ;
- ijp = _ijp ;
- }
-
-
- /*
- Makes sure a class exists
- */
- Class ValidateClass(String name) throws InlineJavaException {
- Class pc = FindType(name) ;
- if (pc != null){
- return pc ;
- }
-
- try {
- Class c = Class.forName(name) ;
- return c ;
- }
- catch (ClassNotFoundException e){
- throw new InlineJavaException("Class " + name + " not found") ;
- }
- }
-
- /*
- This is the monster method that determines how to cast arguments
- */
- Object [] CastArguments (Class [] params, ArrayList args) throws InlineJavaException {
- Object ret[] = new Object [params.length] ;
-
- for (int i = 0 ; i < params.length ; i++){
- // Here the args are all strings or objects (or undef)
- // we need to match them to the prototype.
- Class p = params[i] ;
- ijs.debug(4, "arg " + String.valueOf(i) + " of signature is " + p.getName()) ;
-
- ret[i] = CastArgument(p, (String)args.get(i)) ;
- }
-
- return ret ;
- }
-
-
- /*
- This is the monster method that determines how to cast arguments
- */
- Object CastArgument (Class p, String argument) throws InlineJavaException {
- Object ret = null ;
-
- ArrayList tokens = new ArrayList() ;
- StringTokenizer st = new StringTokenizer(argument, ":") ;
- for (int j = 0 ; st.hasMoreTokens() ; j++){
- tokens.add(j, st.nextToken()) ;
- }
- if (tokens.size() == 1){
- tokens.add(1, "") ;
- }
- String type = (String)tokens.get(0) ;
-
- // We need to separate the primitive types from the
- // reference types.
- boolean num = ClassIsNumeric(p) ;
- if ((num)||(ClassIsString(p))){
- Class ap = p ;
- if (ap == java.lang.Number.class){
- ijs.debug(4, "specializing java.lang.Number to java.lang.Double") ;
- ap = java.lang.Double.class ;
- }
-
- if (type.equals("undef")){
- if (num){
- ijs.debug(4, "args is undef -> forcing to " + ap.getName() + " 0") ;
- ret = ijp.CreateObject(ap, new Object [] {"0"}, new Class [] {String.class}) ;
- ijs.debug(4, " result is " + ret.toString()) ;
- }
- else{
- ret = null ;
- ijs.debug(4, "args is undef -> forcing to " + ap.getName() + " " + ret) ;
- ijs.debug(4, " result is " + ret) ;
- }
- }
- else if (type.equals("scalar")){
- String arg = ijp.decode((String)tokens.get(1)) ;
- ijs.debug(4, "args is scalar -> forcing to " + ap.getName()) ;
- try {
- ret = ijp.CreateObject(ap, new Object [] {arg}, new Class [] {String.class}) ;
- ijs.debug(4, " result is " + ret.toString()) ;
- }
- catch (NumberFormatException e){
- throw new InlineJavaCastException("Can't convert " + arg + " to " + ap.getName()) ;
- }
- }
- else{
- throw new InlineJavaCastException("Can't convert reference to " + p.getName()) ;
- }
- }
- else if (ClassIsBool(p)){
- if (type.equals("undef")){
- ijs.debug(4, "args is undef -> forcing to bool false") ;
- ret = new Boolean("false") ;
- ijs.debug(4, " result is " + ret.toString()) ;
- }
- else if (type.equals("scalar")){
- String arg = ijp.decode(((String)tokens.get(1)).toLowerCase()) ;
- ijs.debug(4, "args is scalar -> forcing to bool") ;
- if ((arg.equals(""))||(arg.equals("0"))){
- arg = "false" ;
- }
- else{
- arg = "true" ;
- }
- ret = new Boolean(arg) ;
- ijs.debug(4, " result is " + ret.toString()) ;
- }
- else{
- throw new InlineJavaCastException("Can't convert reference to " + p.getName()) ;
- }
- }
- else if (ClassIsChar(p)){
- if (type.equals("undef")){
- ijs.debug(4, "args is undef -> forcing to char '\0'") ;
- ret = new Character('\0') ;
- ijs.debug(4, " result is " + ret.toString()) ;
- }
- else if (type.equals("scalar")){
- String arg = ijp.decode((String)tokens.get(1)) ;
- ijs.debug(4, "args is scalar -> forcing to char") ;
- char c = '\0' ;
- if (arg.length() == 1){
- c = arg.toCharArray()[0] ;
- }
- else if (arg.length() > 1){
- throw new InlineJavaCastException("Can't convert " + arg + " to " + p.getName()) ;
- }
- ret = new Character(c) ;
- ijs.debug(4, " result is " + ret.toString()) ;
- }
- else{
- throw new InlineJavaCastException("Can't convert reference to " + p.getName()) ;
- }
- }
- else {
- ijs.debug(4, "class " + p.getName() + " is reference") ;
- // We know that what we expect here is a real object
- if (type.equals("undef")){
- ijs.debug(4, "args is undef -> forcing to null") ;
- ret = null ;
- }
- else if (type.equals("scalar")){
- // Here if we need a java.lang.Object.class, it's probably
- // because we can store anything, so we use a String object.
- if (p == java.lang.Object.class){
- String arg = ijp.decode((String)tokens.get(1)) ;
- ret = arg ;
- }
- else{
- throw new InlineJavaCastException("Can't convert primitive type to " + p.getName()) ;
- }
- }
- else{
- // We need an object and we got an object...
- ijs.debug(4, "class " + p.getName() + " is reference") ;
-
- String c_name = (String)tokens.get(1) ;
- String objid = (String)tokens.get(2) ;
-
- Class c = ValidateClass(c_name) ;
-
- if (DoesExtend(c, p) > -1){
- ijs.debug(4, " " + c.getName() + " is a kind of " + p.getName()) ;
- // get the object from the hash table
- int id = Integer.parseInt(objid) ;
- Object o = ijs.GetObject(id) ;
- ret = o ;
- }
- else{
- throw new InlineJavaCastException("Can't cast a " + c.getName() + " to a " + p.getName()) ;
- }
- }
- }
-
- return ret ;
- }
-
-
- /*
- Returns the number of levels that separate a from b
- */
- int DoesExtend(Class a, Class b){
- return DoesExtend(a, b, 0) ;
- }
-
-
- int DoesExtend(Class a, Class b, int level){
- ijs.debug(4, "checking if " + a.getName() + " extends " + b.getName()) ;
-
- if (a == b){
- return level ;
- }
-
- Class parent = a.getSuperclass() ;
- if (parent != null){
- ijs.debug(4, " parent is " + parent.getName()) ;
- int ret = DoesExtend(parent, b, level + 1) ;
- if (ret != -1){
- return ret ;
- }
- }
-
- // Maybe b is an interface a implements it?
- Class inter[] = a.getInterfaces() ;
- for (int i = 0 ; i < inter.length ; i++){
- ijs.debug(4, " interface is " + inter[i].getName()) ;
- int ret = DoesExtend(inter[i], b, level + 1) ;
- if (ret != -1){
- return ret ;
- }
- }
-
- return -1 ;
- }
-
-
- /*
- Finds the wrapper class for the passed primitive type.
- */
- Class FindWrapper (Class p){
- Class [] list = {
- byte.class,
- short.class,
- int.class,
- long.class,
- float.class,
- double.class,
- boolean.class,
- char.class,
- } ;
- Class [] listw = {
- java.lang.Byte.class,
- java.lang.Short.class,
- java.lang.Integer.class,
- java.lang.Long.class,
- java.lang.Float.class,
- java.lang.Double.class,
- java.lang.Boolean.class,
- java.lang.Character.class,
- } ;
-
- for (int i = 0 ; i < list.length ; i++){
- if (p == list[i]){
- return listw[i] ;
- }
- }
-
- return p ;
- }
-
-
- /*
- Finds the primitive type class for the passed primitive type name.
- */
- Class FindType (String name){
- String [] list = {
- "byte",
- "short",
- "int",
- "long",
- "float",
- "double",
- "boolean",
- "char",
- "B",
- "S",
- "I",
- "J",
- "F",
- "D",
- "Z",
- "C",
- } ;
- Class [] listc = {
- byte.class,
- short.class,
- int.class,
- long.class,
- float.class,
- double.class,
- boolean.class,
- char.class,
- byte.class,
- short.class,
- int.class,
- long.class,
- float.class,
- double.class,
- boolean.class,
- char.class,
- } ;
-
- for (int i = 0 ; i < list.length ; i++){
- if (name.equals(list[i])){
- return listc[i] ;
- }
- }
-
- return null ;
- }
-
-
- boolean ClassIsPrimitive (Class p){
- String name = p.getName() ;
-
- if ((ClassIsNumeric(p))||(ClassIsString(p))||(ClassIsChar(p))||(ClassIsBool(p))){
- return true ;
- }
-
- ijs.debug(4, "class " + name + " is reference") ;
- return false ;
- }
-
-
- /*
- Determines if class is of numerical type.
- */
- boolean ClassIsNumeric (Class p){
- String name = p.getName() ;
-
- Class [] list = {
- java.lang.Byte.class,
- java.lang.Short.class,
- java.lang.Integer.class,
- java.lang.Long.class,
- java.lang.Float.class,
- java.lang.Double.class,
- java.lang.Number.class,
- byte.class,
- short.class,
- int.class,
- long.class,
- float.class,
- double.class,
- } ;
-
- for (int i = 0 ; i < list.length ; i++){
- if (p == list[i]){
- ijs.debug(4, "class " + name + " is primitive numeric") ;
- return true ;
- }
- }
-
- return false ;
- }
-
-
- /*
- Class is String or StringBuffer
- */
- boolean ClassIsString (Class p){
- String name = p.getName() ;
-
- Class [] list = {
- java.lang.String.class,
- java.lang.StringBuffer.class,
- } ;
-
- for (int i = 0 ; i < list.length ; i++){
- if (p == list[i]){
- ijs.debug(4, "class " + name + " is primitive string") ;
- return true ;
- }
- }
-
- return false ;
- }
-
-
- /*
- Class is Char
- */
- boolean ClassIsChar (Class p){
- String name = p.getName() ;
-
- Class [] list = {
- java.lang.Character.class,
- char.class,
- } ;
-
- for (int i = 0 ; i < list.length ; i++){
- if (p == list[i]){
- ijs.debug(4, "class " + name + " is primitive char") ;
- return true ;
- }
- }
-
- return false ;
- }
-
-
- /*
- Class is Bool
- */
- boolean ClassIsBool (Class p){
- String name = p.getName() ;
-
- Class [] list = {
- java.lang.Boolean.class,
- boolean.class,
- } ;
-
- for (int i = 0 ; i < list.length ; i++){
- if (p == list[i]){
- ijs.debug(4, "class " + name + " is primitive bool") ;
- return true ;
- }
- }
-
- return false ;
- }
-
-
- /*
- Determines if a class is not of a primitive type or of a
- wrapper class.
- */
- boolean ClassIsReference (Class p){
- String name = p.getName() ;
-
- if (ClassIsPrimitive(p)){
- return false ;
- }
-
- ijs.debug(4, "class " + name + " is reference") ;
-
- return true ;
- }
-
- boolean ClassIsArray (Class p){
- String name = p.getName() ;
-
- if ((ClassIsReference(p))&&(name.startsWith("["))){
- ijs.debug(4, "class " + name + " is array") ;
- return true ;
- }
-
- return false ;
- }
-
-}
-
diff --git a/Java/Init.pm b/Java/Init.pm
deleted file mode 100644
index 8f21487..0000000
--- a/Java/Init.pm
+++ /dev/null
@@ -1,486 +0,0 @@
-package Inline::Java::Init ;
-
-
-use strict ;
-
-$Inline::Java::Init::VERSION = '0.31' ;
-
-my $DATA = join('', <DATA>) ;
-my $OBJECT_DATA = join('', <Inline::Java::Object::DATA>) ;
-my $ARRAY_DATA = join('', <Inline::Java::Array::DATA>) ;
-my $CLASS_DATA = join('', <Inline::Java::Class::DATA>) ;
-my $PROTO_DATA = join('', <Inline::Java::Protocol::DATA>) ;
-
-my $CALLBACK_DATA = join('', <Inline::Java::Callback::DATA>) ;
-
-
-sub DumpUserJavaCode {
- my $fh = shift ;
- my $code = shift ;
-
- print $fh $code ;
-}
-
-
-sub DumpServerJavaCode {
- my $fh = shift ;
-
- my $java = $DATA ;
- my $java_obj = $OBJECT_DATA ;
- my $java_array = $ARRAY_DATA ;
- my $java_class = $CLASS_DATA ;
- my $java_proto = $PROTO_DATA ;
-
- $java =~ s/<INLINE_JAVA_OBJECT>/$java_obj/g ;
- $java =~ s/<INLINE_JAVA_ARRAY>/$java_array/g ;
- $java =~ s/<INLINE_JAVA_CLASS>/$java_class/g ;
- $java =~ s/<INLINE_JAVA_PROTOCOL>/$java_proto/g ;
-
- print $fh $java ;
-}
-
-
-sub DumpCallbackJavaCode {
- my $fh = shift ;
-
- my $java = $CALLBACK_DATA ;
-
- print $fh $java ;
-}
-
-
-
-1 ;
-
-
-
-__DATA__
-import java.net.* ;
-import java.io.* ;
-import java.util.* ;
-import java.lang.reflect.* ;
-
-
-/*
- This is the server that will answer all the requests for and on Java
- objects.
-*/
-public class InlineJavaServer {
- static public InlineJavaServer instance = null ;
- private int debug ;
- private int port = 0 ;
- private boolean shared_jvm = false ;
-
- private HashMap thread_objects = new HashMap() ;
- private int objid = 1 ;
-
- // This constructor is used in JNI mode
- InlineJavaServer(int d) {
- init() ;
- debug = d ;
-
- thread_objects.put(Thread.currentThread().getName(), new HashMap()) ;
- }
-
-
- // This constructor is used in server mode
- InlineJavaServer(String[] argv) {
- init() ;
-
- debug = new Integer(argv[0]).intValue() ;
- port = Integer.parseInt(argv[1]) ;
- shared_jvm = new Boolean(argv[2]).booleanValue() ;
-
- ServerSocket ss = null ;
- try {
- ss = new ServerSocket(port) ;
- }
- catch (IOException e){
- System.err.println("Can't open server socket on port " + String.valueOf(port) +
- ": " + e.getMessage()) ;
- System.err.flush() ;
- System.exit(1) ;
- }
-
- while (true){
- try {
- InlineJavaThread ijt = new InlineJavaThread(this, ss.accept()) ;
- ijt.start() ;
- if (! shared_jvm){
- try {
- ijt.join() ;
- }
- catch (InterruptedException e){
- }
- break ;
- }
- }
- catch (IOException e){
- System.err.println("IO error: " + e.getMessage()) ;
- System.err.flush() ;
- }
- }
-
- System.exit(1) ;
- }
-
-
- private void init(){
- instance = this ;
- }
-
-
- public String GetType(){
- return (shared_jvm ? "shared" : "private") ;
- }
-
-
- /*
- Since this function is also called from the JNI XS extension,
- it's best if it doesn't throw any exceptions.
- */
- private String ProcessCommand(String cmd) {
- return ProcessCommand(cmd, true) ;
- }
-
- private String ProcessCommand(String cmd, boolean addlf) {
- debug(3, "packet recv is " + cmd) ;
-
- String resp = null ;
- if (cmd != null){
- InlineJavaProtocol ijp = new InlineJavaProtocol(this, cmd) ;
- try {
- ijp.Do() ;
- debug(3, "packet sent is " + ijp.response) ;
- resp = ijp.response ;
- }
- catch (InlineJavaException e){
- String err = "error scalar:" + ijp.encode(e.getMessage()) ;
- debug(3, "packet sent is " + err) ;
- resp = err ;
- }
- }
- else{
- if (! shared_jvm){
- // Probably connection dropped...
- debug(1, "lost connection with client in single client mode. Exiting.") ;
- System.exit(1) ;
- }
- else{
- debug(1, "lost connection with client in shared JVM mode.") ;
- return null ;
- }
- }
-
- if (addlf){
- resp = resp + "\n" ;
- }
-
- return resp ;
- }
-
-
- public Object GetObject(int id) throws InlineJavaException {
- Object o = null ;
- String name = Thread.currentThread().getName() ;
- HashMap h = (HashMap)thread_objects.get(name) ;
-
- if (h == null){
- throw new InlineJavaException("Can't find thread " + name + "!") ;
- }
- else{
- o = h.get(new Integer(id)) ;
- if (o == null){
- throw new InlineJavaException("Can't find object " + id + " for thread " + name) ;
- }
- }
-
- return o ;
- }
-
-
- synchronized public void PutObject(int id, Object o) throws InlineJavaException {
- String name = Thread.currentThread().getName() ;
- HashMap h = (HashMap)thread_objects.get(name) ;
-
- if (h == null){
- throw new InlineJavaException("Can't find thread " + name + "!") ;
- }
- else{
- h.put(new Integer(id), o) ;
- objid++ ;
- }
- }
-
-
- public Object DeleteObject(int id) throws InlineJavaException {
- Object o = null ;
- String name = Thread.currentThread().getName() ;
- HashMap h = (HashMap)thread_objects.get(name) ;
-
- if (h == null){
- throw new InlineJavaException("Can't find thread " + name + "!") ;
- }
- else{
- o = h.remove(new Integer(id)) ;
- if (o == null){
- throw new InlineJavaException("Can't find object " + id + " for thread " + name) ;
- }
- }
-
- return o ;
- }
-
-
- public int ObjectCount() throws InlineJavaException {
- int i = -1 ;
- String name = Thread.currentThread().getName() ;
- HashMap h = (HashMap)thread_objects.get(name) ;
-
- if (h == null){
- throw new InlineJavaException("Can't find thread " + name + "!") ;
- }
- else{
- i = h.values().size() ;
- }
-
- return i ;
- }
-
-
- public Object Callback(String pkg, String method, Object args[], String cast) throws InlineJavaException, InlineJavaPerlException {
- Object ret = null ;
-
- try {
- InlineJavaProtocol ijp = new InlineJavaProtocol(this, null) ;
- InlineJavaClass ijc = new InlineJavaClass(this, ijp) ;
- StringBuffer cmdb = new StringBuffer("callback " + pkg + " " + method + " " + cast) ;
- if (args != null){
- for (int i = 0 ; i < args.length ; i++){
- cmdb.append(" " + ijp.SerializeObject(args[i])) ;
- }
- }
- String cmd = cmdb.toString() ;
- debug(2, "callback command: " + cmd) ;
-
- Thread t = Thread.currentThread() ;
- String resp = null ;
- while (true) {
- debug(3, "packet sent (callback) is " + cmd) ;
- if (t instanceof InlineJavaThread){
- // Client-server mode
- InlineJavaThread ijt = (InlineJavaThread)t ;
- ijt.bw.write(cmd + "\n") ;
- ijt.bw.flush() ;
-
- resp = ijt.br.readLine() ;
- }
- else{
- // JNI mode
- resp = jni_callback(cmd) ;
- }
- debug(3, "packet recv (callback) is " + resp) ;
-
- StringTokenizer st = new StringTokenizer(resp, " ") ;
- String c = st.nextToken() ;
- if (c.equals("callback")){
- boolean thrown = new Boolean(st.nextToken()).booleanValue() ;
- String arg = st.nextToken() ;
- ret = ijc.CastArgument(java.lang.Object.class, arg) ;
-
- if (thrown){
- throw new InlineJavaPerlException(ret) ;
- }
-
- break ;
- }
- else{
- // Pass it on through the regular channel...
- debug(3, "packet is not callback response: " + resp) ;
- cmd = ProcessCommand(resp, false) ;
-
- continue ;
- }
- }
- }
- catch (IOException e){
- throw new InlineJavaException("IO error: " + e.getMessage()) ;
- }
-
- return ret ;
- }
-
-
- native private String jni_callback(String cmd) ;
-
-
- /*
- Creates a string representing a method signature
- */
- public String CreateSignature(Class param[]){
- return CreateSignature(param, ", ") ;
- }
-
-
- public String CreateSignature(Class param[], String del){
- StringBuffer ret = new StringBuffer() ;
- for (int i = 0 ; i < param.length ; i++){
- if (i > 0){
- ret.append(del) ;
- }
- ret.append(param[i].getName()) ;
- }
-
- return "(" + ret.toString() + ")" ;
- }
-
-
- synchronized public void debug(int level, String s) {
- if ((debug > 0)&&(debug >= level)){
- StringBuffer sb = new StringBuffer() ;
- for (int i = 0 ; i < level ; i++){
- sb.append(" ") ;
- }
- System.err.println("[java][" + level + "]" + sb.toString() + s) ;
- System.err.flush() ;
- }
- }
-
-
- boolean reverse_members() {
- String v = System.getProperty("java.version") ;
- boolean no_rev = ((v.startsWith("1.2"))||(v.startsWith("1.3"))) ;
-
- return (! no_rev) ;
- }
-
-
- /*
- Startup
- */
- public static void main(String[] argv) {
- new InlineJavaServer(argv) ;
- }
-
-
- public static InlineJavaServer jni_main(int debug) {
- return new InlineJavaServer(debug) ;
- }
-
- <INLINE_JAVA_OBJECT>
-
- <INLINE_JAVA_ARRAY>
-
- <INLINE_JAVA_CLASS>
-
- <INLINE_JAVA_PROTOCOL>
-
- /*
- Exception thrown by this code.
- */
- class InlineJavaException extends Exception {
- InlineJavaException(String s) {
- super(s) ;
- }
- }
-
-
- /*
- Exception thrown by Perl callbacks.
- */
- class InlineJavaPerlException extends Exception {
- private Object obj = null ;
-
-
- InlineJavaPerlException(Object o) {
- obj = o ;
- }
-
- public Object GetObject(){
- return obj ;
- }
- }
-
-
- /*
- Exception thrown by this code while trying to cast arguments
- */
- class InlineJavaCastException extends InlineJavaException {
- InlineJavaCastException(String m){
- super(m) ;
- }
- }
-
-
-
- class InlineJavaInvocationTargetException extends InlineJavaException {
- Throwable t = null ;
-
- InlineJavaInvocationTargetException(String m, Throwable _t){
- super(m) ;
- t = _t ;
- }
-
- public Throwable GetThrowable(){
- return t ;
- }
- }
-
-
- class InlineJavaThread extends Thread {
- InlineJavaServer ijs ;
- Socket client ;
- BufferedReader br ;
- BufferedWriter bw ;
-
- InlineJavaThread(InlineJavaServer _ijs, Socket _client) throws IOException {
- super() ;
- client = _client ;
- ijs = _ijs ;
-
- br = new BufferedReader(
- new InputStreamReader(client.getInputStream())) ;
- bw = new BufferedWriter(
- new OutputStreamWriter(client.getOutputStream())) ;
- }
-
-
- public void run(){
- try {
- ijs.thread_objects.put(getName(), new HashMap()) ;
-
- while (true){
- String cmd = br.readLine() ;
-
- String resp = ijs.ProcessCommand(cmd) ;
- if (resp != null){
- bw.write(resp) ;
- bw.flush() ;
- }
- else {
- break ;
- }
- }
- }
- catch (IOException e){
- System.err.println("IO error: " + e.getMessage()) ;
- }
- finally {
- ijs.thread_objects.remove(getName()) ;
- }
- }
- }
-}
-
-
-class InlineJavaServerThrown {
- Throwable t = null ;
-
- InlineJavaServerThrown(Throwable _t){
- t = _t ;
- }
-
- public Throwable GetThrowable(){
- return t ;
- }
-}
diff --git a/Java/JNI.pm b/Java/JNI.pm
index 4403187..121dba4 100644
--- a/Java/JNI.pm
+++ b/Java/JNI.pm
@@ -21,7 +21,7 @@ sub load_lib {
my $lib = (DynaLoader::dl_findfile($l))[0] ;
if ((! $lib)||(! defined(DynaLoader::dl_load_file($lib, 0x01)))){
- carp("Couldn't load $l.") ;
+ carp("Couldn't find or load $l.") ;
}
}
diff --git a/Java/JVM.pm b/Java/JVM.pm
index 44ee883..5bfc461 100644
--- a/Java/JVM.pm
+++ b/Java/JVM.pm
@@ -8,7 +8,7 @@ $Inline::Java::JVM::VERSION = '0.31' ;
use Carp ;
use IPC::Open3 ;
use IO::File ;
-use IO::Pipe ;
+use IO::Socket ;
use POSIX qw(setsid) ;
my %SIGS = () ;
@@ -41,7 +41,7 @@ sub new {
Inline::Java::debug(1, "JNI mode") ;
my $jni = new Inline::Java::JNI(
- $ENV{CLASSPATH} || "",
+ $ENV{CLASSPATH} || '',
$o->get_java_config('EMBEDDED_JNI'),
Inline::Java::get_DEBUG(),
) ;
@@ -70,13 +70,12 @@ sub new {
}
$this->capture(1) ;
- my $java = File::Spec->catfile($o->get_java_config('BIN'),
+ my $java = File::Spec->catfile($o->get_java_config('J2SDK'), 'bin',
"java" . Inline::Java::portable("EXE_EXTENSION")) ;
- my $shared_arg = ($this->{shared} ? "true" : "false") ;
- my $cmd = "\"$java\" InlineJavaServer $debug $this->{port} $shared_arg" ;
+ my $shared = ($this->{shared} ? "true" : "false") ;
+ my $cmd = "\"$java\" InlineJavaServer $debug $this->{port} $shared" ;
Inline::Java::debug(1, $cmd) ;
-
if ($o->get_config('UNTAINT')){
($cmd) = $cmd =~ /(.*)/ ;
}
@@ -91,7 +90,7 @@ sub new {
$this->{socket} = $this->setup_socket(
$this->{host},
$this->{port},
- $o->get_java_config('STARTUP_DELAY'),
+ int($o->get_java_config('STARTUP_DELAY')),
0
) ;
}
@@ -323,10 +322,12 @@ sub process_command {
my $data = shift ;
my $resp = undef ;
+
# Patch by Simon Cozens for perl -wle 'use Our::Module; do_stuff()'
local $/ = "\n" ;
local $\ = "" ;
# End Patch
+
while (1){
Inline::Java::debug(3, "packet sent is $data") ;
diff --git a/Java/Makefile.PL b/Java/Makefile.PL
index 3162386..3e8ff86 100644
--- a/Java/Makefile.PL
+++ b/Java/Makefile.PL
@@ -5,6 +5,9 @@ use strict ;
use File::Spec ;
require "Portable.pm" ;
+# The file we just produced in the parent Makefile.PL
+require "DefaultJ2SDK.pl" ;
+
# Some shortcuts while developing
my $jdk_dir = undef ;
@@ -43,22 +46,17 @@ foreach my $f (@files){
}
-print "\n" ;
print
- "Inline::Java can use a JNI extension that allows the Java Virtual Machine\n" .
+ "\nInline::Java can use a JNI extension that allows the Java Virtual Machine\n" .
"(JVM) to be dynamically linked with Perl instead of running as a separate\n" .
"process. The use of this extension is optional, and building it still\n" .
"allows Inline::Java to run the JVM in the default (separate process)\n" .
"fashion. Note: You need a C compiler to build the extension.\n\n" ;
-if (($build_jni || AskYN("Do you wish to build the JNI extension", 'n'))){
+if (($build_jni || AskYN("Do you wish to build the JNI extension?", 'y'))){
print "\nBuilding JNI extension.\n\n" ;
- rename("JNI.xs_", "JNI.xs") ;
-
- $jdk_dir = ($jdk_dir || AskSub("Enter the path to your Java 2 SDK installation",
- sub {((($_[0]) && (-d $_[0])) ? 1 : (print("Directory '$_[0]' does not exist.\n") && 0))})) ;
- print "\n" ;
+ $jdk_dir = Inline::Java::get_default_j2sdk() ;
my $type = FindDefaultVMType() ;
@@ -85,47 +83,37 @@ if (($build_jni || AskYN("Do you wish to build the JNI extension", 'n'))){
CleanSoDirs() ;
print "Building with:\n" ;
- foreach my $f (@files){
- print File::Spec->catfile($files->{$f}->{selected}, $f) . "\n" ;
- }
- print "\n" ;
+ map { print " " . File::Spec->catfile($files->{$_}->{selected}, $_) . "\n" ;} @files ;
$done = 0 ;
if (! $done){
+ print
+ "\nNote: In order for Inline::Java to use the JNI extension, you will need to\n" .
+ "use the JNI configuration option or set the PERL_INLINE_JAVA_JNI environment\n" .
+ "variable to a true value. You will also need to add the following directories\n" .
+ "to your " . Inline::Java::Portable::portable('SO_LIB_PATH_VAR') . " environment variable:\n" ;
+ map {print " $_\n"; } keys %so_dirs ;
+ print "See README.JNI for more information.\n\n" ;
+
WriteMakefile(
NAME => 'Inline::Java::JNI',
VERSION_FROM => 'JNI.pm',
+ DIR => [],
INC => "-I" . $files->{'jni.h'}->{selected} . " -I" . $files->{'jni_md.h'}->{selected},
LIBS => ["-L" . $files->{$jvm_lib}->{selected} . " -ljvm"],
# CCFLAGS => '-D_REENTRANT',
) ;
-
- print
- "\nNote: In order for Inline::Java to use the JNI extension, you\n" .
- "will need to use the JNI configuration option or set the\n" .
- "PERL_INLINE_JAVA_JNI environment variable to a true value.\n" .
- "You will also need to add the following directories to your\n" .
- Inline::Java::Portable::portable('SO_LIB_PATH_VAR') . " environment variable:\n" ;
-
- foreach my $d (keys %so_dirs){
- print " $d\n" ;
- }
-
- print
- "See README.JNI for more information.\n" ;
-
- print "\n" ;
}
}
}
else{
print "\n" ;
-
- rename("JNI.xs", "JNI.xs_") ;
-
WriteMakefile(
NAME => 'Inline::Java::JNI',
- VERSION_FROM => 'JNI.pm') ;
+ VERSION_FROM => 'JNI.pm',
+ DIR => [],
+ XS => {},
+ C => []) ;
}
@@ -139,6 +127,7 @@ sub search {
if ($File::Find::dir =~ /jre/){
if ($file =~ /\.$ext$/){
my $dir = File::Spec->canonpath($File::Find::dir) ;
+ print "---> $File::Find::dir\n" ;
$so_dirs{$dir} = 1 ;
}
}
@@ -211,16 +200,16 @@ sub Choose {
my $o = $files->{$f} ;
my $cnt = 0 ;
+ my $def = undef ;
foreach my $f (@{$o->{choices}}){
$cnt++ ;
- my $hint = '' ;
if ($f =~ /$type/){
- $hint = "[your system default]" ;
+ $def = $cnt ;
}
- print "[$cnt] $f $hint\n" ;
+ print "$cnt- $f\n" ;
}
- my $idx = AskSub("Please select from the above list which '$f' to use [1-$cnt]",
- sub {(($_[0] >= 1)&&($_[0] <= $cnt))}) ;
+ my $idx = AskSub("Please select from the above list (using the corresponding number) which '$f' to use",
+ $def, sub {(($_[0] >= 1)&&($_[0] <= $cnt))}) ;
$o->{selected} = $o->{choices}->[int($idx) - 1] ;
print "\n" ;
@@ -230,8 +219,9 @@ sub Choose {
# Gets string from stdin
sub Ask {
my $ques = shift ;
+ my $def = shift ;
- return AskSub($ques, undef) ;
+ return AskSub($ques, $def, undef) ;
}
@@ -240,22 +230,19 @@ sub AskYN {
my $ques = shift ;
my $def = shift ;
- $ques .= " [yn]?" ;
-
- my $ans = AskSub($ques, sub {((! $_[0])||($_[0] =~ /^(y|n)$/i))}) ;
+ my $ans = AskSub($ques, $def, sub {((! $_[0])||($_[0] =~ /^(y|n)$/i))}) ;
- return (($ans eq "y") ? 1 : 0) ;
+ return (($ans =~ /^y$/i) ? 1 : 0) ;
}
sub AskSub {
my $ques = shift ;
+ my $def = shift ;
my $sub = shift ;
- my $str = $ques . ":" ;
-
while (1){
- my $ans = prompt($str) ;
+ my $ans = prompt($ques, $def) ;
if (! $sub){
return $ans ;
}
diff --git a/Java/Object.pm b/Java/Object.pm
index 4b77ff5..80d01b0 100644
--- a/Java/Object.pm
+++ b/Java/Object.pm
@@ -548,12 +548,4 @@ sub DESTROY {
-
-package Inline::Java::Object ;
-
-
-1 ;
-
-
-__DATA__
-
+1 ;
\ No newline at end of file
diff --git a/Java/Portable.pm b/Java/Portable.pm
index 8403b7c..fb8a432 100644
--- a/Java/Portable.pm
+++ b/Java/Portable.pm
@@ -1,18 +1,20 @@
package Inline::Java::Portable ;
@Inline::Java::Portable::ISA = qw(Exporter) ;
- at EXPORT = qw(portable) ;
+ at EXPORT = qw(portable make_classpath get_jar) ;
use strict ;
-$Inline::Java::Portable::VERSION = '0.31' ;
+$Inline::Java::Portable::VERSION = '0.40' ;
use Exporter ;
use Carp ;
use Config ;
use File::Find ;
+use File::Spec ;
+
# Here is some code to figure out if we are running on command.com
# shell under Windows.
@@ -38,27 +40,50 @@ sub debug {
}
-# Here in Inline <= 0.43 there is a portability issue
-# with the mkpath function. It splits directly on '/'.
-# We assume this will be fixed in 0.44
-sub mkpath {
- my $o = shift ;
- my $path = shift ;
+# Cleans the CLASSPATH environment variable and adds
+# the paths specified.
+sub make_classpath {
+ my @paths = @_ ;
+
+ my @list = () ;
+ if (defined($ENV{CLASSPATH})){
+ push @list, $ENV{CLASSPATH} ;
+ }
+ push @list, @paths ;
+
+ my $sep = portable("ENV_VAR_PATH_SEP_CP") ;
+ my @cp = split(/$sep+/, join($sep, @list)) ;
+
+ # Clean up paths
+ foreach my $p (@cp){
+ $p =~ s/^\s+// ;
+ $p =~ s/\s+$// ;
+ $p = portable("SUB_FIX_CLASSPATH", $p) ;
+ }
+
+ # Remove duplicates, but preserve order
+ my @fcp = () ;
+ my %cp = map {$_ => 1} @cp ;
+ foreach my $p (@cp){
+ if (($p)&&($cp{$p})){
+ push @fcp, $p ;
+ delete $cp{$p} ;
+ }
+ }
+
+ my $cp = join($sep, @fcp) ;
+ Inline::Java::debug(1, "classpath: $cp") ;
- return $o->Inline::mkpath($path) ;
-} ;
+ return (wantarray ? @fcp : $cp) ;
+}
-# Here in Inline <= 0.43 there is a portability issue
-# with the rmpath function. It splits directly on '/'.
-# We assume this will be fixed in 0.44
-sub rmpath {
- my $o = shift ;
- my $prefix = shift ;
- my $path = shift ;
-
- return $o->Inline::rmpath($prefix, $path) ;
-} ;
+sub get_jar {
+ return File::Spec->catfile(
+ (File::Spec->splitpath($INC{"Inline/Java.pm"}))[0,1],
+ 'Java', 'jar', 'InlineJava.jar'
+ ) ;
+}
sub find_classes_in_dir {
@@ -68,9 +93,9 @@ sub find_classes_in_dir {
find(sub {
my $file = $_ ;
if ($file =~ /\.class$/){
- push @ret, $file ;
+ push @ret, File::Spec->catfile($File::Find::dir, $file) ;
}
- }, $dir) ;
+ }, $dir) ;
return @ret ;
}
@@ -177,8 +202,4 @@ sub portable {
}
-1 ;
-
-
-
-
+1 ;
\ No newline at end of file
diff --git a/Java/Protocol.pm b/Java/Protocol.pm
index 546ff68..52e4646 100644
--- a/Java/Protocol.pm
+++ b/Java/Protocol.pm
@@ -3,7 +3,7 @@ package Inline::Java::Protocol ;
use strict ;
-$Inline::Java::Protocol::VERSION = '0.31' ;
+$Inline::Java::Protocol::VERSION = '0.40' ;
use Inline::Java::Object ;
use Inline::Java::Array ;
@@ -370,7 +370,7 @@ sub DeserializeObject {
if ($thrown){
Inline::Java::debug(3, "throwing stub...") ;
- my ($msg, $score) = $obj->__isa('InlineJavaPerlCaller$PerlException') ;
+ my ($msg, $score) = $obj->__isa('IJPerlException') ;
if ($msg){
die $obj ;
}
@@ -416,628 +416,39 @@ sub DESTROY {
-__DATA__
-
-
-/*
- This is where most of the work of Inline Java is done. Here determine
- the request type and then we proceed to serve it.
-*/
-class InlineJavaProtocol {
- private InlineJavaServer ijs ;
- private InlineJavaClass ijc ;
- private InlineJavaArray ija ;
- private String cmd ;
- private String response ;
-
- InlineJavaProtocol(InlineJavaServer _ijs, String _cmd) {
- ijs = _ijs ;
- ijc = new InlineJavaClass(ijs, this) ;
- ija = new InlineJavaArray(ijs, ijc) ;
-
- cmd = _cmd ;
- }
-
-
- /*
- Starts the analysis of the command line
- */
- void Do() throws InlineJavaException {
- StringTokenizer st = new StringTokenizer(cmd, " ") ;
- String c = st.nextToken() ;
-
- if (c.equals("call_method")){
- CallJavaMethod(st) ;
- }
- else if (c.equals("set_member")){
- SetJavaMember(st) ;
- }
- else if (c.equals("get_member")){
- GetJavaMember(st) ;
- }
- else if (c.equals("server_type")){
- ServerType(st) ;
- }
- else if (c.equals("report")){
- Report(st) ;
- }
- else if (c.equals("isa")){
- ISA(st) ;
- }
- else if (c.equals("create_object")){
- CreateJavaObject(st) ;
- }
- else if (c.equals("delete_object")){
- DeleteJavaObject(st) ;
- }
- else if (c.equals("obj_cnt")){
- ObjectCount(st) ;
- }
- else if (c.equals("die")){
- ijs.debug(1, "received a request to die...") ;
- System.exit(0) ;
- }
- else {
- throw new InlineJavaException("Unknown command " + c) ;
- }
- }
-
- /*
- Returns a report on the Java classes, listing all public methods
- and members
- */
- void Report(StringTokenizer st) throws InlineJavaException {
- StringBuffer pw = new StringBuffer() ;
-
- StringTokenizer st2 = new StringTokenizer(st.nextToken(), ":") ;
- st2.nextToken() ;
-
- StringTokenizer st3 = new StringTokenizer(decode(st2.nextToken()), " ") ;
-
- ArrayList class_list = new ArrayList() ;
- while (st3.hasMoreTokens()){
- String c = st3.nextToken() ;
- class_list.add(class_list.size(), c) ;
- }
-
- for (int i = 0 ; i < class_list.size() ; i++){
- String name = (String)class_list.get(i) ;
- Class c = ijc.ValidateClass(name) ;
-
- ijs.debug(3, "reporting for " + c) ;
-
- pw.append("class " + c.getName() + "\n") ;
- Constructor constructors[] = c.getConstructors() ;
- Method methods[] = c.getMethods() ;
- Field fields[] = c.getFields() ;
-
- int pub = c.getModifiers() & Modifier.PUBLIC ;
- if (pub != 0){
- // If the class is public and has no constructors,
- // we provide a default no-arg constructors.
- if (c.getDeclaredConstructors().length == 0){
- String noarg_sign = CreateSignature(new Class [] {}) ;
- pw.append("constructor " + noarg_sign + "\n") ;
- }
- }
- for (int j = 0 ; j < constructors.length ; j++){
- Constructor x = constructors[j] ;
- Class params[] = x.getParameterTypes() ;
- String sign = CreateSignature(params) ;
- Class decl = x.getDeclaringClass() ;
- pw.append("constructor " + sign + "\n") ;
- }
-
- for (int j = 0 ; j < methods.length ; j++){
- Method x = methods[j] ;
- String stat = (Modifier.isStatic(x.getModifiers()) ? " static " : " instance ") ;
- String sign = CreateSignature(x.getParameterTypes()) ;
- Class decl = x.getDeclaringClass() ;
- pw.append("method" + stat + decl.getName() + " " + x.getName() + sign + "\n") ;
- }
-
- for (int j = 0 ; j < fields.length ; j++){
- Field x = fields[(ijs.reverse_members() ? (fields.length - 1 - j) : j)] ;
- String stat = (Modifier.isStatic(x.getModifiers()) ? " static " : " instance ") ;
- Class decl = x.getDeclaringClass() ;
- Class type = x.getType() ;
- pw.append("field" + stat + decl.getName() + " " + x.getName() + " " + type.getName() + "\n") ;
- }
- }
-
- SetResponse(pw.toString()) ;
- }
-
-
- void ServerType(StringTokenizer st) throws InlineJavaException {
- SetResponse(ijs.GetType()) ;
- }
-
-
- void ISA(StringTokenizer st) throws InlineJavaException {
- String class_name = st.nextToken() ;
- Class c = ijc.ValidateClass(class_name) ;
-
- String is_it_a = st.nextToken() ;
- Class d = ijc.ValidateClass(is_it_a) ;
-
- SetResponse(new Integer(ijc.DoesExtend(c, d))) ;
- }
-
-
- void ObjectCount(StringTokenizer st) throws InlineJavaException {
- SetResponse(new Integer(ijs.ObjectCount())) ;
- }
-
-
- /*
- Creates a Java Object with the specified arguments.
- */
- void CreateJavaObject(StringTokenizer st) throws InlineJavaException {
- String class_name = st.nextToken() ;
- Class c = ijc.ValidateClass(class_name) ;
-
- if (! ijc.ClassIsArray(c)){
- ArrayList f = ValidateMethod(true, c, class_name, st) ;
- Object p[] = (Object [])f.get(1) ;
- Class clist[] = (Class [])f.get(2) ;
-
- try {
- Object o = CreateObject(c, p, clist) ;
- SetResponse(o) ;
- }
- catch (InlineJavaInvocationTargetException ite){
- Throwable t = ite.GetThrowable() ;
- if (t instanceof InlineJavaPerlCaller.InlineJavaException){
- throw ((InlineJavaPerlCaller.InlineJavaException)t).GetException() ;
- }
- else{
- SetResponse(new InlineJavaServerThrown(t)) ;
- }
- }
- }
- else{
- // Here we send the type of array we want, but CreateArray
- // exception the element type.
- StringBuffer sb = new StringBuffer(class_name) ;
- // Remove the ['s
- while (sb.toString().startsWith("[")){
- sb.replace(0, 1, "") ;
- }
- // remove the L and the ;
- if (sb.toString().startsWith("L")){
- sb.replace(0, 1, "") ;
- sb.replace(sb.length() - 1, sb.length(), "") ;
- }
-
- Class ec = ijc.ValidateClass(sb.toString()) ;
-
- ijs.debug(4, "array elements: " + ec.getName()) ;
- Object o = ija.CreateArray(ec, st) ;
- SetResponse(o) ;
- }
- }
-
-
- /*
- Calls a Java method
- */
- void CallJavaMethod(StringTokenizer st) throws InlineJavaException {
- int id = Integer.parseInt(st.nextToken()) ;
-
- String class_name = st.nextToken() ;
- Object o = null ;
- if (id > 0){
- o = ijs.GetObject(id) ;
-
- // Use the class of the object
- class_name = o.getClass().getName() ;
- }
-
- Class c = ijc.ValidateClass(class_name) ;
- String method = st.nextToken() ;
-
- if ((ijc.ClassIsArray(c))&&(method.equals("getLength"))){
- int length = Array.getLength(o) ;
- SetResponse(new Integer(length)) ;
- }
- else{
- ArrayList f = ValidateMethod(false, c, method, st) ;
- Method m = (Method)f.get(0) ;
- String name = m.getName() ;
- Object p[] = (Object [])f.get(1) ;
-
- try {
- Object ret = m.invoke(o, p) ;
- SetResponse(ret) ;
- }
- catch (IllegalAccessException e){
- throw new InlineJavaException("You are not allowed to invoke method " + name + " in class " + class_name + ": " + e.getMessage()) ;
- }
- catch (IllegalArgumentException e){
- throw new InlineJavaException("Arguments for method " + name + " in class " + class_name + " are incompatible: " + e.getMessage()) ;
- }
- catch (InvocationTargetException e){
- Throwable t = e.getTargetException() ;
- String type = t.getClass().getName() ;
- String msg = t.getMessage() ;
- ijs.debug(1, "method " + name + " in class " + class_name + " threw exception " + type + ": " + msg) ;
- if (t instanceof InlineJavaPerlCaller.InlineJavaException){
- throw ((InlineJavaPerlCaller.InlineJavaException)t).GetException() ;
- }
- else{
- SetResponse(new InlineJavaServerThrown(t)) ;
- }
- }
- }
- }
-
-
- /*
- Sets a Java member variable
- */
- void SetJavaMember(StringTokenizer st) throws InlineJavaException {
- int id = Integer.parseInt(st.nextToken()) ;
-
- String class_name = st.nextToken() ;
- Object o = null ;
- if (id > 0){
- o = ijs.GetObject(id) ;
-
- // Use the class of the object
- class_name = o.getClass().getName() ;
- }
-
- Class c = ijc.ValidateClass(class_name) ;
- String member = st.nextToken() ;
-
- if (ijc.ClassIsArray(c)){
- int idx = Integer.parseInt(member) ;
- Class type = ijc.ValidateClass(st.nextToken()) ;
- String arg = st.nextToken() ;
-
- String msg = "For array of type " + c.getName() + ", element " + member + ": " ;
- try {
- Object elem = ijc.CastArgument(type, arg) ;
- Array.set(o, idx, elem) ;
- SetResponse(null) ;
- }
- catch (InlineJavaCastException e){
- throw new InlineJavaCastException(msg + e.getMessage()) ;
- }
- catch (InlineJavaException e){
- throw new InlineJavaException(msg + e.getMessage()) ;
- }
- }
- else{
- ArrayList fl = ValidateMember(c, member, st) ;
- Field f = (Field)fl.get(0) ;
- String name = f.getName() ;
- Object p = (Object)fl.get(1) ;
-
- try {
- f.set(o, p) ;
- SetResponse(null) ;
- }
- catch (IllegalAccessException e){
- throw new InlineJavaException("You are not allowed to set member " + name + " in class " + class_name + ": " + e.getMessage()) ;
- }
- catch (IllegalArgumentException e){
- throw new InlineJavaException("Argument for member " + name + " in class " + class_name + " is incompatible: " + e.getMessage()) ;
- }
- }
- }
-
-
- /*
- Gets a Java member variable
- */
- void GetJavaMember(StringTokenizer st) throws InlineJavaException {
- int id = Integer.parseInt(st.nextToken()) ;
-
- String class_name = st.nextToken() ;
- Object o = null ;
- if (id > 0){
- o = ijs.GetObject(id) ;
-
- // Use the class of the object
- class_name = o.getClass().getName() ;
- }
-
- Class c = ijc.ValidateClass(class_name) ;
- String member = st.nextToken() ;
-
- if (ijc.ClassIsArray(c)){
- int idx = Integer.parseInt(member) ;
- SetResponse(Array.get(o, idx)) ;
- }
- else{
- ArrayList fl = ValidateMember(c, member, st) ;
-
- Field f = (Field)fl.get(0) ;
- String name = f.getName() ;
- try {
- Object ret = f.get(o) ;
- SetResponse(ret) ;
- }
- catch (IllegalAccessException e){
- throw new InlineJavaException("You are not allowed to set member " + name + " in class " + class_name + ": " + e.getMessage()) ;
- }
- catch (IllegalArgumentException e){
- throw new InlineJavaException("Argument for member " + name + " in class " + class_name + " is incompatible: " + e.getMessage()) ;
- }
- }
- }
-
-
- /*
- Deletes a Java object
- */
- void DeleteJavaObject(StringTokenizer st) throws InlineJavaException {
- int id = Integer.parseInt(st.nextToken()) ;
-
- Object o = ijs.DeleteObject(id) ;
-
- SetResponse(null) ;
- }
-
-
- /*
- Creates a Java Object with the specified arguments.
- */
- Object CreateObject(Class p, Object args[], Class proto[]) throws InlineJavaException {
- p = ijc.FindWrapper(p) ;
-
- String name = p.getName() ;
- Object ret = null ;
- try {
- // This will allow usage of the default no-arg constructor
- if (proto.length == 0){
- ret = p.newInstance() ;
- }
- else{
- Constructor con = (Constructor)p.getConstructor(proto) ;
- ret = con.newInstance(args) ;
- }
- }
- catch (NoSuchMethodException e){
- throw new InlineJavaException("Constructor for class " + name + " with signature " + ijs.CreateSignature(proto) + " not found: " + e.getMessage()) ;
- }
- catch (InstantiationException e){
- throw new InlineJavaException("You are not allowed to instantiate object of class " + name + ": " + e.getMessage()) ;
- }
- catch (IllegalAccessException e){
- throw new InlineJavaException("You are not allowed to instantiate object of class " + name + " using the constructor with signature " + ijs.CreateSignature(proto) + ": " + e.getMessage()) ;
- }
- catch (IllegalArgumentException e){
- throw new InlineJavaException("Arguments to constructor for class " + name + " with signature " + ijs.CreateSignature(proto) + " are incompatible: " + e.getMessage()) ;
- }
- catch (InvocationTargetException e){
- Throwable t = e.getTargetException() ;
- String type = t.getClass().getName() ;
- String msg = t.getMessage() ;
- throw new InlineJavaInvocationTargetException(
- "Constructor for class " + name + " with signature " + ijs.CreateSignature(proto) + " threw exception " + type + ": " + msg,
- t) ;
- }
-
- return ret ;
- }
-
-
- /*
- 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
- String signature = st.nextToken() ;
-
- // Extract the arguments
- ArrayList args = new ArrayList() ;
- while (st.hasMoreTokens()){
- args.add(args.size(), st.nextToken()) ;
- }
-
- ArrayList ml = new ArrayList(ma.length) ;
- Class params[] = null ;
- for (int i = 0 ; i < ma.length ; i++){
- Member m = ma[i] ;
-
- if (m.getName().equals(name)){
- ijs.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 = ijs.CreateSignature(params, ",") ;
- ijs.debug(3, sign + " = " + signature + "?") ;
-
- if (signature.equals(sign)){
- ijs.debug(3, "has matching signature " + sign) ;
- ml.add(ml.size(), m) ;
- break ;
- }
- }
- }
-
- // Now we got a list of matching methods.
- // We have to figure out which one we will call.
- if (ml.size() == 0){
- // Nothing matched. Maybe we got a default constructor
- if ((constructor)&&(signature.equals("()"))){
- ret.add(0, null) ;
- ret.add(1, new Object [] {}) ;
- ret.add(2, new Class [] {}) ;
- }
- else{
- throw new InlineJavaException(
- (constructor ? "Constructor " : "Method ") +
- name + " for class " + c.getName() + " with signature " +
- signature + " not found") ;
- }
- }
- else if (ml.size() == 1){
- // Now we need to force the arguments received to match
- // the methods signature.
- Member m = (Member)ml.get(0) ;
- if (constructor){
- params = ((Constructor)m).getParameterTypes() ;
- }
- else{
- params = ((Method)m).getParameterTypes() ;
- }
-
- String msg = "In method " + name + " of class " + c.getName() + ": " ;
- try {
- ret.add(0, m) ;
- ret.add(1, ijc.CastArguments(params, args)) ;
- ret.add(2, params) ;
- }
- catch (InlineJavaCastException e){
- throw new InlineJavaCastException(msg + e.getMessage()) ;
- }
- catch (InlineJavaException e){
- throw new InlineJavaException(msg + e.getMessage()) ;
- }
- }
-
- return ret ;
- }
-
-
- /*
- 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
- String type = st.nextToken() ;
-
- // Extract the argument
- String arg = st.nextToken() ;
-
- ArrayList fl = new ArrayList(fa.length) ;
- Class param = null ;
- for (int i = 0 ; i < fa.length ; i++){
- Field f = fa[(ijs.reverse_members() ? (fa.length - 1 - i) : i)] ;
-
- if (f.getName().equals(name)){
- ijs.debug(3, "found a " + name + " member") ;
-
- param = f.getType() ;
- String t = param.getName() ;
- if (type.equals(t)){
- ijs.debug(3, "has matching type " + t) ;
- fl.add(fl.size(), f) ;
- }
- }
- }
-
- // Now we got a list of matching members.
- // We have to figure out which one we will call.
- if (fl.size() == 0){
- throw new InlineJavaException(
- "Member " + name + " of type " + type + " for class " + c.getName() +
- " not found") ;
- }
- else {
- // Now we need to force the arguments received to match
- // the methods signature.
-
- // If we have more that one, we use the last one, which is the most
- // specialized
- Field f = (Field)fl.get(fl.size() - 1) ;
- param = f.getType() ;
-
- String msg = "For member " + name + " of class " + c.getName() + ": " ;
- try {
- ret.add(0, f) ;
- ret.add(1, ijc.CastArgument(param, arg)) ;
- ret.add(2, param) ;
- }
- catch (InlineJavaCastException e){
- throw new InlineJavaCastException(msg + e.getMessage()) ;
- }
- catch (InlineJavaException e){
- throw new InlineJavaException(msg + e.getMessage()) ;
- }
- }
-
- return ret ;
- }
-
-
- /*
- This sets the response that will be returned to the Perl
- script
- */
- void SetResponse (Object o) throws InlineJavaException {
- response = "ok " + SerializeObject(o) ;
- }
-
-
- String SerializeObject(Object o) throws InlineJavaException {
- if (o == null){
- return "undef:" ;
- }
- else if ((ijc.ClassIsNumeric(o.getClass()))||(ijc.ClassIsChar(o.getClass()))||(ijc.ClassIsString(o.getClass()))){
- return "scalar:" + encode(o.toString()) ;
- }
- else if (ijc.ClassIsBool(o.getClass())){
- String b = o.toString() ;
- return "scalar:" + encode((b.equals("true") ? "1" : "0")) ;
- }
- else {
- // Here we need to register the object in order to send
- // it back to the Perl script.
- boolean thrown = false ;
- if (o instanceof InlineJavaServerThrown){
- thrown = true ;
- o = ((InlineJavaServerThrown)o).GetThrowable() ;
- }
- int id = ijs.objid ;
- ijs.PutObject(id, o) ;
- return "object:" + (thrown ? "1" : "0") + ":" + String.valueOf(id) +
- ":" + o.getClass().getName() ;
- }
- }
-
-
-
- public String decode(String s){
- StringTokenizer st = new StringTokenizer(s, ".") ;
- StringBuffer sb = new StringBuffer() ;
- while (st.hasMoreTokens()){
- String ss = st.nextToken() ;
- byte b[] = {(byte)Integer.parseInt(ss)} ;
- sb.append(new String(b)) ;
- }
-
- return sb.toString() ;
- }
-
-
- public String encode(String s){
- byte b[] = s.getBytes() ;
- StringBuffer sb = new StringBuffer() ;
- for (int i = 0 ; i < b.length ; i++){
- if (i > 0){
- sb.append(".") ;
- }
- sb.append(String.valueOf(b[i])) ;
- }
-
- return sb.toString() ;
- }
-}
-
+__END__
+
+
+RCS file: /cvsroot/inline-java/Inline-Java/Java/Protocol.pm,v
+retrieving revision 1.29
+diff -r1.29 Protocol.pm
+37a38,51
+> sub AddClassPath {
+> my $this = shift ;
+> my @paths = @_ ;
+>
+> Inline::Java::debug(3, "adding to class path (" .
+> join(", ", map {"'" . $_ . "'"} @paths) . ")") ;
+>
+> my $data = "add_classpath " . join(" ", map {encode($_)} @paths) ;
+>
+> return $this->Send($data, 1) ;
+> }
+>
+>
+>
+460a475,477
+> else if (c.equals("add_classpath")){
+> AddClassPath(st) ;
+> }
+553a571,580
+> }
+>
+>
+> void AddClassPath(StringTokenizer st) throws InlineJavaException {
+> while (st.hasMoreTokens()){
+> String path = decode(st.nextToken()) ;
+> InlineJavaServer.instance.AddClassPath(path) ;
+> }
+>
+> SetResponse(null) ;
diff --git a/Java/sources/InlineJavaArray.java b/Java/sources/InlineJavaArray.java
new file mode 100644
index 0000000..c05c621
--- /dev/null
+++ b/Java/sources/InlineJavaArray.java
@@ -0,0 +1,98 @@
+import java.util.* ;
+import java.lang.reflect.Array ;
+
+
+class InlineJavaArray {
+ private InlineJavaClass ijc ;
+
+
+ InlineJavaArray(InlineJavaClass _ijc){
+ ijc = _ijc ;
+ }
+
+
+ Object CreateArray(Class c, StringTokenizer st) throws InlineJavaException {
+ StringBuffer sb = new StringBuffer(st.nextToken()) ;
+ sb.replace(0, 1, "") ;
+ sb.replace(sb.length() - 1, sb.length(), "") ;
+
+ StringTokenizer st2 = new StringTokenizer(sb.toString(), ",") ;
+ ArrayList al = new ArrayList() ;
+ while (st2.hasMoreTokens()){
+ al.add(al.size(), st2.nextToken()) ;
+ }
+
+ int size = al.size() ;
+ int dims[] = new int[size] ;
+ for (int i = 0 ; i < size ; i++){
+ dims[i] = Integer.parseInt((String)al.get(i)) ;
+ InlineJavaUtils.debug(4, "array dimension: " + (String)al.get(i)) ;
+ }
+
+ Object array = null ;
+ try {
+ array = Array.newInstance(c, dims) ;
+
+ ArrayList args = new ArrayList() ;
+ while (st.hasMoreTokens()){
+ args.add(args.size(), st.nextToken()) ;
+ }
+
+ // Now we need to fill it. Since we have an arbitrary number
+ // of dimensions, we can do this recursively.
+
+ PopulateArray(array, c, dims, args) ;
+ }
+ catch (IllegalArgumentException e){
+ throw new InlineJavaException("Arguments to array constructor for class " + c.getName() + " are incompatible: " + e.getMessage()) ;
+ }
+
+ return array ;
+ }
+
+
+ void PopulateArray (Object array, Class elem, int dims[], ArrayList args) throws InlineJavaException {
+ if (dims.length > 1){
+ int nb_args = args.size() ;
+ int nb_sub_dims = dims[0] ;
+ int nb_args_per_sub_dim = nb_args / nb_sub_dims ;
+
+ int sub_dims[] = new int[dims.length - 1] ;
+ for (int i = 1 ; i < dims.length ; i++){
+ sub_dims[i - 1] = dims[i] ;
+ }
+
+ for (int i = 0 ; i < nb_sub_dims ; i++){
+ // We want the args from i*nb_args_per_sub_dim ->
+ ArrayList sub_args = new ArrayList() ;
+ for (int j = (i * nb_args_per_sub_dim) ; j < ((i + 1) * nb_args_per_sub_dim) ; j++){
+ sub_args.add(sub_args.size(), (String)args.get(j)) ;
+ }
+ PopulateArray(((Object [])array)[i], elem, sub_dims, sub_args) ;
+ }
+ }
+ else{
+ String msg = "In creation of array of " + elem.getName() + ": " ;
+ try {
+ for (int i = 0 ; i < dims[0] ; i++){
+ String arg = (String)args.get(i) ;
+
+ Object o = ijc.CastArgument(elem, arg) ;
+ Array.set(array, i, o) ;
+ if (o != null){
+ InlineJavaUtils.debug(4, "setting array element " + String.valueOf(i) + " to " + o.toString()) ;
+ }
+ else{
+ InlineJavaUtils.debug(4, "setting array element " + String.valueOf(i) + " to " + o) ;
+ }
+ }
+ }
+ catch (InlineJavaCastException e){
+ throw new InlineJavaCastException(msg + e.getMessage()) ;
+ }
+ catch (InlineJavaException e){
+ throw new InlineJavaException(msg + e.getMessage()) ;
+ }
+ }
+ }
+}
diff --git a/Java/sources/InlineJavaCastException.java b/Java/sources/InlineJavaCastException.java
new file mode 100644
index 0000000..798fe21
--- /dev/null
+++ b/Java/sources/InlineJavaCastException.java
@@ -0,0 +1,5 @@
+class InlineJavaCastException extends InlineJavaException {
+ InlineJavaCastException(String m){
+ super(m) ;
+ }
+}
diff --git a/Java/sources/InlineJavaClass.java b/Java/sources/InlineJavaClass.java
new file mode 100644
index 0000000..861076f
--- /dev/null
+++ b/Java/sources/InlineJavaClass.java
@@ -0,0 +1,455 @@
+import java.util.* ;
+
+
+class InlineJavaClass {
+ private InlineJavaServer ijs ;
+ private InlineJavaProtocol ijp ;
+
+
+ InlineJavaClass(InlineJavaServer _ijs, InlineJavaProtocol _ijp){
+ ijs = _ijs ;
+ ijp = _ijp ;
+ }
+
+
+ /*
+ Makes sure a class exists
+ */
+ Class ValidateClass(String name) throws InlineJavaException {
+ Class pc = FindType(name) ;
+ if (pc != null){
+ return pc ;
+ }
+
+ try {
+ Class c = Class.forName(name) ;
+ return c ;
+ }
+ catch (ClassNotFoundException e){
+ throw new InlineJavaException("Class " + name + " not found") ;
+ }
+ }
+
+ /*
+ This is the monster method that determines how to cast arguments
+ */
+ Object [] CastArguments (Class [] params, ArrayList args) throws InlineJavaException {
+ Object ret[] = new Object [params.length] ;
+
+ for (int i = 0 ; i < params.length ; i++){
+ // Here the args are all strings or objects (or undef)
+ // we need to match them to the prototype.
+ Class p = params[i] ;
+ InlineJavaUtils.debug(4, "arg " + String.valueOf(i) + " of signature is " + p.getName()) ;
+
+ ret[i] = CastArgument(p, (String)args.get(i)) ;
+ }
+
+ return ret ;
+ }
+
+
+ /*
+ This is the monster method that determines how to cast arguments
+ */
+ Object CastArgument (Class p, String argument) throws InlineJavaException {
+ Object ret = null ;
+
+ ArrayList tokens = new ArrayList() ;
+ StringTokenizer st = new StringTokenizer(argument, ":") ;
+ for (int j = 0 ; st.hasMoreTokens() ; j++){
+ tokens.add(j, st.nextToken()) ;
+ }
+ if (tokens.size() == 1){
+ tokens.add(1, "") ;
+ }
+ String type = (String)tokens.get(0) ;
+
+ // We need to separate the primitive types from the
+ // reference types.
+ boolean num = ClassIsNumeric(p) ;
+ if ((num)||(ClassIsString(p))){
+ Class ap = p ;
+ if (ap == java.lang.Number.class){
+ InlineJavaUtils.debug(4, "specializing java.lang.Number to java.lang.Double") ;
+ ap = java.lang.Double.class ;
+ }
+
+ if (type.equals("undef")){
+ if (num){
+ InlineJavaUtils.debug(4, "args is undef -> forcing to " + ap.getName() + " 0") ;
+ ret = ijp.CreateObject(ap, new Object [] {"0"}, new Class [] {String.class}) ;
+ InlineJavaUtils.debug(4, " result is " + ret.toString()) ;
+ }
+ else{
+ ret = null ;
+ InlineJavaUtils.debug(4, "args is undef -> forcing to " + ap.getName() + " " + ret) ;
+ InlineJavaUtils.debug(4, " result is " + ret) ;
+ }
+ }
+ else if (type.equals("scalar")){
+ String arg = ijp.Decode((String)tokens.get(1)) ;
+ InlineJavaUtils.debug(4, "args is scalar -> forcing to " + ap.getName()) ;
+ try {
+ ret = ijp.CreateObject(ap, new Object [] {arg}, new Class [] {String.class}) ;
+ InlineJavaUtils.debug(4, " result is " + ret.toString()) ;
+ }
+ catch (NumberFormatException e){
+ throw new InlineJavaCastException("Can't convert " + arg + " to " + ap.getName()) ;
+ }
+ }
+ else{
+ throw new InlineJavaCastException("Can't convert reference to " + p.getName()) ;
+ }
+ }
+ else if (ClassIsBool(p)){
+ if (type.equals("undef")){
+ InlineJavaUtils.debug(4, "args is undef -> forcing to bool false") ;
+ ret = new Boolean("false") ;
+ InlineJavaUtils.debug(4, " result is " + ret.toString()) ;
+ }
+ else if (type.equals("scalar")){
+ String arg = ijp.Decode(((String)tokens.get(1)).toLowerCase()) ;
+ InlineJavaUtils.debug(4, "args is scalar -> forcing to bool") ;
+ if ((arg.equals(""))||(arg.equals("0"))){
+ arg = "false" ;
+ }
+ else{
+ arg = "true" ;
+ }
+ ret = new Boolean(arg) ;
+ InlineJavaUtils.debug(4, " result is " + ret.toString()) ;
+ }
+ else{
+ throw new InlineJavaCastException("Can't convert reference to " + p.getName()) ;
+ }
+ }
+ else if (ClassIsChar(p)){
+ if (type.equals("undef")){
+ InlineJavaUtils.debug(4, "args is undef -> forcing to char '\0'") ;
+ ret = new Character('\0') ;
+ InlineJavaUtils.debug(4, " result is " + ret.toString()) ;
+ }
+ else if (type.equals("scalar")){
+ String arg = ijp.Decode((String)tokens.get(1)) ;
+ InlineJavaUtils.debug(4, "args is scalar -> forcing to char") ;
+ char c = '\0' ;
+ if (arg.length() == 1){
+ c = arg.toCharArray()[0] ;
+ }
+ else if (arg.length() > 1){
+ throw new InlineJavaCastException("Can't convert " + arg + " to " + p.getName()) ;
+ }
+ ret = new Character(c) ;
+ InlineJavaUtils.debug(4, " result is " + ret.toString()) ;
+ }
+ else{
+ throw new InlineJavaCastException("Can't convert reference to " + p.getName()) ;
+ }
+ }
+ else {
+ InlineJavaUtils.debug(4, "class " + p.getName() + " is reference") ;
+ // We know that what we expect here is a real object
+ if (type.equals("undef")){
+ InlineJavaUtils.debug(4, "args is undef -> forcing to null") ;
+ ret = null ;
+ }
+ else if (type.equals("scalar")){
+ // Here if we need a java.lang.Object.class, it's probably
+ // because we can store anything, so we use a String object.
+ if (p == java.lang.Object.class){
+ String arg = ijp.Decode((String)tokens.get(1)) ;
+ ret = arg ;
+ }
+ else{
+ throw new InlineJavaCastException("Can't convert primitive type to " + p.getName()) ;
+ }
+ }
+ else{
+ // We need an object and we got an object...
+ InlineJavaUtils.debug(4, "class " + p.getName() + " is reference") ;
+
+ String c_name = (String)tokens.get(1) ;
+ String objid = (String)tokens.get(2) ;
+
+ Class c = ValidateClass(c_name) ;
+
+ if (DoesExtend(c, p) > -1){
+ InlineJavaUtils.debug(4, " " + c.getName() + " is a kind of " + p.getName()) ;
+ // get the object from the hash table
+ int id = Integer.parseInt(objid) ;
+ Object o = ijs.GetObject(id) ;
+ ret = o ;
+ }
+ else{
+ throw new InlineJavaCastException("Can't cast a " + c.getName() + " to a " + p.getName()) ;
+ }
+ }
+ }
+
+ return ret ;
+ }
+
+
+ /*
+ Returns the number of levels that separate a from b
+ */
+ int DoesExtend(Class a, Class b){
+ return DoesExtend(a, b, 0) ;
+ }
+
+
+ int DoesExtend(Class a, Class b, int level){
+ InlineJavaUtils.debug(4, "checking if " + a.getName() + " extends " + b.getName()) ;
+
+ if (a == b){
+ return level ;
+ }
+
+ Class parent = a.getSuperclass() ;
+ if (parent != null){
+ InlineJavaUtils.debug(4, " parent is " + parent.getName()) ;
+ int ret = DoesExtend(parent, b, level + 1) ;
+ if (ret != -1){
+ return ret ;
+ }
+ }
+
+ // Maybe b is an interface a implements it?
+ Class inter[] = a.getInterfaces() ;
+ for (int i = 0 ; i < inter.length ; i++){
+ InlineJavaUtils.debug(4, " interface is " + inter[i].getName()) ;
+ int ret = DoesExtend(inter[i], b, level + 1) ;
+ if (ret != -1){
+ return ret ;
+ }
+ }
+
+ return -1 ;
+ }
+
+
+ /*
+ Finds the wrapper class for the passed primitive type.
+ */
+ Class FindWrapper (Class p){
+ Class [] list = {
+ byte.class,
+ short.class,
+ int.class,
+ long.class,
+ float.class,
+ double.class,
+ boolean.class,
+ char.class,
+ } ;
+ Class [] listw = {
+ java.lang.Byte.class,
+ java.lang.Short.class,
+ java.lang.Integer.class,
+ java.lang.Long.class,
+ java.lang.Float.class,
+ java.lang.Double.class,
+ java.lang.Boolean.class,
+ java.lang.Character.class,
+ } ;
+
+ for (int i = 0 ; i < list.length ; i++){
+ if (p == list[i]){
+ return listw[i] ;
+ }
+ }
+
+ return p ;
+ }
+
+
+ /*
+ Finds the primitive type class for the passed primitive type name.
+ */
+ Class FindType (String name){
+ String [] list = {
+ "byte",
+ "short",
+ "int",
+ "long",
+ "float",
+ "double",
+ "boolean",
+ "char",
+ "B",
+ "S",
+ "I",
+ "J",
+ "F",
+ "D",
+ "Z",
+ "C",
+ } ;
+ Class [] listc = {
+ byte.class,
+ short.class,
+ int.class,
+ long.class,
+ float.class,
+ double.class,
+ boolean.class,
+ char.class,
+ byte.class,
+ short.class,
+ int.class,
+ long.class,
+ float.class,
+ double.class,
+ boolean.class,
+ char.class,
+ } ;
+
+ for (int i = 0 ; i < list.length ; i++){
+ if (name.equals(list[i])){
+ return listc[i] ;
+ }
+ }
+
+ return null ;
+ }
+
+
+ boolean ClassIsPrimitive (Class p){
+ String name = p.getName() ;
+
+ if ((ClassIsNumeric(p))||(ClassIsString(p))||(ClassIsChar(p))||(ClassIsBool(p))){
+ return true ;
+ }
+
+ InlineJavaUtils.debug(4, "class " + name + " is reference") ;
+ return false ;
+ }
+
+
+ /*
+ Determines if class is of numerical type.
+ */
+ boolean ClassIsNumeric (Class p){
+ String name = p.getName() ;
+
+ Class [] list = {
+ java.lang.Byte.class,
+ java.lang.Short.class,
+ java.lang.Integer.class,
+ java.lang.Long.class,
+ java.lang.Float.class,
+ java.lang.Double.class,
+ java.lang.Number.class,
+ byte.class,
+ short.class,
+ int.class,
+ long.class,
+ float.class,
+ double.class,
+ } ;
+
+ for (int i = 0 ; i < list.length ; i++){
+ if (p == list[i]){
+ InlineJavaUtils.debug(4, "class " + name + " is primitive numeric") ;
+ return true ;
+ }
+ }
+
+ return false ;
+ }
+
+
+ /*
+ Class is String or StringBuffer
+ */
+ boolean ClassIsString (Class p){
+ String name = p.getName() ;
+
+ Class [] list = {
+ java.lang.String.class,
+ java.lang.StringBuffer.class,
+ } ;
+
+ for (int i = 0 ; i < list.length ; i++){
+ if (p == list[i]){
+ InlineJavaUtils.debug(4, "class " + name + " is primitive string") ;
+ return true ;
+ }
+ }
+
+ return false ;
+ }
+
+
+ /*
+ Class is Char
+ */
+ boolean ClassIsChar (Class p){
+ String name = p.getName() ;
+
+ Class [] list = {
+ java.lang.Character.class,
+ char.class,
+ } ;
+
+ for (int i = 0 ; i < list.length ; i++){
+ if (p == list[i]){
+ InlineJavaUtils.debug(4, "class " + name + " is primitive char") ;
+ return true ;
+ }
+ }
+
+ return false ;
+ }
+
+
+ /*
+ Class is Bool
+ */
+ boolean ClassIsBool (Class p){
+ String name = p.getName() ;
+
+ Class [] list = {
+ java.lang.Boolean.class,
+ boolean.class,
+ } ;
+
+ for (int i = 0 ; i < list.length ; i++){
+ if (p == list[i]){
+ InlineJavaUtils.debug(4, "class " + name + " is primitive bool") ;
+ return true ;
+ }
+ }
+
+ return false ;
+ }
+
+
+ /*
+ Determines if a class is not of a primitive type or of a
+ wrapper class.
+ */
+ boolean ClassIsReference (Class p){
+ String name = p.getName() ;
+
+ if (ClassIsPrimitive(p)){
+ return false ;
+ }
+
+ InlineJavaUtils.debug(4, "class " + name + " is reference") ;
+
+ return true ;
+ }
+
+ boolean ClassIsArray (Class p){
+ String name = p.getName() ;
+
+ if ((ClassIsReference(p))&&(name.startsWith("["))){
+ InlineJavaUtils.debug(4, "class " + name + " is array") ;
+ return true ;
+ }
+
+ return false ;
+ }
+}
\ No newline at end of file
diff --git a/Java/sources/InlineJavaException.java b/Java/sources/InlineJavaException.java
new file mode 100644
index 0000000..2143dac
--- /dev/null
+++ b/Java/sources/InlineJavaException.java
@@ -0,0 +1,5 @@
+class InlineJavaException extends Exception {
+ InlineJavaException(String s) {
+ super(s) ;
+ }
+}
diff --git a/Java/sources/InlineJavaInvocationTargetException.java b/Java/sources/InlineJavaInvocationTargetException.java
new file mode 100644
index 0000000..d65b55d
--- /dev/null
+++ b/Java/sources/InlineJavaInvocationTargetException.java
@@ -0,0 +1,13 @@
+class InlineJavaInvocationTargetException extends InlineJavaException {
+ private Throwable t = null ;
+
+
+ InlineJavaInvocationTargetException(String m, Throwable _t){
+ super(m) ;
+ t = _t ;
+ }
+
+ Throwable GetThrowable(){
+ return t ;
+ }
+}
diff --git a/Java/sources/InlineJavaPerlCaller.java b/Java/sources/InlineJavaPerlCaller.java
new file mode 100644
index 0000000..04eaa38
--- /dev/null
+++ b/Java/sources/InlineJavaPerlCaller.java
@@ -0,0 +1,19 @@
+/*
+ Callback to Perl...
+
+ This class has user visibility so methods must be public.
+*/
+class InlineJavaPerlCaller {
+ public InlineJavaPerlCaller(){
+ }
+
+
+ public Object CallPerl(String pkg, String method, Object args[]) throws InlineJavaException, InlineJavaPerlException {
+ return CallPerl(pkg, method, args, null) ;
+ }
+
+
+ public Object CallPerl(String pkg, String method, Object args[], String cast) throws InlineJavaException, InlineJavaPerlException {
+ return InlineJavaServer.instance.Callback(pkg, method, args, cast) ;
+ }
+}
diff --git a/Java/sources/InlineJavaPerlException.java b/Java/sources/InlineJavaPerlException.java
new file mode 100644
index 0000000..4f78755
--- /dev/null
+++ b/Java/sources/InlineJavaPerlException.java
@@ -0,0 +1,21 @@
+/*
+ This object can have user visibility and therefore
+ must have public methods.
+*/
+
+class InlineJavaPerlException extends Exception {
+ private Object obj = null ;
+
+
+ InlineJavaPerlException(Object o) {
+ obj = o ;
+ }
+
+ public Object GetObject(){
+ return obj ;
+ }
+
+ public String GetString(){
+ return (String)obj ;
+ }
+}
diff --git a/Java/Protocol.pm b/Java/sources/InlineJavaProtocol.java
similarity index 58%
copy from Java/Protocol.pm
copy to Java/sources/InlineJavaProtocol.java
index 546ff68..694ae83 100644
--- a/Java/Protocol.pm
+++ b/Java/sources/InlineJavaProtocol.java
@@ -1,422 +1,5 @@
-package Inline::Java::Protocol ;
-
-
-use strict ;
-
-$Inline::Java::Protocol::VERSION = '0.31' ;
-
-use Inline::Java::Object ;
-use Inline::Java::Array ;
-use Carp ;
-
-
-sub new {
- my $class = shift ;
- my $obj = shift ;
- my $inline = shift ;
-
- my $this = {} ;
- $this->{obj_priv} = $obj || {} ;
- $this->{module} = $inline->get_api('modfname') ;
-
- bless($this, $class) ;
- return $this ;
-}
-
-
-sub ServerType {
- my $this = shift ;
-
- Inline::Java::debug(3, "getting server type") ;
-
- my $data = "server_type" ;
-
- return $this->Send($data, 1) ;
-}
-
-
-sub Report {
- my $this = shift ;
- my $classes = shift ;
-
- Inline::Java::debug(3, "reporting on $classes") ;
-
- my $data = join(" ",
- "report",
- $this->ValidateArgs([$classes]),
- ) ;
-
- return $this->Send($data, 1) ;
-}
-
-
-sub ISA {
- my $this = shift ;
- my $proto = shift ;
-
- my $class = $this->{obj_priv}->{java_class} ;
-
- Inline::Java::debug(3, "checking if $class is a $proto") ;
-
- my $data = join(" ",
- "isa",
- Inline::Java::Class::ValidateClass($class),
- Inline::Java::Class::ValidateClass($proto),
- ) ;
-
- return $this->Send($data, 1) ;
-}
-
-
-sub ObjectCount {
- my $this = shift ;
-
- Inline::Java::debug(3, "getting object count") ;
-
- my $data = join(" ",
- "obj_cnt",
- ) ;
-
- return $this->Send($data, 1) ;
-}
-
-
-# Called to create a Java object
-sub CreateJavaObject {
- my $this = shift ;
- my $class = shift ;
- my $proto = shift ;
- my $args = shift ;
-
- Inline::Java::debug(3, "creating object new $class" . $this->CreateSignature($args)) ;
-
- my $data = join(" ",
- "create_object",
- Inline::Java::Class::ValidateClass($class),
- $this->CreateSignature($proto, ","),
- $this->ValidateArgs($args),
- ) ;
-
- return $this->Send($data, 1) ;
-}
-
-
-# Calls a Java method.
-sub CallJavaMethod {
- my $this = shift ;
- my $method = shift ;
- my $proto = shift ;
- my $args = shift ;
-
- my $id = $this->{obj_priv}->{id} ;
- my $class = $this->{obj_priv}->{java_class} ;
- Inline::Java::debug(3, "calling object($id).$method" . $this->CreateSignature($args)) ;
-
- my $data = join(" ",
- "call_method",
- $id,
- Inline::Java::Class::ValidateClass($class),
- $this->ValidateMethod($method),
- $this->CreateSignature($proto, ","),
- $this->ValidateArgs($args),
- ) ;
-
- return $this->Send($data) ;
-}
-
-
-# Sets a member variable.
-sub SetJavaMember {
- my $this = shift ;
- my $member = shift ;
- my $proto = shift ;
- my $arg = shift ;
-
- my $id = $this->{obj_priv}->{id} ;
- my $class = $this->{obj_priv}->{java_class} ;
- Inline::Java::debug(3, "setting object($id)->{$member} = " . ($arg->[0] || '')) ;
- my $data = join(" ",
- "set_member",
- $id,
- Inline::Java::Class::ValidateClass($class),
- $this->ValidateMember($member),
- Inline::Java::Class::ValidateClass($proto->[0]),
- $this->ValidateArgs($arg),
- ) ;
-
- return $this->Send($data) ;
-}
-
-
-# Gets a member variable.
-sub GetJavaMember {
- my $this = shift ;
- my $member = shift ;
- my $proto = shift ;
-
- my $id = $this->{obj_priv}->{id} ;
- my $class = $this->{obj_priv}->{java_class} ;
- Inline::Java::debug(3, "getting object($id)->{$member}") ;
-
- my $data = join(" ",
- "get_member",
- $id,
- Inline::Java::Class::ValidateClass($class),
- $this->ValidateMember($member),
- Inline::Java::Class::ValidateClass($proto->[0]),
- "undef:",
- ) ;
-
- return $this->Send($data) ;
-}
-
-
-# Deletes a Java object
-sub DeleteJavaObject {
- my $this = shift ;
- my $obj = shift ;
-
- if (defined($this->{obj_priv}->{id})){
- my $id = $this->{obj_priv}->{id} ;
- my $class = $this->{obj_priv}->{java_class} ;
-
- Inline::Java::debug(3, "deleting object $obj $id ($class)") ;
-
- my $data = join(" ",
- "delete_object",
- $id,
- ) ;
-
- $this->Send($data) ;
- }
-}
-
-
-# This method makes sure that the method we are asking for
-# has the correct form for a Java method.
-sub ValidateMethod {
- my $this = shift ;
- my $method = shift ;
-
- if ($method !~ /^(\w+)$/){
- croak "Invalid Java method name $method" ;
- }
-
- return $method ;
-}
-
-
-# This method makes sure that the member we are asking for
-# has the correct form for a Java member.
-sub ValidateMember {
- my $this = shift ;
- my $member = shift ;
-
- if ($member !~ /^(\w+)$/){
- croak "Invalid Java member name $member" ;
- }
-
- return $member ;
-}
-
-
-# Validates the arguments to be used in a method call.
-sub ValidateArgs {
- my $this = shift ;
- my $args = shift ;
- my $callback = shift ;
-
- my @ret = () ;
- foreach my $arg (@{$args}){
- if (! defined($arg)){
- push @ret, "undef:" ;
- }
- elsif (ref($arg)){
- if ((! UNIVERSAL::isa($arg, "Inline::Java::Object"))&&(! UNIVERSAL::isa($arg, "Inline::Java::Array"))){
- if (! $callback){
- croak "A Java method or member can only have Java objects, Java arrays or scalars as arguments" ;
- }
- else{
- croak "A Java callback function can only return Java objects, Java arrays or scalars" ;
- }
- }
-
- my $obj = $arg ;
- if (UNIVERSAL::isa($arg, "Inline::Java::Array")){
- $obj = $arg->__get_object() ;
- }
- my $class = $obj->__get_private()->{java_class} ;
- my $id = $obj->__get_private()->{id} ;
- push @ret, "object:$class:$id" ;
- }
- else{
- push @ret, "scalar:" . encode($arg) ;
- }
- }
-
- return @ret ;
-}
-
-
-sub CreateSignature {
- my $this = shift ;
- my $proto = shift ;
- my $del = shift || ", " ;
-
- my @p = map {$_ || ''} @{$proto} ;
-
- return "(" . join($del, @p) . ")" ;
-}
-
-
-# This actually sends the request to the Java program. It also takes
-# care of registering the returned object (if any)
-sub Send {
- my $this = shift ;
- my $data = shift ;
- my $const = shift ;
-
- my $inline = Inline::Java::get_INLINE($this->{module}) ;
- my $resp = Inline::Java::__get_JVM()->process_command($inline, $data) ;
-
- if ($resp =~ /^error scalar:([\d.-]*)$/){
- my $msg = decode($1) ;
- Inline::Java::debug(3, "packet recv error: $msg") ;
- croak $msg ;
- }
- elsif ($resp =~ s/^ok //){
- return $this->DeserializeObject($const, $resp) ;
- }
-
- croak "Malformed response from server: $resp" ;
-}
-
-
-sub DeserializeObject {
- my $this = shift ;
- my $const = shift ;
- my $resp = shift ;
-
- if ($resp =~ /^scalar:([\d.-]*)$/){
- return decode($1) ;
- }
- elsif ($resp =~ /^undef:$/){
- return undef ;
- }
- elsif ($resp =~ /^object:([01]):(\d+):(.*)$/){
- # Create the Perl object wrapper and return it.
- my $thrown = $1 ;
- my $id = $2 ;
- my $class = $3 ;
-
- if ($thrown){
- # If we receive a thrown object, we jump out of 'constructor
- # mode' and process the returned object.
- $const = 0 ;
- }
-
- if ($const){
- $this->{obj_priv}->{java_class} = $class ;
- $this->{obj_priv}->{id} = $id ;
-
- return undef ;
- }
- else{
- my $inline = Inline::Java::get_INLINE($this->{module}) ;
- my $pkg = $inline->get_api('pkg') ;
-
- my $obj = undef ;
- my $elem_class = $class ;
-
- Inline::Java::debug(3, "checking if stub is array...") ;
- if (Inline::Java::Class::ClassIsArray($class)){
- my @d = Inline::Java::Class::ValidateClassSplit($class) ;
- $elem_class = $d[2] ;
- }
-
-
- my $perl_class = "Inline::Java::Object" ;
- if ($elem_class){
- # We have a real class or an array of real classes
- $perl_class = Inline::Java::java2perl($pkg, $elem_class) ;
- if (Inline::Java::Class::ClassIsReference($elem_class)){
- if (! Inline::Java::known_to_perl($pkg, $elem_class)){
- if (($thrown)||($inline->get_java_config('AUTOSTUDY'))){
- $inline->_study([$elem_class]) ;
- }
- else{
- # Object is not known to Perl, it lives as a
- # Inline::Java::Object
- $perl_class = "Inline::Java::Object" ;
- }
- }
- }
- }
- else{
- # We should only get here if an array of primitives types
- # was returned, and there is nothing to do since
- # the block below will handle it.
- }
-
- if (Inline::Java::Class::ClassIsArray($class)){
- Inline::Java::debug(3, "creating array object...") ;
- $obj = Inline::Java::Object->__new($class, $inline, $id) ;
- $obj = new Inline::Java::Array($obj) ;
- Inline::Java::debug(3, "array object created...") ;
- }
- else{
- $obj = $perl_class->__new($class, $inline, $id) ;
- }
-
- if ($thrown){
- Inline::Java::debug(3, "throwing stub...") ;
- my ($msg, $score) = $obj->__isa('InlineJavaPerlCaller$PerlException') ;
- if ($msg){
- die $obj ;
- }
- else{
- die $obj->GetObject() ;
- }
- }
- else{
- Inline::Java::debug(3, "returning stub...") ;
- return $obj ;
- }
- }
- }
- else{
- croak "Malformed response from server: $resp" ;
- }
-}
-
-
-sub encode {
- my $s = shift ;
-
- return join(".", unpack("C*", $s)) ;
-}
-
-
-sub decode {
- my $s = shift ;
-
- return pack("C*", split(/\./, $s)) ;
-}
-
-
-sub DESTROY {
- my $this = shift ;
-
- Inline::Java::debug(4, "destroying Inline::Java::Protocol") ;
-}
-
-
-
-1 ;
-
-
-
-__DATA__
+import java.util.* ;
+import java.lang.reflect.* ;
/*
@@ -430,12 +13,13 @@ class InlineJavaProtocol {
private String cmd ;
private String response ;
+
InlineJavaProtocol(InlineJavaServer _ijs, String _cmd) {
ijs = _ijs ;
ijc = new InlineJavaClass(ijs, this) ;
- ija = new InlineJavaArray(ijs, ijc) ;
+ ija = new InlineJavaArray(ijc) ;
- cmd = _cmd ;
+ cmd = _cmd ;
}
@@ -462,7 +46,7 @@ class InlineJavaProtocol {
Report(st) ;
}
else if (c.equals("isa")){
- ISA(st) ;
+ IsA(st) ;
}
else if (c.equals("create_object")){
CreateJavaObject(st) ;
@@ -474,7 +58,7 @@ class InlineJavaProtocol {
ObjectCount(st) ;
}
else if (c.equals("die")){
- ijs.debug(1, "received a request to die...") ;
+ InlineJavaUtils.debug(1, "received a request to die...") ;
System.exit(0) ;
}
else {
@@ -492,7 +76,7 @@ class InlineJavaProtocol {
StringTokenizer st2 = new StringTokenizer(st.nextToken(), ":") ;
st2.nextToken() ;
- StringTokenizer st3 = new StringTokenizer(decode(st2.nextToken()), " ") ;
+ StringTokenizer st3 = new StringTokenizer(Decode(st2.nextToken()), " ") ;
ArrayList class_list = new ArrayList() ;
while (st3.hasMoreTokens()){
@@ -504,7 +88,7 @@ class InlineJavaProtocol {
String name = (String)class_list.get(i) ;
Class c = ijc.ValidateClass(name) ;
- ijs.debug(3, "reporting for " + c) ;
+ InlineJavaUtils.debug(3, "reporting for " + c) ;
pw.append("class " + c.getName() + "\n") ;
Constructor constructors[] = c.getConstructors() ;
@@ -516,14 +100,14 @@ class InlineJavaProtocol {
// If the class is public and has no constructors,
// we provide a default no-arg constructors.
if (c.getDeclaredConstructors().length == 0){
- String noarg_sign = CreateSignature(new Class [] {}) ;
+ String noarg_sign = InlineJavaUtils.CreateSignature(new Class [] {}) ;
pw.append("constructor " + noarg_sign + "\n") ;
}
}
for (int j = 0 ; j < constructors.length ; j++){
Constructor x = constructors[j] ;
Class params[] = x.getParameterTypes() ;
- String sign = CreateSignature(params) ;
+ String sign = InlineJavaUtils.CreateSignature(params) ;
Class decl = x.getDeclaringClass() ;
pw.append("constructor " + sign + "\n") ;
}
@@ -531,13 +115,13 @@ class InlineJavaProtocol {
for (int j = 0 ; j < methods.length ; j++){
Method x = methods[j] ;
String stat = (Modifier.isStatic(x.getModifiers()) ? " static " : " instance ") ;
- String sign = CreateSignature(x.getParameterTypes()) ;
+ String sign = InlineJavaUtils.CreateSignature(x.getParameterTypes()) ;
Class decl = x.getDeclaringClass() ;
pw.append("method" + stat + decl.getName() + " " + x.getName() + sign + "\n") ;
}
for (int j = 0 ; j < fields.length ; j++){
- Field x = fields[(ijs.reverse_members() ? (fields.length - 1 - j) : j)] ;
+ Field x = fields[(InlineJavaUtils.ReverseMembers() ? (fields.length - 1 - j) : j)] ;
String stat = (Modifier.isStatic(x.getModifiers()) ? " static " : " instance ") ;
Class decl = x.getDeclaringClass() ;
Class type = x.getType() ;
@@ -554,7 +138,7 @@ class InlineJavaProtocol {
}
- void ISA(StringTokenizer st) throws InlineJavaException {
+ void IsA(StringTokenizer st) throws InlineJavaException {
String class_name = st.nextToken() ;
Class c = ijc.ValidateClass(class_name) ;
@@ -588,11 +172,12 @@ class InlineJavaProtocol {
}
catch (InlineJavaInvocationTargetException ite){
Throwable t = ite.GetThrowable() ;
- if (t instanceof InlineJavaPerlCaller.InlineJavaException){
- throw ((InlineJavaPerlCaller.InlineJavaException)t).GetException() ;
+ if (t instanceof InlineJavaException){
+ InlineJavaException ije = (InlineJavaException)t ;
+ throw ije ;
}
else{
- SetResponse(new InlineJavaServerThrown(t)) ;
+ SetResponse(new InlineJavaThrown(t)) ;
}
}
}
@@ -612,7 +197,7 @@ class InlineJavaProtocol {
Class ec = ijc.ValidateClass(sb.toString()) ;
- ijs.debug(4, "array elements: " + ec.getName()) ;
+ InlineJavaUtils.debug(4, "array elements: " + ec.getName()) ;
Object o = ija.CreateArray(ec, st) ;
SetResponse(o) ;
}
@@ -661,12 +246,13 @@ class InlineJavaProtocol {
Throwable t = e.getTargetException() ;
String type = t.getClass().getName() ;
String msg = t.getMessage() ;
- ijs.debug(1, "method " + name + " in class " + class_name + " threw exception " + type + ": " + msg) ;
- if (t instanceof InlineJavaPerlCaller.InlineJavaException){
- throw ((InlineJavaPerlCaller.InlineJavaException)t).GetException() ;
+ InlineJavaUtils.debug(1, "method " + name + " in class " + class_name + " threw exception " + type + ": " + msg) ;
+ if (t instanceof InlineJavaException){
+ InlineJavaException ije = (InlineJavaException)t ;
+ throw ije ;
}
else{
- SetResponse(new InlineJavaServerThrown(t)) ;
+ SetResponse(new InlineJavaThrown(t)) ;
}
}
}
@@ -801,23 +387,23 @@ class InlineJavaProtocol {
}
}
catch (NoSuchMethodException e){
- throw new InlineJavaException("Constructor for class " + name + " with signature " + ijs.CreateSignature(proto) + " not found: " + e.getMessage()) ;
+ throw new InlineJavaException("Constructor for class " + name + " with signature " + InlineJavaUtils.CreateSignature(proto) + " not found: " + e.getMessage()) ;
}
catch (InstantiationException e){
throw new InlineJavaException("You are not allowed to instantiate object of class " + name + ": " + e.getMessage()) ;
}
catch (IllegalAccessException e){
- throw new InlineJavaException("You are not allowed to instantiate object of class " + name + " using the constructor with signature " + ijs.CreateSignature(proto) + ": " + e.getMessage()) ;
+ throw new InlineJavaException("You are not allowed to instantiate object of class " + name + " using the constructor with signature " + InlineJavaUtils.CreateSignature(proto) + ": " + e.getMessage()) ;
}
catch (IllegalArgumentException e){
- throw new InlineJavaException("Arguments to constructor for class " + name + " with signature " + ijs.CreateSignature(proto) + " are incompatible: " + e.getMessage()) ;
+ throw new InlineJavaException("Arguments to constructor for class " + name + " with signature " + InlineJavaUtils.CreateSignature(proto) + " are incompatible: " + e.getMessage()) ;
}
catch (InvocationTargetException e){
Throwable t = e.getTargetException() ;
String type = t.getClass().getName() ;
String msg = t.getMessage() ;
throw new InlineJavaInvocationTargetException(
- "Constructor for class " + name + " with signature " + ijs.CreateSignature(proto) + " threw exception " + type + ": " + msg,
+ "Constructor for class " + name + " with signature " + InlineJavaUtils.CreateSignature(proto) + " threw exception " + type + ": " + msg,
t) ;
}
@@ -847,7 +433,7 @@ class InlineJavaProtocol {
Member m = ma[i] ;
if (m.getName().equals(name)){
- ijs.debug(3, "found a " + name + (constructor ? " constructor" : " method")) ;
+ InlineJavaUtils.debug(3, "found a " + name + (constructor ? " constructor" : " method")) ;
if (constructor){
params = ((Constructor)m).getParameterTypes() ;
@@ -857,11 +443,11 @@ class InlineJavaProtocol {
}
// Now we check if the signatures match
- String sign = ijs.CreateSignature(params, ",") ;
- ijs.debug(3, sign + " = " + signature + "?") ;
+ String sign = InlineJavaUtils.CreateSignature(params, ",") ;
+ InlineJavaUtils.debug(3, sign + " = " + signature + "?") ;
if (signature.equals(sign)){
- ijs.debug(3, "has matching signature " + sign) ;
+ InlineJavaUtils.debug(3, "has matching signature " + sign) ;
ml.add(ml.size(), m) ;
break ;
}
@@ -929,15 +515,15 @@ class InlineJavaProtocol {
ArrayList fl = new ArrayList(fa.length) ;
Class param = null ;
for (int i = 0 ; i < fa.length ; i++){
- Field f = fa[(ijs.reverse_members() ? (fa.length - 1 - i) : i)] ;
+ Field f = fa[(InlineJavaUtils.ReverseMembers() ? (fa.length - 1 - i) : i)] ;
if (f.getName().equals(name)){
- ijs.debug(3, "found a " + name + " member") ;
+ InlineJavaUtils.debug(3, "found a " + name + " member") ;
param = f.getType() ;
String t = param.getName() ;
if (type.equals(t)){
- ijs.debug(3, "has matching type " + t) ;
+ InlineJavaUtils.debug(3, "has matching type " + t) ;
fl.add(fl.size(), f) ;
}
}
@@ -991,30 +577,28 @@ class InlineJavaProtocol {
return "undef:" ;
}
else if ((ijc.ClassIsNumeric(o.getClass()))||(ijc.ClassIsChar(o.getClass()))||(ijc.ClassIsString(o.getClass()))){
- return "scalar:" + encode(o.toString()) ;
+ return "scalar:" + Encode(o.toString()) ;
}
else if (ijc.ClassIsBool(o.getClass())){
String b = o.toString() ;
- return "scalar:" + encode((b.equals("true") ? "1" : "0")) ;
+ return "scalar:" + Encode((b.equals("true") ? "1" : "0")) ;
}
else {
// Here we need to register the object in order to send
// it back to the Perl script.
boolean thrown = false ;
- if (o instanceof InlineJavaServerThrown){
+ if (o instanceof InlineJavaThrown){
thrown = true ;
- o = ((InlineJavaServerThrown)o).GetThrowable() ;
+ o = ((InlineJavaThrown)o).GetThrowable() ;
}
- int id = ijs.objid ;
- ijs.PutObject(id, o) ;
+ int id = ijs.PutObject(o) ;
return "object:" + (thrown ? "1" : "0") + ":" + String.valueOf(id) +
":" + o.getClass().getName() ;
}
}
-
- public String decode(String s){
+ String Decode(String s){
StringTokenizer st = new StringTokenizer(s, ".") ;
StringBuffer sb = new StringBuffer() ;
while (st.hasMoreTokens()){
@@ -1027,7 +611,7 @@ class InlineJavaProtocol {
}
- public String encode(String s){
+ String Encode(String s){
byte b[] = s.getBytes() ;
StringBuffer sb = new StringBuffer() ;
for (int i = 0 ; i < b.length ; i++){
@@ -1039,5 +623,9 @@ class InlineJavaProtocol {
return sb.toString() ;
}
-}
+
+ String GetResponse(){
+ return response ;
+ }
+}
diff --git a/Java/sources/InlineJavaServer.java b/Java/sources/InlineJavaServer.java
new file mode 100644
index 0000000..da1b0ff
--- /dev/null
+++ b/Java/sources/InlineJavaServer.java
@@ -0,0 +1,288 @@
+import java.net.* ;
+import java.io.* ;
+import java.util.* ;
+
+
+/*
+ This is the server that will answer all the requests for and on Java
+ objects.
+*/
+public class InlineJavaServer {
+ static InlineJavaServer instance = null ;
+ private int port = 0 ;
+ private boolean shared_jvm = false ;
+
+
+ private InlineJavaUserClassLoader ijucl = null ;
+ private HashMap thread_objects = new HashMap() ;
+ private int objid = 1 ;
+
+
+ // This constructor is used in JNI mode
+ public InlineJavaServer(int d){
+ init(d) ;
+
+ thread_objects.put(Thread.currentThread().getName(), new HashMap()) ;
+ }
+
+
+ // This constructor is used in server mode
+ public InlineJavaServer(String[] argv){
+ init(new Integer(argv[1]).intValue()) ;
+
+ port = Integer.parseInt(argv[2]) ;
+ shared_jvm = new Boolean(argv[3]).booleanValue() ;
+
+ ServerSocket ss = null ;
+ try {
+ ss = new ServerSocket(port) ;
+ }
+ catch (IOException e){
+ System.err.println("Can't open server socket on port " + String.valueOf(port) +
+ ": " + e.getMessage()) ;
+ System.err.flush() ;
+ System.exit(1) ;
+ }
+
+ while (true){
+ try {
+ InlineJavaServerThread ijt = new InlineJavaServerThread(this, ss.accept()) ;
+ ijt.start() ;
+ if (! shared_jvm){
+ try {
+ ijt.join() ;
+ }
+ catch (InterruptedException e){
+ }
+ break ;
+ }
+ }
+ catch (IOException e){
+ System.err.println("IO error: " + e.getMessage()) ;
+ System.err.flush() ;
+ }
+ }
+
+ System.exit(1) ;
+ }
+
+
+ private void init(int debug){
+ instance = this ;
+ InlineJavaUtils.debug = debug ;
+
+ ijucl = new InlineJavaUserClassLoader() ;
+ }
+
+
+ String GetType(){
+ return (shared_jvm ? "shared" : "private") ;
+ }
+
+
+ /*
+ Since this function is also called from the JNI XS extension,
+ it's best if it doesn't throw any exceptions.
+ It is public only for testing purposes.
+ */
+ String ProcessCommand(String cmd) {
+ return ProcessCommand(cmd, true) ;
+ }
+
+
+ private String ProcessCommand(String cmd, boolean addlf) {
+ InlineJavaUtils.debug(3, "packet recv is " + cmd) ;
+
+ String resp = null ;
+ if (cmd != null){
+ InlineJavaProtocol ijp = new InlineJavaProtocol(this, cmd) ;
+ try {
+ ijp.Do() ;
+ InlineJavaUtils.debug(3, "packet sent is " + ijp.GetResponse()) ;
+ resp = ijp.GetResponse() ;
+ }
+ catch (InlineJavaException e){
+ String err = "error scalar:" + ijp.Encode(e.getMessage()) ;
+ InlineJavaUtils.debug(3, "packet sent is " + err) ;
+ resp = err ;
+ }
+ }
+ else{
+ if (! shared_jvm){
+ // Probably connection dropped...
+ InlineJavaUtils.debug(1, "lost connection with client in single client mode. Exiting.") ;
+ System.exit(1) ;
+ }
+ else{
+ InlineJavaUtils.debug(1, "lost connection with client in shared JVM mode.") ;
+ return null ;
+ }
+ }
+
+ if (addlf){
+ resp = resp + "\n" ;
+ }
+
+ return resp ;
+ }
+
+
+ Object GetObject(int id) throws InlineJavaException {
+ Object o = null ;
+ String name = Thread.currentThread().getName() ;
+ HashMap h = (HashMap)thread_objects.get(name) ;
+
+ if (h == null){
+ throw new InlineJavaException("Can't find thread " + name + "!") ;
+ }
+ else{
+ o = h.get(new Integer(id)) ;
+ if (o == null){
+ throw new InlineJavaException("Can't find object " + id + " for thread " + name) ;
+ }
+ }
+
+ return o ;
+ }
+
+
+ synchronized int PutObject(Object o) throws InlineJavaException {
+ String name = Thread.currentThread().getName() ;
+ HashMap h = (HashMap)thread_objects.get(name) ;
+
+ int id = objid ;
+ if (h == null){
+ throw new InlineJavaException("Can't find thread " + name + "!") ;
+ }
+ else{
+ h.put(new Integer(objid), o) ;
+ objid++ ;
+ }
+
+ return id ;
+ }
+
+
+ Object DeleteObject(int id) throws InlineJavaException {
+ Object o = null ;
+ String name = Thread.currentThread().getName() ;
+ HashMap h = (HashMap)thread_objects.get(name) ;
+
+ if (h == null){
+ throw new InlineJavaException("Can't find thread " + name + "!") ;
+ }
+ else{
+ o = h.remove(new Integer(id)) ;
+ if (o == null){
+ throw new InlineJavaException("Can't find object " + id + " for thread " + name) ;
+ }
+ }
+
+ return o ;
+ }
+
+
+ int ObjectCount() throws InlineJavaException {
+ int i = -1 ;
+ String name = Thread.currentThread().getName() ;
+ HashMap h = (HashMap)thread_objects.get(name) ;
+
+ if (h == null){
+ throw new InlineJavaException("Can't find thread " + name + "!") ;
+ }
+ else{
+ i = h.values().size() ;
+ }
+
+ return i ;
+ }
+
+
+ Object Callback(String pkg, String method, Object args[], String cast) throws InlineJavaException, InlineJavaPerlException {
+ Object ret = null ;
+
+ try {
+ InlineJavaProtocol ijp = new InlineJavaProtocol(this, null) ;
+ InlineJavaClass ijc = new InlineJavaClass(this, ijp) ;
+ StringBuffer cmdb = new StringBuffer("callback " + pkg + " " + method + " " + cast) ;
+ if (args != null){
+ for (int i = 0 ; i < args.length ; i++){
+ cmdb.append(" " + ijp.SerializeObject(args[i])) ;
+ }
+ }
+ String cmd = cmdb.toString() ;
+ InlineJavaUtils.debug(2, "callback command: " + cmd) ;
+
+ Thread t = Thread.currentThread() ;
+ String resp = null ;
+ while (true) {
+ InlineJavaUtils.debug(3, "packet sent (callback) is " + cmd) ;
+ if (t instanceof InlineJavaServerThread){
+ // Client-server mode
+ InlineJavaServerThread ijt = (InlineJavaServerThread)t ;
+ ijt.bw.write(cmd + "\n") ;
+ ijt.bw.flush() ;
+
+ resp = ijt.br.readLine() ;
+ }
+ else{
+ // JNI mode
+ resp = jni_callback(cmd) ;
+ }
+ InlineJavaUtils.debug(3, "packet recv (callback) is " + resp) ;
+
+ StringTokenizer st = new StringTokenizer(resp, " ") ;
+ String c = st.nextToken() ;
+ if (c.equals("callback")){
+ boolean thrown = new Boolean(st.nextToken()).booleanValue() ;
+ String arg = st.nextToken() ;
+ ret = ijc.CastArgument(java.lang.Object.class, arg) ;
+
+ if (thrown){
+ throw new InlineJavaPerlException(ret) ;
+ }
+
+ break ;
+ }
+ else{
+ // Pass it on through the regular channel...
+ InlineJavaUtils.debug(3, "packet is not callback response: " + resp) ;
+ cmd = ProcessCommand(resp, false) ;
+
+ continue ;
+ }
+ }
+ }
+ catch (IOException e){
+ throw new InlineJavaException("IO error: " + e.getMessage()) ;
+ }
+
+ return ret ;
+ }
+
+
+ native private String jni_callback(String cmd) ;
+
+
+ void AddThread(String name){
+ thread_objects.put(name, new HashMap()) ;
+ }
+
+
+ void RemoveThread(String name){
+ thread_objects.remove(name) ;
+ }
+
+
+ /*
+ Startup
+ */
+ public static void main(String[] argv){
+ new InlineJavaServer(argv) ;
+ }
+
+
+ public static InlineJavaServer jni_main(int debug){
+ return new InlineJavaServer(debug) ;
+ }
+}
diff --git a/Java/sources/InlineJavaServerThread.java b/Java/sources/InlineJavaServerThread.java
new file mode 100644
index 0000000..9a524eb
--- /dev/null
+++ b/Java/sources/InlineJavaServerThread.java
@@ -0,0 +1,48 @@
+import java.io.* ;
+import java.net.* ;
+import java.util.* ;
+
+
+class InlineJavaServerThread extends Thread {
+ InlineJavaServer ijs ;
+ Socket client ;
+ BufferedReader br ;
+ BufferedWriter bw ;
+
+ InlineJavaServerThread(InlineJavaServer _ijs, Socket _client) throws IOException {
+ super() ;
+ client = _client ;
+ ijs = _ijs ;
+
+ br = new BufferedReader(
+ new InputStreamReader(client.getInputStream())) ;
+ bw = new BufferedWriter(
+ new OutputStreamWriter(client.getOutputStream())) ;
+ }
+
+
+ public void run(){
+ try {
+ ijs.AddThread(getName()) ;
+
+ while (true){
+ String cmd = br.readLine() ;
+
+ String resp = ijs.ProcessCommand(cmd) ;
+ if (resp != null){
+ bw.write(resp) ;
+ bw.flush() ;
+ }
+ else {
+ break ;
+ }
+ }
+ }
+ catch (IOException e){
+ System.err.println("IO error: " + e.getMessage()) ;
+ }
+ finally {
+ ijs.RemoveThread(getName()) ;
+ }
+ }
+}
diff --git a/Java/sources/InlineJavaTest.java b/Java/sources/InlineJavaTest.java
new file mode 100644
index 0000000..16f27ae
--- /dev/null
+++ b/Java/sources/InlineJavaTest.java
@@ -0,0 +1,8 @@
+class InlineJavaTest {
+ public static void main(String[] args){
+ InlineJavaServer ijs = InlineJavaServer.jni_main(5) ;
+ String resp = ijs.ProcessCommand("server_type") ;
+
+ System.out.println(resp) ;
+ }
+}
diff --git a/Java/sources/InlineJavaThrown.java b/Java/sources/InlineJavaThrown.java
new file mode 100644
index 0000000..92f88bd
--- /dev/null
+++ b/Java/sources/InlineJavaThrown.java
@@ -0,0 +1,11 @@
+class InlineJavaThrown {
+ Throwable t = null ;
+
+ InlineJavaThrown(Throwable _t){
+ t = _t ;
+ }
+
+ Throwable GetThrowable(){
+ return t ;
+ }
+}
diff --git a/Java/sources/InlineJavaUserClassLoader.java b/Java/sources/InlineJavaUserClassLoader.java
new file mode 100644
index 0000000..b8e4f88
--- /dev/null
+++ b/Java/sources/InlineJavaUserClassLoader.java
@@ -0,0 +1,20 @@
+import java.net.* ;
+import java.util.* ;
+
+
+public class InlineJavaUserClassLoader extends URLClassLoader {
+ private HashMap urls = new HashMap() ;
+
+
+ public InlineJavaUserClassLoader(){
+ super(new URL [] {}) ;
+ }
+
+
+ public void AddPath(URL u){
+ if (urls.get(u) == null){
+ urls.put(u, "1") ;
+ addURL(u) ;
+ }
+ }
+}
diff --git a/Java/sources/InlineJavaUtils.java b/Java/sources/InlineJavaUtils.java
new file mode 100644
index 0000000..7d2173a
--- /dev/null
+++ b/Java/sources/InlineJavaUtils.java
@@ -0,0 +1,47 @@
+import java.util.* ;
+
+
+/*
+ Creates a string representing a method signature
+*/
+class InlineJavaUtils {
+ static int debug = 0 ;
+
+
+ static String CreateSignature(Class param[]){
+ return CreateSignature(param, ", ") ;
+ }
+
+
+ static String CreateSignature(Class param[], String del){
+ StringBuffer ret = new StringBuffer() ;
+ for (int i = 0 ; i < param.length ; i++){
+ if (i > 0){
+ ret.append(del) ;
+ }
+ ret.append(param[i].getName()) ;
+ }
+
+ return "(" + ret.toString() + ")" ;
+ }
+
+
+ synchronized static void debug(int level, String s) {
+ if ((debug > 0)&&(debug >= level)){
+ StringBuffer sb = new StringBuffer() ;
+ for (int i = 0 ; i < level ; i++){
+ sb.append(" ") ;
+ }
+ System.err.println("[java][" + level + "]" + sb.toString() + s) ;
+ System.err.flush() ;
+ }
+ }
+
+
+ static boolean ReverseMembers() {
+ String v = System.getProperty("java.version") ;
+ boolean no_rev = ((v.startsWith("1.2"))||(v.startsWith("1.3"))) ;
+
+ return (! no_rev) ;
+ }
+}
diff --git a/MANIFEST b/MANIFEST
index df3ff11..0e9445a 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -6,7 +6,6 @@ TODO
Makefile.PL
Java.pm
Java.pod
-Java/Init.pm
Java/Object.pm
Java/Protocol.pm
Java/Class.pm
diff --git a/Makefile.PL b/Makefile.PL
index 3d80d06..637291f 100644
--- a/Makefile.PL
+++ b/Makefile.PL
@@ -1,26 +1,137 @@
use ExtUtils::MakeMaker ;
+# $Verbose = 2 ;
use strict ;
use File::Spec ;
+use Config ;
require "Java/Portable.pm" ;
-# Replace everything just like out-of-the-box...
-my $xs = File::Spec->catfile("Java", "JNI.xs") ;
-rename($xs . "_", "$xs") ;
-
print "\nWelcome to the Inline::Java installation procedure.\n\n" ;
+# Grab the J2SDK argument
+my @new_args = () ;
+my $jdk_dir = '' ;
+foreach my $arg (@ARGV){
+ if ($arg =~ /^J2SDK=(.+)$/){
+ $jdk_dir = $1 ;
+ }
+ else {
+ push @new_args, $_ ;
+ }
+}
+ at ARGV = @new_args ;
+
+if (! $jdk_dir){
+ print <<NO_J2SDK;
+A Java 2 SDK is required to install and use Inline::Java. Please
+specify your Java 2 SDK installation directory using the J2SDK
+option to Makefile.PL as such:
+
+ perl Makefile.PL J2SDK=/path/to/your/j2sdk/installation
+NO_J2SDK
+ exit(1) ;
+}
+elsif (! -d $jdk_dir){
+ print <<BAD_J2SDK;
+Java 2 SDK installation directory '$jdk_dir' does not exist.
+BAD_J2SDK
+ exit(1) ;
+}
+my $perl_jdk_dir = $jdk_dir ;
+$perl_jdk_dir =~ s/'/\'/g ;
+
+# Check directory
+my $ext = Inline::Java::Portable::portable('EXE_EXTENSION') ;
+foreach my $f ('javac', 'jar', 'java'){
+ if (! -x File::Spec->catfile($jdk_dir, 'bin', $f . $ext)){
+ my $bf = File::Spec->catfile('bin', $f . $ext) ;
+ print "Can't locate file '$bf' anywhere under '$jdk_dir'\n" ;
+ }
+}
+
+
+# Now we have the J2SDK directory and it exists.
+# We will create the DefaultJ2SDK.pl file that
+# will contain that value for future use.
+my $def_jdk = File::Spec->catfile('Java', 'DefaultJ2SDK.pl') ;
+open(J2SDK, ">$def_jdk") or
+ die("Can't open '$def_jdk' for writing: $!") ;
+print J2SDK <<J2SDK_PL;
+# This file is created by the Makefile.PL for Inline::Java
+# You can modify it if you which
+use strict ;
+
+# The default J2SDK to use for Inline::Java. You can change
+# it if this value becomes invalid.
+sub Inline::Java::get_default_j2sdk {
+ return '$perl_jdk_dir' ;
+}
+
+1 ;
+J2SDK_PL
+close(J2SDK) ;
+
+my $ij_site_lib = File::Spec->catdir($Config{installsitelib}, 'Inline', 'Java') ;
+print <<SAVE_J2SDK;
+Default J2SDK for Inline:Java will be '$jdk_dir'.
+See module documentation for information on how to use a different J2SDK
+or change this default value.
+
+SAVE_J2SDK
+
+
+# We will now add the building of our Java files to the Makefile.
+my $javac = File::Spec->catfile($jdk_dir, 'bin', 'javac' . $ext) ;
+my $jar = File::Spec->catfile($jdk_dir, 'bin', 'jar' . $ext) ;
+my $src_dir = File::Spec->catdir('Java', 'sources') ;
+my $src = File::Spec->catfile($src_dir, '*.java') ;
+my $obj_dir = File::Spec->catdir('Java', 'classes') ;
+my $arch_dir = File::Spec->catdir('Java', 'jar') ;
+my $arch = File::Spec->catfile($arch_dir, 'InlineJava.jar') ;
+
+sub MY::postamble {
+ <<MAKE;
+pure_all :: java
+
+java ::
+ \@\$(MKPATH) $obj_dir
+ \@\$(MKPATH) $arch_dir
+ "$javac" -d $obj_dir $src
+ "$jar" cf $arch -C $obj_dir .
+MAKE
+}
+
+
+# Skip the tests for the Java directory
+sub MY::test {
+ my $this = shift ;
+
+ my $hold = delete $this->{DIR} ;
+ my $ret = $this->MM::test(@_) ;
+ $this->{DIR} = $hold if defined($hold) ;
+ return $ret ;
+}
+
+
+# Write the Makefile
WriteMakefile(
NAME => 'Inline::Java',
VERSION_FROM => 'Java.pm',
+ DIR => ['Java'],
PREREQ_PM => {
Inline => 0.44
},
- clean => {FILES => '_Inline_test/'},
+ PM => {
+ 'Java.pm' => File::Spec->catfile('$(INST_LIBDIR)', 'Java.pm'),
+ 'Java.pod'=> File::Spec->catfile('$(INST_LIBDIR)', 'Java.pod'),
+ $arch => File::Spec->catfile('$(INST_LIBDIR)', $arch),
+ },
+ clean => {FILES => "$def_jdk _Inline_test $obj_dir $arch_dir"},
) ;
+# Clean up the Makefile for Win95/98/Me
if (Inline::Java::Portable::portable('COMMAND_COM')){
print "\nFixing Makefile for Win95/98/Me...\n" ;
open(MAKEFILE, "<Makefile") or die "Can't open Makefile for reading" ;
diff --git a/TODO b/TODO
index 0c8dd4b..0922b1c 100644
--- a/TODO
+++ b/TODO
@@ -1,4 +1,8 @@
CODE:
+- Implement AddClassPath
+- Change BIN to J2SDK
+- Fix makfile.PL to build at install time, create jar and config file
+- Fix environment variables
TEST:
- Alpha
diff --git a/t/01_init.t b/t/01_init.t
index 4cdc2ae..6c0a978 100644
--- a/t/01_init.t
+++ b/t/01_init.t
@@ -13,11 +13,13 @@ use Inline (
Java => 'DATA'
) ;
-
+my $mod = (Inline::Java::get_INLINE_modules())[0] ;
+my $ij = Inline::Java::get_INLINE($mod) ;
+my $jdk = $ij->get_java_config("J2SDK") ;
my $ver = types1->version() ;
print STDERR "\nInline version is $Inline::VERSION\n" ;
print STDERR "Inline::Java version is $Inline::Java::VERSION\n" ;
-print STDERR "J2SDK version is $ver\n" ;
+print STDERR "J2SDK version is $ver, from $jdk\n" ;
if ($ENV{PERL_INLINE_JAVA_EMBEDDED_JNI}){
print STDERR "Using JNI extension (embedded).\n" ;
diff --git a/t/no_const.class b/t/no_const.class
index 98ea5ef..79d98bc 100644
Binary files a/t/no_const.class and b/t/no_const.class differ
diff --git a/t/types.class b/t/types.class
index 918c408..fc9e393 100644
Binary files a/t/types.class and b/t/types.class differ
--
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