summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSam Ruby <rubys@php.net>1999-11-09 12:02:22 +0000
committerSam Ruby <rubys@php.net>1999-11-09 12:02:22 +0000
commitd17a12319f3fabff41884b1e578f331a88f80f83 (patch)
treec0a7b87e2b7c96a8aab7a2ed96b1bdc75f247928
parent60766eff5a356954c1d036bfb8341a56063b2251 (diff)
downloadphp-git-d17a12319f3fabff41884b1e578f331a88f80f83.tar.gz
@ Added Zend OO syntax overloading support for Java components
# # My lawyer made me do this: # Users of PHP are hereby granted a non-exclusive, irrevocable, world-wide, royalty-free, non-transferable license to use, execute, prepare derivative works of, and distribute (internally and externally, and including derivative works) the code accompanying this license as part of, and integrated into PHP. WARRANTY OF ANY KIND EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTY OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY WARRANTY OF NON-INFRINGEMENT. THE ENTIRE RISK ARISING OUT OF THE USE OR PERFORMANCE OF THIS CODE REMAINS WITH USERS OF PHP. The owner of this code represents and warrants that it is legally entitled to grant the above license.
-rw-r--r--ext/java/Makefile.am24
-rw-r--r--ext/java/README132
-rw-r--r--ext/java/config.h.stub3
-rw-r--r--ext/java/config.m459
-rw-r--r--ext/java/java.c518
-rw-r--r--ext/java/java.dsp254
-rw-r--r--ext/java/jawt.php28
-rw-r--r--ext/java/jver.php15
-rw-r--r--ext/java/reflect.java186
-rw-r--r--ext/rpc/Makefile.am24
-rw-r--r--ext/rpc/config.h.stub3
-rw-r--r--ext/rpc/java/Makefile.am24
-rw-r--r--ext/rpc/java/README132
-rw-r--r--ext/rpc/java/config.h.stub3
-rw-r--r--ext/rpc/java/config.m459
-rw-r--r--ext/rpc/java/java.c518
-rw-r--r--ext/rpc/java/java.dsp254
-rw-r--r--ext/rpc/java/jawt.php28
-rw-r--r--ext/rpc/java/jver.php15
-rw-r--r--ext/rpc/java/reflect.java186
20 files changed, 2465 insertions, 0 deletions
diff --git a/ext/java/Makefile.am b/ext/java/Makefile.am
new file mode 100644
index 0000000000..95196a49be
--- /dev/null
+++ b/ext/java/Makefile.am
@@ -0,0 +1,24 @@
+# $Id$
+
+SRC=java.c
+
+CFLAGS=@CFLAGS@ @JAVA_CFLAGS@
+INCLUDES=@INCLUDES@ @JAVA_INCLUDE@ -I@top_srcdir@ -I@top_srcdir@/libzend
+EXTRA_LTLIBRARIES=libphp_java.la
+phplib_LTLIBRARIES=@JAVA_SHARED@
+libphp_java_la_SOURCES=$(SRC)
+libphp_java_la_LIBADD=@JAVA_LFLAGS@
+libphp_java_la_LDFLAGS=-avoid-version -module -rpath $(phplibdir)
+EXTRA_LIBS=
+
+phplib_DATA=php_java.jar
+php_java.jar : reflect.java
+ @test -e net || mkdir net
+ @test -e net/php || mkdir net/php
+ @cp reflect.java net/php
+ javac net/php/reflect.java
+ @test ! -f reflect.class || mv reflect.class net/php # bug in KJC javac
+ zip -q0 php_java.jar net/php/*.class
+ @rm net/php/reflect.*
+ @rmdir net/php
+ @rmdir net
diff --git a/ext/java/README b/ext/java/README
new file mode 100644
index 0000000000..d873fe75a2
--- /dev/null
+++ b/ext/java/README
@@ -0,0 +1,132 @@
+What is PHP4 ext/java?
+
+ PHP4 ext/java provides a simple and effective means for creating and
+ invoking methods on Java objects from PHP. The JVM is created using JNI,
+ and everthing runs in-process.
+
+ Two examples are provided, jver and jawt, to illustrate usage of this
+ extension. A few things to note:
+
+ 1) new Java() will create an instance of a class if a suitable constructor
+ is available. If no parameters are passed and the default constructor
+ is private, then an instance of the class is returned instead. This
+ is useful as it provides access to classes like "java.lang.system"
+ which expose most of their functionallity through static methods.
+
+ 2) Accessing a member of an instance will first look for bean properties
+ then public fields. In other words, "print $date.time" will first
+ attempt to be resolved as "$date.getTime()", then as "$date.time";
+
+ 3) Both static and instance members can be accessed on an object with
+ the same syntax. Furthermore, if the java object is of type
+ "java.lang.Class", then static members
+
+ 4) Exceptions raised result in PHP warnings, and null results.
+
+ 5) Overload resolution is in general a hard problem given the
+ differences in types between the two languages. This being said,
+ the current support is pretty lame and I intend to improve it.
+ The current algorithm is to pick the first method with the right
+ name (ignoring case!) and number of parameters - I warned you it
+ was lame!
+
+Build and execution instructions:
+
+ Given the number of platforms and providers of JVMs, no single set of
+ instructions will be able to cover all cases. So in place of hard and
+ fast instructions, below are a working examples for a number of free and
+ commercial implementations and platforms. Please adjust the paths to
+ suit your installation. Also, if you happen to get this to work on
+ another JVM/platform combination, please let me know, particularly if
+ a unique build or execution setup was required.
+
+ This function has been tested in both CGI and Apache (apxs) modes. As
+ the current design requires shared libraries, this support can not be
+ linked statically into Apache.
+
+ Finally, it is worth noting that no JVMs are created until the first
+ Java call is made. This not only eliminates unnecessary overhead if
+ the extension is never used, it also provides error messages directly
+ back to the user instead of being burried in a log some place.
+ Additionally, on Unix, the loading of the shared library which implements
+ the JVM is also deferred until first use.
+
+========================================================================
+=== JVM=Kaffe 1.0.4 (as delivered with OS), OS=Redhat Linux 6.1 ===
+========================================================================
+
+build instructions:
+
+ ./configure --with-java
+
+php.ini:
+
+ [java]
+ java.library=/usr/lib/kaffe/libkaffevm.so
+ java.library.path=/usr/lib/kaffe:/home/rubys/php4/modules
+ java.class.path=/usr/share/kaffe/Klasses.jar:/home/rubys/php4/modules/php_java.jar
+ extension_dir=/home/rubys/php4/modules
+ extension=libphp_java.so
+
+========================================================================
+=== JVM=Kaffe 1.0.5 (built from source), OS=Redhat Linux 6.1 ===
+========================================================================
+
+build instructions:
+
+ ./configure --with-java
+
+php.ini:
+
+ [java]
+ java.library=/usr/local/lib/libkaffevm.so
+ java.library.path=/usr/local/lib/kaffe:/home/rubys/php4/modules
+ java.class.path=/usr/local/share/kaffe/Klasses.jar:/home/rubys/php4/modules/php_java.jar
+ extension_dir=/home/rubys/php4/modules
+ extension=libphp_java.so
+
+========================================================================
+=== JVM=IBM 1.1.8, OS=Redhat Linux 6.1 ===
+========================================================================
+
+build instructions:
+
+ ./configure --with-java=/home/jdk118
+
+php.ini:
+
+ [java]
+ java.library=/home/jdk118/lib/linux/native_threads/libjava.so
+ java.class.path=/home/jdk118/lib/classes.zip:/home/rubys/php4/modules/php_java.jar
+ extension_dir=/home/rubys/php4/modules
+ extension=libphp_java.so
+
+========================================================================
+=== JVM=Sun JDK 1.1.8, OS=Windows NT 4 ===
+========================================================================
+
+build instructions:
+
+ SET JAVA_HOME=D:\jdk1.1.8
+ msdev ext\java\java.dsp /MAKE "java - Win32 Debug_TS"
+
+php.ini:
+
+ [java]
+ java.class.path="D:\jdk1.1.8\lib\classes.zip;F:\PHP4\Debug_TS\php_java.jar"
+ extension=php_java.dll
+
+========================================================================
+=== JVM=Sun JDK 1.2.2, OS=Windows NT 4 ===
+========================================================================
+
+build instructions:
+
+ SET JAVA_HOME=D:\jdk1.2.2
+ msdev ext\java\java.dsp /MAKE "java - Win32 Debug_TS"
+
+php.ini:
+
+ [java]
+ java.class.path=F:\PHP4\Debug_TS\php_java.jar
+ extension=php_java.dll
diff --git a/ext/java/config.h.stub b/ext/java/config.h.stub
new file mode 100644
index 0000000000..737d5d39ff
--- /dev/null
+++ b/ext/java/config.h.stub
@@ -0,0 +1,3 @@
+#ifndef HAVE_JAVA
+#define HAVE_JAVA 0
+#endif
diff --git a/ext/java/config.m4 b/ext/java/config.m4
new file mode 100644
index 0000000000..d0a955b680
--- /dev/null
+++ b/ext/java/config.m4
@@ -0,0 +1,59 @@
+# $Id$
+# config.m4 for extension java
+
+AC_MSG_CHECKING(for Java support)
+AC_ARG_WITH(java,
+[ --with-java[=DIR] Include Java support. DIR is the base install
+ directory for the JDK. This extension can only
+ be built as a shared dl.],
+[
+ if test "$withval" != "no"; then
+ JAVA_SHARED="libphp_java.la"
+
+ if test "$withval" = "yes"; then
+ if test -d /usr/local/lib/kaffe; then
+ JAVA_CFLAGS="-DKAFFE"
+ JAVA_INCLUDE=-I/usr/local/include/kaffe
+ elif test -d /usr/lib/kaffe; then
+ JAVA_CFLAGS="-DKAFFE"
+ JAVA_INCLUDE=-I/usr/include/kaffe
+ else
+ AC_MSG_RESULT(no)
+ AC_MSG_ERROR(unable to find Java VM libraries)
+ fi
+ else
+ if test -f $withval/lib/libjava.so; then
+ JAVA_INCLUDE="-I$withval/include"
+ test -f $withval/lib/classes.zip && JAVA_CFLAGS="-DJNI_11"
+ test -f $withval/lib/jvm.jar && JAVA_CFLAGS="-DJNI_12"
+ for i in $JAVA_INCLUDE/*; do
+ test -f $i/jni_md.h && JAVA_INCLUDE="$JAVA_INCLUDE $i"
+ done
+ else
+ for i in `find $withval -type d`; do
+ test -f $i/jni.h && JAVA_INCLUDE="-I$i"
+ test -f $i/jni_md.h && JAVA_INCLUDE="$JAVA_INCLUDE -I$i"
+ test -f $i/classes.zip && JAVA_CFLAGS="-DJNI_11"
+ test -f $i/jvm.jar && JAVA_CFLAGS="-DJNI_12"
+ done
+ if test -z "$JAVA_INCLUDE"; then
+ AC_MSG_RESULT(no)
+ AC_MSG_ERROR(unable to find Java VM libraries)
+ fi
+ fi
+ fi
+
+ AC_DEFINE(HAVE_JAVA)
+ PHP_EXTENSION(java, "shared")
+ PHP_BUILD_SHARED
+ AC_MSG_RESULT(yes)
+ else
+ AC_MSG_RESULT(no)
+ fi
+],[
+ AC_MSG_RESULT(no)
+])
+
+AC_SUBST(JAVA_CFLAGS)
+AC_SUBST(JAVA_INCLUDE)
+AC_SUBST(JAVA_SHARED)
diff --git a/ext/java/java.c b/ext/java/java.c
new file mode 100644
index 0000000000..2c2aee1a9a
--- /dev/null
+++ b/ext/java/java.c
@@ -0,0 +1,518 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP version 4.0 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997, 1998, 1999 The PHP Group |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 2.0 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available at through the world-wide-web at |
+ | http://www.php.net/license.html. |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Author: Sam Ruby (rubys@us.ibm.com) |
+ +----------------------------------------------------------------------+
+ */
+
+/*
+ * This module implements Zend OO syntax overloading support for Java
+ * components using JNI and reflection.
+ */
+
+#include "dl/phpdl.h"
+
+#include "php.h"
+#include "zend_compile.h"
+#include "php_ini.h"
+#include "php_globals.h"
+
+#include <jni.h>
+
+#include <stdio.h>
+
+#define IS_EXCEPTION 86
+
+/***************************************************************************/
+
+#ifndef KAFFE
+#ifndef JNI_11
+#ifndef JNI_12
+
+#ifdef JNI_VERSION_1_2
+#define JNI_12
+#else
+#define JNI_11
+#endif
+
+#endif
+#endif
+#endif
+
+#if WIN32|WINNT
+#ifdef JNI_12
+#pragma comment(lib,"jvm.lib")
+#else
+#pragma comment(lib,"javai.lib")
+#endif
+#else
+static void *javadl = 0;
+#endif
+
+/***************************************************************************/
+
+static int le_jobject = 0;
+
+static char *javalib = 0;
+static char *classpath = 0;
+static char *libpath = 0;
+static char *javahome = 0;
+
+static int iniUpdated = 0;
+
+static JavaVM *jvm = 0;
+static JNIEnv *jenv = 0;
+static jclass php_reflect;
+
+static zend_class_entry java_class_entry;
+
+static PHP_INI_MH(OnIniUpdate) {
+ if (new_value) *(char**)mh_arg1 = new_value;
+ iniUpdated=1;
+ return SUCCESS;
+}
+
+PHP_INI_BEGIN()
+ PHP_INI_ENTRY1("java.class.path",
+ NULL, PHP_INI_ALL, OnIniUpdate, &classpath)
+ PHP_INI_ENTRY1("java.home",
+ NULL, PHP_INI_ALL, OnIniUpdate, &javahome)
+ PHP_INI_ENTRY1("java.library",
+ NULL, PHP_INI_ALL, OnIniUpdate, &javalib)
+ PHP_INI_ENTRY1("java.library.path",
+ NULL, PHP_INI_ALL, OnIniUpdate, &libpath)
+PHP_INI_END()
+
+/***************************************************************************/
+
+/*
+ * Destroy a Java Virtual Machine.
+ */
+void jvm_destroy() {
+ if (php_reflect) (*jenv)->DeleteGlobalRef(jenv, php_reflect);
+ if (jvm) (*jvm)->DestroyJavaVM(jvm);
+#if !(WIN32||WINNT)
+ if (javadl) dlclose(javadl);
+#endif
+ php_reflect = 0;
+ jvm = 0;
+ jenv = 0;
+}
+
+/*
+ * Create a Java Virtual Machine.
+ * - class.path, home, and library.path are read out of the INI file
+ * - appropriate (pre 1.1, JDK 1.1, and JDK 1.2) initialization is performed
+ * - net.php.reflect class file is located
+ */
+
+#ifdef JNI_12
+static void addJVMOption(JavaVMInitArgs *vm_args, char *name, char *value) {
+ char *option = (char*) malloc(strlen(name) + strlen(value) + 1);
+ strcpy(option, name);
+ strcat(option, value);
+ vm_args->options[vm_args->nOptions++].optionString = option;
+}
+#endif
+
+static int jvm_create() {
+
+ int rc;
+ jclass local_php_reflect;
+ jthrowable error;
+
+#ifdef JNI_11
+ JDK1_1InitArgs vm_args;
+#else
+ JavaVMInitArgs vm_args;
+#ifdef JNI_12
+ JavaVMOption options[3];
+#endif
+#endif
+
+ iniUpdated=0;
+
+ if (!classpath) classpath = getenv("CLASSPATH");
+
+#if !(WIN32||WINNT)
+ if (!libpath) libpath = getenv("LD_LIBRARY_PATH");
+ if (javalib) {
+ javadl = dlopen(javalib, RTLD_GLOBAL | RTLD_LAZY);
+ if (!javadl) {
+ php_error(E_ERROR, "Unable to create Java Virtual Machine");
+ return -1;
+ }
+ }
+#endif
+
+#ifdef JNI_12
+
+ vm_args.version = JNI_VERSION_1_2;
+ vm_args.ignoreUnrecognized = FALSE;
+ vm_args.options = options;
+ vm_args.nOptions = 0;
+
+ if (classpath) addJVMOption(&vm_args, "-Djava.class.path=", classpath);
+ if (javahome) addJVMOption(&vm_args, "-Djava.home=", javahome);
+ if (libpath) addJVMOption(&vm_args, "-Djava.library.path=", libpath);
+
+ rc = JNI_CreateJavaVM(&jvm, (void**)&jenv, &vm_args);
+
+#else
+
+ vm_args.version=0x00010001;
+ JNI_GetDefaultJavaVMInitArgs(&vm_args);
+
+ if (!classpath) classpath = "";
+ vm_args.classpath = classpath;
+#ifdef KAFFE
+ vm_args.classhome = javahome;
+ vm_args.libraryhome = libpath;
+#endif
+ rc = JNI_CreateJavaVM(&jvm, &jenv, &vm_args);
+
+#endif
+
+ if (rc) {
+ php_error(E_ERROR, "Unable to create Java Virtual Machine");
+ return rc;
+ }
+
+ local_php_reflect = (*jenv)->FindClass(jenv, "net/php/reflect");
+ error = (*jenv)->ExceptionOccurred(jenv);
+ if (error) {
+ jclass errClass = (*jenv)->GetObjectClass(jenv, error);
+ jmethodID toString = (*jenv)->GetMethodID(jenv, errClass, "toString",
+ "()Ljava/lang/String;");
+ jobject errString = (*jenv)->CallObjectMethod(jenv, error, toString);
+ const char *errAsUTF = (*jenv)->GetStringUTFChars(jenv, errString, 0);
+ php_error(E_ERROR, "%s", errAsUTF);
+ (*jenv)->ReleaseStringUTFChars(jenv, error, errAsUTF);
+ (*jenv)->ExceptionClear(jenv);
+ jvm_destroy();
+ return -1;
+ }
+
+ php_reflect = (*jenv)->NewGlobalRef(jenv, local_php_reflect);
+ return rc;
+}
+
+/***************************************************************************/
+
+static jobjectArray _java_makeArray(int argc, pval** argv) {
+ jclass objectClass = (*jenv)->FindClass(jenv, "java/lang/Object");
+ jobjectArray result = (*jenv)->NewObjectArray(jenv, argc, objectClass, 0);
+ jobject arg;
+ jmethodID makeArg;
+ int i;
+ pval **handle;
+ int type;
+
+ for (i=0; i<argc; i++) {
+ switch (argv[i]->type) {
+ case IS_STRING:
+ arg=(*jenv)->NewStringUTF(jenv,argv[i]->value.str.val);
+ break;
+
+ case IS_OBJECT:
+ zend_hash_index_find(argv[i]->value.obj.properties, 0, (void*)&handle);
+ arg = php3_list_find((*handle)->value.lval, &type);
+ break;
+
+ case IS_BOOL:
+ makeArg = (*jenv)->GetStaticMethodID(jenv, php_reflect, "MakeArg",
+ "(Z)Ljava/lang/Object;");
+ arg = (*jenv)->CallStaticObjectMethod(jenv, php_reflect, makeArg,
+ (jboolean)(argv[i]->value.lval));
+ break;
+
+ case IS_LONG:
+ makeArg = (*jenv)->GetStaticMethodID(jenv, php_reflect, "MakeArg",
+ "(J)Ljava/lang/Object;");
+ arg = (*jenv)->CallStaticObjectMethod(jenv, php_reflect, makeArg,
+ (jlong)(argv[i]->value.lval));
+ break;
+
+ case IS_DOUBLE:
+ makeArg = (*jenv)->GetStaticMethodID(jenv, php_reflect, "MakeArg",
+ "(D)Ljava/lang/Object;");
+ arg = (*jenv)->CallStaticObjectMethod(jenv, php_reflect, makeArg,
+ (jdouble)(argv[i]->value.dval));
+ break;
+
+ default:
+ arg=0;
+ }
+ (*jenv)->SetObjectArrayElement(jenv, result, i, arg);
+ if (argv[i]->type != IS_OBJECT)
+ (*jenv)->DeleteLocalRef(jenv, arg);
+ }
+ return result;
+}
+
+static int checkError(pval *value) {
+ if (value->type == IS_EXCEPTION) {
+ php_error(E_WARNING, "%s", value->value.str.val);
+ efree(value->value.str.val);
+ var_reset(value);
+ return 1;
+ };
+ return 0;
+}
+
+/***************************************************************************/
+
+/*
+ * Invoke a method on an object. If method name is "java", create a new
+ * object instead.
+ */
+void java_call_function_handler
+ (INTERNAL_FUNCTION_PARAMETERS, zend_property_reference *property_reference)
+{
+ pval *object = property_reference->object;
+ zend_overloaded_element *function_name = (zend_overloaded_element *)
+ property_reference->elements_list.tail->data;
+
+ int arg_count = ARG_COUNT(ht);
+ jlong result = 0;
+
+ pval **arguments = (pval **) emalloc(sizeof(pval *)*arg_count);
+ getParametersArray(ht, arg_count, arguments);
+
+ if (iniUpdated && jvm) jvm_destroy();
+ if (!jvm) jvm_create();
+ if (!jvm) return;
+
+ if (!strcmp("java",function_name->element.value.str.val)) {
+
+ /* construct a Java object:
+ First argument is the class name. Any additional arguments will
+ be treated as constructor parameters. */
+
+ jmethodID co = (*jenv)->GetStaticMethodID(jenv, php_reflect, "CreateObject",
+ "(Ljava/lang/String;[Ljava/lang/Object;J)V");
+ jstring className=(*jenv)->NewStringUTF(jenv, arguments[0]->value.str.val);
+ (pval*)(long)result = object;
+
+ (*jenv)->CallStaticVoidMethod(jenv, php_reflect, co,
+ className, _java_makeArray(arg_count-1, arguments+1), result);
+
+ (*jenv)->DeleteLocalRef(jenv, className);
+
+ } else {
+
+ pval **handle;
+ int type;
+ jobject obj;
+ jstring method;
+
+ /* invoke a method on the given object */
+
+ jmethodID invoke = (*jenv)->GetStaticMethodID(jenv, php_reflect, "Invoke",
+ "(Ljava/lang/Object;Ljava/lang/String;[Ljava/lang/Object;J)V");
+ zend_hash_index_find(object->value.obj.properties, 0, (void**) &handle);
+ obj = php3_list_find((*handle)->value.lval, &type);
+ method = (*jenv)->NewStringUTF(jenv, function_name->element.value.str.val);
+ (pval*)(long)result = return_value;
+
+ (*jenv)->CallStaticVoidMethod(jenv, php_reflect, invoke,
+ obj, method, _java_makeArray(arg_count, arguments), result);
+
+ (*jenv)->DeleteLocalRef(jenv, method);
+
+ }
+
+ efree(arguments);
+ pval_destructor(&function_name->element);
+
+ checkError((pval*)(long)result);
+}
+
+/***************************************************************************/
+
+static pval _java_getset_property
+ (zend_property_reference *property_reference, jobjectArray value)
+{
+ pval presult;
+ jlong result = 0;
+ pval **pobject;
+ jobject obj;
+ int type;
+
+ /* get the property name */
+ zend_llist_element *element = property_reference->elements_list.head;
+ zend_overloaded_element *property=(zend_overloaded_element *)element->data;
+ jstring propName =
+ (*jenv)->NewStringUTF(jenv, property->element.value.str.val);
+
+ /* get the object */
+ zend_hash_index_find(property_reference->object->value.obj.properties,
+ 0, (void **) &pobject);
+ obj = php3_list_find((*pobject)->value.lval,&type);
+ (pval*)(long)result = &presult;
+ var_uninit(&presult);
+
+ if (!obj || (type!=le_jobject)) {
+ php_error(E_ERROR,
+ "Attempt to access a Java property on a non-Java object");
+ } else {
+ /* invoke the method */
+ jmethodID gsp = (*jenv)->GetStaticMethodID(jenv, php_reflect, "GetSetProp",
+ "(Ljava/lang/Object;Ljava/lang/String;[Ljava/lang/Object;J)V");
+ (*jenv)->CallStaticVoidMethod
+ (jenv, php_reflect, gsp, obj, propName, value, result);
+ }
+
+ (*jenv)->DeleteLocalRef(jenv, propName);
+ pval_destructor(&property->element);
+ return presult;
+}
+
+pval java_get_property_handler
+ (zend_property_reference *property_reference)
+{
+ pval presult = _java_getset_property(property_reference, 0);
+ checkError(&presult);
+ return presult;
+}
+
+
+int java_set_property_handler
+ (zend_property_reference *property_reference, pval *value)
+{
+ pval presult = _java_getset_property
+ (property_reference, _java_makeArray(1, &value));
+ return checkError(&presult) ? FAILURE : SUCCESS;
+}
+
+/***************************************************************************/
+
+static void _php3_java_destructor(void *jobject) {
+ (*jenv)->DeleteGlobalRef(jenv, jobject);
+}
+
+PHP_MINIT_FUNCTION(java) {
+ INIT_OVERLOADED_CLASS_ENTRY(java_class_entry, "java", NULL,
+ java_call_function_handler,
+ java_get_property_handler,
+ java_set_property_handler);
+
+ register_internal_class(&java_class_entry);
+
+ le_jobject = register_list_destructors(_php3_java_destructor,NULL);
+
+ REGISTER_INI_ENTRIES();
+ return SUCCESS;
+}
+
+
+PHP_MSHUTDOWN_FUNCTION(java) {
+ UNREGISTER_INI_ENTRIES();
+ if (jvm) jvm_destroy();
+ return SUCCESS;
+}
+
+function_entry java_functions[] = {
+ {NULL, NULL, NULL}
+};
+
+
+static PHP_MINFO_FUNCTION(java) {
+ DISPLAY_INI_ENTRIES();
+}
+
+php3_module_entry java_module_entry = {
+ "java",
+ java_functions,
+ PHP_MINIT(java),
+ PHP_MSHUTDOWN(java),
+ NULL,
+ NULL,
+ PHP_MINFO(java),
+ STANDARD_MODULE_PROPERTIES
+};
+
+DLEXPORT zend_module_entry *get_module(void) { return &java_module_entry; }
+
+/***************************************************************************/
+
+JNIEXPORT void JNICALL Java_net_php_reflect_setResultFromString
+ (JNIEnv *jenv, jobject self, jlong result, jstring value)
+{
+ const char *valueAsUTF = (*jenv)->GetStringUTFChars(jenv, value, 0);
+ pval *presult = (pval*)(long)result;
+ presult->type=IS_STRING;
+ presult->value.str.len=strlen(valueAsUTF);
+ presult->value.str.val=emalloc(presult->value.str.len+1);
+ strcpy(presult->value.str.val, valueAsUTF);
+ (*jenv)->ReleaseStringUTFChars(jenv, value, valueAsUTF);
+}
+
+JNIEXPORT void JNICALL Java_net_php_reflect_setResultFromLong
+ (JNIEnv *jenv, jobject self, jlong result, jlong value)
+{
+ pval *presult = (pval*)(long)result;
+ presult->type=IS_LONG;
+ presult->value.lval=(long)value;
+}
+
+JNIEXPORT void JNICALL Java_net_php_reflect_setResultFromDouble
+ (JNIEnv *jenv, jobject self, jlong result, jdouble value)
+{
+ pval *presult = (pval*)(long)result;
+ presult->type=IS_DOUBLE;
+ presult->value.dval=value;
+}
+
+JNIEXPORT void JNICALL Java_net_php_reflect_setResultFromBoolean
+ (JNIEnv *jenv, jobject self, jlong result, jboolean value)
+{
+ pval *presult = (pval*)(long)result;
+ presult->type=IS_BOOL;
+ presult->value.lval=value;
+}
+
+JNIEXPORT void JNICALL Java_net_php_reflect_setResultFromObject
+ (JNIEnv *jenv, jobject self, jlong result, jobject value)
+{
+ /* wrapper the java object in a pval object */
+ pval *presult = (pval*)(long)result;
+ pval *handle;
+
+ if (presult->type != IS_OBJECT) {
+ presult->type=IS_OBJECT;
+ presult->value.obj.ce=&java_class_entry;
+ presult->value.obj.properties = (HashTable *) emalloc(sizeof(HashTable));
+ presult->is_ref=1;
+ presult->refcount=1;
+ zend_hash_init(presult->value.obj.properties, 0, NULL, PVAL_PTR_DTOR, 0);
+ };
+
+ handle = (pval *) emalloc(sizeof(pval));
+ handle->type = IS_LONG;
+ handle->value.lval =
+ php3_list_insert((*jenv)->NewGlobalRef(jenv,value), le_jobject);
+ pval_copy_constructor(handle);
+ INIT_PZVAL(handle);
+ zend_hash_index_update(presult->value.obj.properties, 0,
+ &handle, sizeof(pval *), NULL);
+}
+
+JNIEXPORT void JNICALL Java_net_php_reflect_setException
+ (JNIEnv *jenv, jobject self, jlong result, jstring value)
+{
+ pval *presult = (pval*)(long)result;
+ Java_net_php_reflect_setResultFromString(jenv, self, result, value);
+ presult->type=IS_EXCEPTION;
+}
diff --git a/ext/java/java.dsp b/ext/java/java.dsp
new file mode 100644
index 0000000000..0281dbf7bc
--- /dev/null
+++ b/ext/java/java.dsp
@@ -0,0 +1,254 @@
+# Microsoft Developer Studio Project File - Name="java" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=java - Win32 Debug_TS
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "java.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "java.mak" CFG="java - Win32 Debug_TS"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "java - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "java - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "java - Win32 Debug_TS" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "java - Win32 Release_TS" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "java - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "..\..\Release"
+# PROP BASE Intermediate_Dir "..\..\Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "..\..\Release"
+# PROP Intermediate_Dir "..\..\Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /YX /FD /c
+# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\.." /I "..\..\libzend" /I "$(JAVA_HOME)\include\win32" /I "$(JAVA_HOME)\include" /I "..\..\..\bindlib_w32" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "COMPILE_DL" /YX /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x40d /d "NDEBUG"
+# ADD RSC /l 0x40d /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"..\..\Release/php_java.dll" /libpath:"$(JAVA_HOME)\lib" /libpath:"..\..\Release"
+
+!ELSEIF "$(CFG)" == "java - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "..\..\Debug"
+# PROP BASE Intermediate_Dir "..\..\Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "..\..\Debug"
+# PROP Intermediate_Dir "..\..\Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /YX /FD /GZ /c
+# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "..\.." /I "..\..\libzend" /I "$(JAVA_HOME)\include\win32" /I "$(JAVA_HOME)\include" /I "..\..\..\bindlib_w32" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "COMPILE_DL" /D ZEND_DEBUG=1 /FR /YX /FD /GZ /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x40d /d "_DEBUG"
+# ADD RSC /l 0x40d /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /out:"..\..\Debug/php_java.dll" /pdbtype:sept /libpath:"$(JAVA_HOME)\lib" /libpath:"..\..\Debug"
+
+!ELSEIF "$(CFG)" == "java - Win32 Debug_TS"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "..\..\Debug_TS"
+# PROP BASE Intermediate_Dir "..\..\Debug_TS"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "..\..\Debug_TS"
+# PROP Intermediate_Dir "..\..\Debug_TS"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "..\.." /I "..\..\..\libzend" /I "$(JAVA_HOME)\include\win32" /I "$(JAVA_HOME)\include" /I "..\..\..\bindlib_w32" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "COMPILE_DL" /FR /YX /FD /GZ /c
+# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "..\.." /I "..\..\libzend" /I "$(JAVA_HOME)\include\win32" /I "$(JAVA_HOME)\include" /I "..\..\..\bindlib_w32" /D "_DEBUG" /D ZEND_DEBUG=1 /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "COMPILE_DL" /D "ZTS" /FR /YX /FD /GZ /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x40d /d "_DEBUG"
+# ADD RSC /l 0x40d /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib php4ts.lib /nologo /dll /debug /machine:I386 /out:"..\..\Debug_TS/php_java.dll" /pdbtype:sept /libpath:"$(JAVA_HOME)\lib" /libpath:"..\..\Debug_TS"
+
+!ELSEIF "$(CFG)" == "java - Win32 Release_TS"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "..\..\Release_TS"
+# PROP BASE Intermediate_Dir "..\..\Release_TS"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "..\..\Release_TS"
+# PROP Intermediate_Dir "..\..\Release_TS"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MD /W3 /GX /O2 /I "..\.." /I "..\..\..\libzend" /I "$(JAVA_HOME)\include\win32" /I "$(JAVA_HOME)\include" /I "..\..\..\bindlib_w32" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "COMPILE_DL" /YX /FD /c
+# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\.." /I "..\..\libzend" /I "$(JAVA_HOME)\include\win32" /I "$(JAVA_HOME)\include" /I "..\..\..\bindlib_w32" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "COMPILE_DL" /D "ZTS" /YX /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x40d /d "NDEBUG"
+# ADD RSC /l 0x40d /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib php4ts.lib /nologo /dll /machine:I386 /out:"..\..\Release_TS/php_java.dll" /libpath:"$(JAVA_HOME)\lib" /libpath:"..\..\Release_TS"
+
+!ENDIF
+
+# Begin Target
+
+# Name "java - Win32 Release"
+# Name "java - Win32 Debug"
+# Name "java - Win32 Debug_TS"
+# Name "java - Win32 Release_TS"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=.\java.c
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# Begin Source File
+
+SOURCE=.\php_java.h
+# End Source File
+# End Group
+# Begin Group "Java Files"
+
+# PROP Default_Filter "java"
+# Begin Source File
+
+SOURCE=.\reflect.java
+
+!IF "$(CFG)" == "java - Win32 Release"
+
+# Begin Custom Build
+OutDir=.\..\..\Release
+TargetName=php_java
+InputPath=.\reflect.java
+
+"$(OutDir)\php_java.jar" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ if not exist net mkdir net
+ if not exist net\php mkdir net\php
+ copy $(InputPath) net\php > nul
+ $(JAVA_HOME)\bin\javac net\php\reflect.java
+ $(JAVA_HOME)\bin\jar c0f $(OutDir)\php_java.jar net\php\*.class
+ erase net\php\reflect.*
+ rmdir net\php
+ rmdir net
+
+# End Custom Build
+
+!ELSEIF "$(CFG)" == "java - Win32 Debug"
+
+# Begin Custom Build
+OutDir=.\..\..\Debug
+TargetName=php_java
+InputPath=.\reflect.java
+
+"$(OutDir)\php_java.jar" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ if not exist net mkdir net
+ if not exist net\php mkdir net\php
+ copy $(InputPath) net\php > nul
+ $(JAVA_HOME)\bin\javac -g net\php\reflect.java
+ $(JAVA_HOME)\bin\jar c0f $(OutDir)\php_java.jar net\php\*.class
+ erase net\php\reflect.*
+ rmdir net\php
+ rmdir net
+
+# End Custom Build
+
+!ELSEIF "$(CFG)" == "java - Win32 Debug_TS"
+
+# Begin Custom Build
+OutDir=.\..\..\Debug_TS
+TargetName=php_java
+InputPath=.\reflect.java
+
+"$(OutDir)\php_java.jar" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ if not exist net mkdir net
+ if not exist net\php mkdir net\php
+ copy $(InputPath) net\php > nul
+ $(JAVA_HOME)\bin\javac -g net\php\reflect.java
+ $(JAVA_HOME)\bin\jar c0f $(OutDir)\php_java.jar net\php\*.class
+ erase net\php\reflect.*
+ rmdir net\php
+ rmdir net
+
+# End Custom Build
+
+!ELSEIF "$(CFG)" == "java - Win32 Release_TS"
+
+# Begin Custom Build
+OutDir=.\..\..\Release_TS
+TargetName=php_java
+InputPath=.\reflect.java
+
+"$(OutDir)\php_java.jar" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ if not exist net mkdir net
+ if not exist net\php mkdir net\php
+ copy $(InputPath) net\php > nul
+ $(JAVA_HOME)\bin\javac net\php\reflect.java
+ $(JAVA_HOME)\bin\jar c0f $(OutDir)\php_java.jar net\php\*.class
+ erase net\php\reflect.*
+ rmdir net\php
+ rmdir net
+
+# End Custom Build
+
+!ENDIF
+
+# End Source File
+# End Group
+# Begin Source File
+
+SOURCE=.\jtest.php
+# End Source File
+# End Target
+# End Project
diff --git a/ext/java/jawt.php b/ext/java/jawt.php
new file mode 100644
index 0000000000..db06949100
--- /dev/null
+++ b/ext/java/jawt.php
@@ -0,0 +1,28 @@
+<?
+
+ // this example makes about as much sense from a web server perspective as,
+ // say, launching and interacting with Microsoft word. <grin>
+
+ $frame = new Java("java.awt.Frame", "Zend");
+ $button = new Java("java.awt.Button", "Hello Java world!");
+ $frame->add("North", $button);
+ $frame->validate();
+ $frame->pack();
+ $frame->visible = True;
+
+ $thread = new Java("java.lang.Thread");
+ $thread->sleep(10000);
+
+ $frame->dispose();
+
+ // Odd behavior noted with Sun JVMs:
+ //
+ // 1) $thread->destroy() will fail with a NoSuchMethodError exception.
+ // 2) The call to (*jvm)->DestroyJVM(jvm) made when PHP terminates
+ // will hang, unless _BOTH_ the calls to pack and setVisible above
+ // are removed.
+ //
+ // Even more odd: both effects are seen with a 100% Java implementation
+ // of the above!
+
+?>
diff --git a/ext/java/jver.php b/ext/java/jver.php
new file mode 100644
index 0000000000..7df8c07ac4
--- /dev/null
+++ b/ext/java/jver.php
@@ -0,0 +1,15 @@
+<?
+
+ $system = new Java("java.lang.System");
+ print "Java version=".$system->getProperty("java.version")." <br>\n";
+ print "Java vendor=".$system->getProperty("java.vendor")." <p>\n\n";
+ print "OS=".$system->getProperty("os.name")." ".
+ $system->getProperty("os.version")." on ".
+ $system->getProperty("os.arch")." <br>\n";
+
+ $formatter = new Java("java.text.SimpleDateFormat",
+ "EEEE, MMMM dd, yyyy 'at' h:mm:ss a zzzz");
+
+ print $formatter->format(new Java("java.util.Date"))."\n";
+
+?>
diff --git a/ext/java/reflect.java b/ext/java/reflect.java
new file mode 100644
index 0000000000..07c5ccc717
--- /dev/null
+++ b/ext/java/reflect.java
@@ -0,0 +1,186 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP version 4.0 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997, 1998, 1999 The PHP Group |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 2.0 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available at through the world-wide-web at |
+ | http://www.php.net/license.html. |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Author: Sam Ruby (rubys@us.ibm.com) |
+ +----------------------------------------------------------------------+
+ */
+
+package net.php;
+
+import java.lang.reflect.*;
+import java.beans.*;
+
+class reflect {
+
+ static { System.loadLibrary("php_java"); }
+
+ //
+ // Native methods
+ //
+ private static native void setResultFromString(long result, String value);
+ private static native void setResultFromLong(long result, long value);
+ private static native void setResultFromDouble(long result, double value);
+ private static native void setResultFromBoolean(long result, boolean value);
+ private static native void setResultFromObject(long result, Object value);
+ private static native void setException(long result, String value);
+
+ //
+ // Helper routines which encapsulate the native methods
+ //
+ static void setResult(long result, Object value) {
+ if (value == null) return;
+
+ if (value instanceof java.lang.String) {
+
+ setResultFromString(result, (String)value);
+
+ } else if (value instanceof java.lang.Number) {
+
+ if (value instanceof java.lang.Integer ||
+ value instanceof java.lang.Short ||
+ value instanceof java.lang.Byte) {
+ setResultFromLong(result, ((Number)value).longValue());
+ } else {
+ /* Float, Double, BigDecimal, BigInteger, Double, Long, ... */
+ setResultFromDouble(result, ((Number)value).doubleValue());
+ }
+
+ } else if (value instanceof java.lang.Boolean) {
+
+ setResultFromBoolean(result, ((Boolean)value).booleanValue());
+
+ } else {
+
+ setResultFromObject(result, value);
+
+ }
+ }
+
+ static void setException(long result, Throwable e) {
+ if (e instanceof InvocationTargetException) {
+ Throwable t = ((InvocationTargetException)e).getTargetException();
+ if (t!=null) e=t;
+ }
+
+ setException(result, e.toString());
+ }
+
+ //
+ // Create an new instance of a given class
+ //
+ public static void CreateObject(String name, Object args[], long result) {
+ try {
+ Constructor cons[] = Class.forName(name).getConstructors();
+ for (int i=0; i<cons.length; i++) {
+ if (cons[i].getParameterTypes().length == args.length) {
+ setResult(result, cons[i].newInstance(args));
+ return;
+ }
+ }
+
+ // for classes which have no visible constructor, return the class
+ // useful for classes like java.lang.System and java.util.Calendar.
+ if (args.length == 0) {
+ setResult(result, Class.forName(name));
+ return;
+ }
+
+ throw new InstantiationException("No matching constructor found");
+
+ } catch (Exception e) {
+ setException(result, e);
+ }
+ }
+
+ //
+ // Invoke a method on a given object
+ //
+ public static void Invoke
+ (Object object, String method, Object args[], long result)
+ {
+ try {
+
+ for (Class jclass = object.getClass();;jclass=(Class)object) {
+ Method methods[] = jclass.getMethods();
+ for (int i=0; i<methods.length; i++) {
+ if (methods[i].getName().equalsIgnoreCase(method) &&
+ methods[i].getParameterTypes().length == args.length) {
+ setResult(result, methods[i].invoke(object, args));
+ return;
+ }
+ }
+
+ // try a second time with the object itself, if it is of type Class
+ if (!(jclass instanceof Class) || (jclass==object)) break;
+ }
+
+ throw new NoSuchMethodException(method);
+
+ } catch (Exception e) {
+ setException(result, e);
+ }
+ }
+
+ //
+ // Get or Set a property
+ //
+ public static void GetSetProp
+ (Object object, String prop, Object args[], long result)
+ {
+ try {
+
+ for (Class jclass = object.getClass();;jclass=(Class)object) {
+ BeanInfo beanInfo = Introspector.getBeanInfo(jclass);
+ PropertyDescriptor props[] = beanInfo.getPropertyDescriptors();
+ for (int i=0; i<props.length; i++) {
+ if (props[i].getName().equalsIgnoreCase(prop)) {
+ Method method;
+ if (args!=null && args.length>0) {
+ method=props[i].getWriteMethod();
+ } else {
+ method=props[i].getReadMethod();
+ }
+ setResult(result, method.invoke(object, args));
+ return;
+ }
+ }
+
+ Field jfields[] = jclass.getFields();
+ for (int i=0; i<jfields.length; i++) {
+ if (jfields[i].getName().equalsIgnoreCase(prop)) {
+ if (args!=null && args.length>0) {
+ jfields[i].set(object, args[0]);
+ } else {
+ setResult(result, jfields[i].get(object));
+ }
+ return;
+ }
+ }
+
+ // try a second time with the object itself, if it is of type Class
+ if (!(jclass instanceof Class) || (jclass==object)) break;
+ }
+
+ } catch (Exception e) {
+ setException(result, e);
+ }
+ }
+
+ //
+ // Helper routines for the C implementation
+ //
+ public static Object MakeArg(boolean b) { return new Boolean(b); }
+ public static Object MakeArg(long l) { return new Long(l); }
+ public static Object MakeArg(double d) { return new Double(d); }
+}
diff --git a/ext/rpc/Makefile.am b/ext/rpc/Makefile.am
new file mode 100644
index 0000000000..95196a49be
--- /dev/null
+++ b/ext/rpc/Makefile.am
@@ -0,0 +1,24 @@
+# $Id$
+
+SRC=java.c
+
+CFLAGS=@CFLAGS@ @JAVA_CFLAGS@
+INCLUDES=@INCLUDES@ @JAVA_INCLUDE@ -I@top_srcdir@ -I@top_srcdir@/libzend
+EXTRA_LTLIBRARIES=libphp_java.la
+phplib_LTLIBRARIES=@JAVA_SHARED@
+libphp_java_la_SOURCES=$(SRC)
+libphp_java_la_LIBADD=@JAVA_LFLAGS@
+libphp_java_la_LDFLAGS=-avoid-version -module -rpath $(phplibdir)
+EXTRA_LIBS=
+
+phplib_DATA=php_java.jar
+php_java.jar : reflect.java
+ @test -e net || mkdir net
+ @test -e net/php || mkdir net/php
+ @cp reflect.java net/php
+ javac net/php/reflect.java
+ @test ! -f reflect.class || mv reflect.class net/php # bug in KJC javac
+ zip -q0 php_java.jar net/php/*.class
+ @rm net/php/reflect.*
+ @rmdir net/php
+ @rmdir net
diff --git a/ext/rpc/config.h.stub b/ext/rpc/config.h.stub
new file mode 100644
index 0000000000..737d5d39ff
--- /dev/null
+++ b/ext/rpc/config.h.stub
@@ -0,0 +1,3 @@
+#ifndef HAVE_JAVA
+#define HAVE_JAVA 0
+#endif
diff --git a/ext/rpc/java/Makefile.am b/ext/rpc/java/Makefile.am
new file mode 100644
index 0000000000..95196a49be
--- /dev/null
+++ b/ext/rpc/java/Makefile.am
@@ -0,0 +1,24 @@
+# $Id$
+
+SRC=java.c
+
+CFLAGS=@CFLAGS@ @JAVA_CFLAGS@
+INCLUDES=@INCLUDES@ @JAVA_INCLUDE@ -I@top_srcdir@ -I@top_srcdir@/libzend
+EXTRA_LTLIBRARIES=libphp_java.la
+phplib_LTLIBRARIES=@JAVA_SHARED@
+libphp_java_la_SOURCES=$(SRC)
+libphp_java_la_LIBADD=@JAVA_LFLAGS@
+libphp_java_la_LDFLAGS=-avoid-version -module -rpath $(phplibdir)
+EXTRA_LIBS=
+
+phplib_DATA=php_java.jar
+php_java.jar : reflect.java
+ @test -e net || mkdir net
+ @test -e net/php || mkdir net/php
+ @cp reflect.java net/php
+ javac net/php/reflect.java
+ @test ! -f reflect.class || mv reflect.class net/php # bug in KJC javac
+ zip -q0 php_java.jar net/php/*.class
+ @rm net/php/reflect.*
+ @rmdir net/php
+ @rmdir net
diff --git a/ext/rpc/java/README b/ext/rpc/java/README
new file mode 100644
index 0000000000..d873fe75a2
--- /dev/null
+++ b/ext/rpc/java/README
@@ -0,0 +1,132 @@
+What is PHP4 ext/java?
+
+ PHP4 ext/java provides a simple and effective means for creating and
+ invoking methods on Java objects from PHP. The JVM is created using JNI,
+ and everthing runs in-process.
+
+ Two examples are provided, jver and jawt, to illustrate usage of this
+ extension. A few things to note:
+
+ 1) new Java() will create an instance of a class if a suitable constructor
+ is available. If no parameters are passed and the default constructor
+ is private, then an instance of the class is returned instead. This
+ is useful as it provides access to classes like "java.lang.system"
+ which expose most of their functionallity through static methods.
+
+ 2) Accessing a member of an instance will first look for bean properties
+ then public fields. In other words, "print $date.time" will first
+ attempt to be resolved as "$date.getTime()", then as "$date.time";
+
+ 3) Both static and instance members can be accessed on an object with
+ the same syntax. Furthermore, if the java object is of type
+ "java.lang.Class", then static members
+
+ 4) Exceptions raised result in PHP warnings, and null results.
+
+ 5) Overload resolution is in general a hard problem given the
+ differences in types between the two languages. This being said,
+ the current support is pretty lame and I intend to improve it.
+ The current algorithm is to pick the first method with the right
+ name (ignoring case!) and number of parameters - I warned you it
+ was lame!
+
+Build and execution instructions:
+
+ Given the number of platforms and providers of JVMs, no single set of
+ instructions will be able to cover all cases. So in place of hard and
+ fast instructions, below are a working examples for a number of free and
+ commercial implementations and platforms. Please adjust the paths to
+ suit your installation. Also, if you happen to get this to work on
+ another JVM/platform combination, please let me know, particularly if
+ a unique build or execution setup was required.
+
+ This function has been tested in both CGI and Apache (apxs) modes. As
+ the current design requires shared libraries, this support can not be
+ linked statically into Apache.
+
+ Finally, it is worth noting that no JVMs are created until the first
+ Java call is made. This not only eliminates unnecessary overhead if
+ the extension is never used, it also provides error messages directly
+ back to the user instead of being burried in a log some place.
+ Additionally, on Unix, the loading of the shared library which implements
+ the JVM is also deferred until first use.
+
+========================================================================
+=== JVM=Kaffe 1.0.4 (as delivered with OS), OS=Redhat Linux 6.1 ===
+========================================================================
+
+build instructions:
+
+ ./configure --with-java
+
+php.ini:
+
+ [java]
+ java.library=/usr/lib/kaffe/libkaffevm.so
+ java.library.path=/usr/lib/kaffe:/home/rubys/php4/modules
+ java.class.path=/usr/share/kaffe/Klasses.jar:/home/rubys/php4/modules/php_java.jar
+ extension_dir=/home/rubys/php4/modules
+ extension=libphp_java.so
+
+========================================================================
+=== JVM=Kaffe 1.0.5 (built from source), OS=Redhat Linux 6.1 ===
+========================================================================
+
+build instructions:
+
+ ./configure --with-java
+
+php.ini:
+
+ [java]
+ java.library=/usr/local/lib/libkaffevm.so
+ java.library.path=/usr/local/lib/kaffe:/home/rubys/php4/modules
+ java.class.path=/usr/local/share/kaffe/Klasses.jar:/home/rubys/php4/modules/php_java.jar
+ extension_dir=/home/rubys/php4/modules
+ extension=libphp_java.so
+
+========================================================================
+=== JVM=IBM 1.1.8, OS=Redhat Linux 6.1 ===
+========================================================================
+
+build instructions:
+
+ ./configure --with-java=/home/jdk118
+
+php.ini:
+
+ [java]
+ java.library=/home/jdk118/lib/linux/native_threads/libjava.so
+ java.class.path=/home/jdk118/lib/classes.zip:/home/rubys/php4/modules/php_java.jar
+ extension_dir=/home/rubys/php4/modules
+ extension=libphp_java.so
+
+========================================================================
+=== JVM=Sun JDK 1.1.8, OS=Windows NT 4 ===
+========================================================================
+
+build instructions:
+
+ SET JAVA_HOME=D:\jdk1.1.8
+ msdev ext\java\java.dsp /MAKE "java - Win32 Debug_TS"
+
+php.ini:
+
+ [java]
+ java.class.path="D:\jdk1.1.8\lib\classes.zip;F:\PHP4\Debug_TS\php_java.jar"
+ extension=php_java.dll
+
+========================================================================
+=== JVM=Sun JDK 1.2.2, OS=Windows NT 4 ===
+========================================================================
+
+build instructions:
+
+ SET JAVA_HOME=D:\jdk1.2.2
+ msdev ext\java\java.dsp /MAKE "java - Win32 Debug_TS"
+
+php.ini:
+
+ [java]
+ java.class.path=F:\PHP4\Debug_TS\php_java.jar
+ extension=php_java.dll
diff --git a/ext/rpc/java/config.h.stub b/ext/rpc/java/config.h.stub
new file mode 100644
index 0000000000..737d5d39ff
--- /dev/null
+++ b/ext/rpc/java/config.h.stub
@@ -0,0 +1,3 @@
+#ifndef HAVE_JAVA
+#define HAVE_JAVA 0
+#endif
diff --git a/ext/rpc/java/config.m4 b/ext/rpc/java/config.m4
new file mode 100644
index 0000000000..d0a955b680
--- /dev/null
+++ b/ext/rpc/java/config.m4
@@ -0,0 +1,59 @@
+# $Id$
+# config.m4 for extension java
+
+AC_MSG_CHECKING(for Java support)
+AC_ARG_WITH(java,
+[ --with-java[=DIR] Include Java support. DIR is the base install
+ directory for the JDK. This extension can only
+ be built as a shared dl.],
+[
+ if test "$withval" != "no"; then
+ JAVA_SHARED="libphp_java.la"
+
+ if test "$withval" = "yes"; then
+ if test -d /usr/local/lib/kaffe; then
+ JAVA_CFLAGS="-DKAFFE"
+ JAVA_INCLUDE=-I/usr/local/include/kaffe
+ elif test -d /usr/lib/kaffe; then
+ JAVA_CFLAGS="-DKAFFE"
+ JAVA_INCLUDE=-I/usr/include/kaffe
+ else
+ AC_MSG_RESULT(no)
+ AC_MSG_ERROR(unable to find Java VM libraries)
+ fi
+ else
+ if test -f $withval/lib/libjava.so; then
+ JAVA_INCLUDE="-I$withval/include"
+ test -f $withval/lib/classes.zip && JAVA_CFLAGS="-DJNI_11"
+ test -f $withval/lib/jvm.jar && JAVA_CFLAGS="-DJNI_12"
+ for i in $JAVA_INCLUDE/*; do
+ test -f $i/jni_md.h && JAVA_INCLUDE="$JAVA_INCLUDE $i"
+ done
+ else
+ for i in `find $withval -type d`; do
+ test -f $i/jni.h && JAVA_INCLUDE="-I$i"
+ test -f $i/jni_md.h && JAVA_INCLUDE="$JAVA_INCLUDE -I$i"
+ test -f $i/classes.zip && JAVA_CFLAGS="-DJNI_11"
+ test -f $i/jvm.jar && JAVA_CFLAGS="-DJNI_12"
+ done
+ if test -z "$JAVA_INCLUDE"; then
+ AC_MSG_RESULT(no)
+ AC_MSG_ERROR(unable to find Java VM libraries)
+ fi
+ fi
+ fi
+
+ AC_DEFINE(HAVE_JAVA)
+ PHP_EXTENSION(java, "shared")
+ PHP_BUILD_SHARED
+ AC_MSG_RESULT(yes)
+ else
+ AC_MSG_RESULT(no)
+ fi
+],[
+ AC_MSG_RESULT(no)
+])
+
+AC_SUBST(JAVA_CFLAGS)
+AC_SUBST(JAVA_INCLUDE)
+AC_SUBST(JAVA_SHARED)
diff --git a/ext/rpc/java/java.c b/ext/rpc/java/java.c
new file mode 100644
index 0000000000..2c2aee1a9a
--- /dev/null
+++ b/ext/rpc/java/java.c
@@ -0,0 +1,518 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP version 4.0 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997, 1998, 1999 The PHP Group |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 2.0 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available at through the world-wide-web at |
+ | http://www.php.net/license.html. |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Author: Sam Ruby (rubys@us.ibm.com) |
+ +----------------------------------------------------------------------+
+ */
+
+/*
+ * This module implements Zend OO syntax overloading support for Java
+ * components using JNI and reflection.
+ */
+
+#include "dl/phpdl.h"
+
+#include "php.h"
+#include "zend_compile.h"
+#include "php_ini.h"
+#include "php_globals.h"
+
+#include <jni.h>
+
+#include <stdio.h>
+
+#define IS_EXCEPTION 86
+
+/***************************************************************************/
+
+#ifndef KAFFE
+#ifndef JNI_11
+#ifndef JNI_12
+
+#ifdef JNI_VERSION_1_2
+#define JNI_12
+#else
+#define JNI_11
+#endif
+
+#endif
+#endif
+#endif
+
+#if WIN32|WINNT
+#ifdef JNI_12
+#pragma comment(lib,"jvm.lib")
+#else
+#pragma comment(lib,"javai.lib")
+#endif
+#else
+static void *javadl = 0;
+#endif
+
+/***************************************************************************/
+
+static int le_jobject = 0;
+
+static char *javalib = 0;
+static char *classpath = 0;
+static char *libpath = 0;
+static char *javahome = 0;
+
+static int iniUpdated = 0;
+
+static JavaVM *jvm = 0;
+static JNIEnv *jenv = 0;
+static jclass php_reflect;
+
+static zend_class_entry java_class_entry;
+
+static PHP_INI_MH(OnIniUpdate) {
+ if (new_value) *(char**)mh_arg1 = new_value;
+ iniUpdated=1;
+ return SUCCESS;
+}
+
+PHP_INI_BEGIN()
+ PHP_INI_ENTRY1("java.class.path",
+ NULL, PHP_INI_ALL, OnIniUpdate, &classpath)
+ PHP_INI_ENTRY1("java.home",
+ NULL, PHP_INI_ALL, OnIniUpdate, &javahome)
+ PHP_INI_ENTRY1("java.library",
+ NULL, PHP_INI_ALL, OnIniUpdate, &javalib)
+ PHP_INI_ENTRY1("java.library.path",
+ NULL, PHP_INI_ALL, OnIniUpdate, &libpath)
+PHP_INI_END()
+
+/***************************************************************************/
+
+/*
+ * Destroy a Java Virtual Machine.
+ */
+void jvm_destroy() {
+ if (php_reflect) (*jenv)->DeleteGlobalRef(jenv, php_reflect);
+ if (jvm) (*jvm)->DestroyJavaVM(jvm);
+#if !(WIN32||WINNT)
+ if (javadl) dlclose(javadl);
+#endif
+ php_reflect = 0;
+ jvm = 0;
+ jenv = 0;
+}
+
+/*
+ * Create a Java Virtual Machine.
+ * - class.path, home, and library.path are read out of the INI file
+ * - appropriate (pre 1.1, JDK 1.1, and JDK 1.2) initialization is performed
+ * - net.php.reflect class file is located
+ */
+
+#ifdef JNI_12
+static void addJVMOption(JavaVMInitArgs *vm_args, char *name, char *value) {
+ char *option = (char*) malloc(strlen(name) + strlen(value) + 1);
+ strcpy(option, name);
+ strcat(option, value);
+ vm_args->options[vm_args->nOptions++].optionString = option;
+}
+#endif
+
+static int jvm_create() {
+
+ int rc;
+ jclass local_php_reflect;
+ jthrowable error;
+
+#ifdef JNI_11
+ JDK1_1InitArgs vm_args;
+#else
+ JavaVMInitArgs vm_args;
+#ifdef JNI_12
+ JavaVMOption options[3];
+#endif
+#endif
+
+ iniUpdated=0;
+
+ if (!classpath) classpath = getenv("CLASSPATH");
+
+#if !(WIN32||WINNT)
+ if (!libpath) libpath = getenv("LD_LIBRARY_PATH");
+ if (javalib) {
+ javadl = dlopen(javalib, RTLD_GLOBAL | RTLD_LAZY);
+ if (!javadl) {
+ php_error(E_ERROR, "Unable to create Java Virtual Machine");
+ return -1;
+ }
+ }
+#endif
+
+#ifdef JNI_12
+
+ vm_args.version = JNI_VERSION_1_2;
+ vm_args.ignoreUnrecognized = FALSE;
+ vm_args.options = options;
+ vm_args.nOptions = 0;
+
+ if (classpath) addJVMOption(&vm_args, "-Djava.class.path=", classpath);
+ if (javahome) addJVMOption(&vm_args, "-Djava.home=", javahome);
+ if (libpath) addJVMOption(&vm_args, "-Djava.library.path=", libpath);
+
+ rc = JNI_CreateJavaVM(&jvm, (void**)&jenv, &vm_args);
+
+#else
+
+ vm_args.version=0x00010001;
+ JNI_GetDefaultJavaVMInitArgs(&vm_args);
+
+ if (!classpath) classpath = "";
+ vm_args.classpath = classpath;
+#ifdef KAFFE
+ vm_args.classhome = javahome;
+ vm_args.libraryhome = libpath;
+#endif
+ rc = JNI_CreateJavaVM(&jvm, &jenv, &vm_args);
+
+#endif
+
+ if (rc) {
+ php_error(E_ERROR, "Unable to create Java Virtual Machine");
+ return rc;
+ }
+
+ local_php_reflect = (*jenv)->FindClass(jenv, "net/php/reflect");
+ error = (*jenv)->ExceptionOccurred(jenv);
+ if (error) {
+ jclass errClass = (*jenv)->GetObjectClass(jenv, error);
+ jmethodID toString = (*jenv)->GetMethodID(jenv, errClass, "toString",
+ "()Ljava/lang/String;");
+ jobject errString = (*jenv)->CallObjectMethod(jenv, error, toString);
+ const char *errAsUTF = (*jenv)->GetStringUTFChars(jenv, errString, 0);
+ php_error(E_ERROR, "%s", errAsUTF);
+ (*jenv)->ReleaseStringUTFChars(jenv, error, errAsUTF);
+ (*jenv)->ExceptionClear(jenv);
+ jvm_destroy();
+ return -1;
+ }
+
+ php_reflect = (*jenv)->NewGlobalRef(jenv, local_php_reflect);
+ return rc;
+}
+
+/***************************************************************************/
+
+static jobjectArray _java_makeArray(int argc, pval** argv) {
+ jclass objectClass = (*jenv)->FindClass(jenv, "java/lang/Object");
+ jobjectArray result = (*jenv)->NewObjectArray(jenv, argc, objectClass, 0);
+ jobject arg;
+ jmethodID makeArg;
+ int i;
+ pval **handle;
+ int type;
+
+ for (i=0; i<argc; i++) {
+ switch (argv[i]->type) {
+ case IS_STRING:
+ arg=(*jenv)->NewStringUTF(jenv,argv[i]->value.str.val);
+ break;
+
+ case IS_OBJECT:
+ zend_hash_index_find(argv[i]->value.obj.properties, 0, (void*)&handle);
+ arg = php3_list_find((*handle)->value.lval, &type);
+ break;
+
+ case IS_BOOL:
+ makeArg = (*jenv)->GetStaticMethodID(jenv, php_reflect, "MakeArg",
+ "(Z)Ljava/lang/Object;");
+ arg = (*jenv)->CallStaticObjectMethod(jenv, php_reflect, makeArg,
+ (jboolean)(argv[i]->value.lval));
+ break;
+
+ case IS_LONG:
+ makeArg = (*jenv)->GetStaticMethodID(jenv, php_reflect, "MakeArg",
+ "(J)Ljava/lang/Object;");
+ arg = (*jenv)->CallStaticObjectMethod(jenv, php_reflect, makeArg,
+ (jlong)(argv[i]->value.lval));
+ break;
+
+ case IS_DOUBLE:
+ makeArg = (*jenv)->GetStaticMethodID(jenv, php_reflect, "MakeArg",
+ "(D)Ljava/lang/Object;");
+ arg = (*jenv)->CallStaticObjectMethod(jenv, php_reflect, makeArg,
+ (jdouble)(argv[i]->value.dval));
+ break;
+
+ default:
+ arg=0;
+ }
+ (*jenv)->SetObjectArrayElement(jenv, result, i, arg);
+ if (argv[i]->type != IS_OBJECT)
+ (*jenv)->DeleteLocalRef(jenv, arg);
+ }
+ return result;
+}
+
+static int checkError(pval *value) {
+ if (value->type == IS_EXCEPTION) {
+ php_error(E_WARNING, "%s", value->value.str.val);
+ efree(value->value.str.val);
+ var_reset(value);
+ return 1;
+ };
+ return 0;
+}
+
+/***************************************************************************/
+
+/*
+ * Invoke a method on an object. If method name is "java", create a new
+ * object instead.
+ */
+void java_call_function_handler
+ (INTERNAL_FUNCTION_PARAMETERS, zend_property_reference *property_reference)
+{
+ pval *object = property_reference->object;
+ zend_overloaded_element *function_name = (zend_overloaded_element *)
+ property_reference->elements_list.tail->data;
+
+ int arg_count = ARG_COUNT(ht);
+ jlong result = 0;
+
+ pval **arguments = (pval **) emalloc(sizeof(pval *)*arg_count);
+ getParametersArray(ht, arg_count, arguments);
+
+ if (iniUpdated && jvm) jvm_destroy();
+ if (!jvm) jvm_create();
+ if (!jvm) return;
+
+ if (!strcmp("java",function_name->element.value.str.val)) {
+
+ /* construct a Java object:
+ First argument is the class name. Any additional arguments will
+ be treated as constructor parameters. */
+
+ jmethodID co = (*jenv)->GetStaticMethodID(jenv, php_reflect, "CreateObject",
+ "(Ljava/lang/String;[Ljava/lang/Object;J)V");
+ jstring className=(*jenv)->NewStringUTF(jenv, arguments[0]->value.str.val);
+ (pval*)(long)result = object;
+
+ (*jenv)->CallStaticVoidMethod(jenv, php_reflect, co,
+ className, _java_makeArray(arg_count-1, arguments+1), result);
+
+ (*jenv)->DeleteLocalRef(jenv, className);
+
+ } else {
+
+ pval **handle;
+ int type;
+ jobject obj;
+ jstring method;
+
+ /* invoke a method on the given object */
+
+ jmethodID invoke = (*jenv)->GetStaticMethodID(jenv, php_reflect, "Invoke",
+ "(Ljava/lang/Object;Ljava/lang/String;[Ljava/lang/Object;J)V");
+ zend_hash_index_find(object->value.obj.properties, 0, (void**) &handle);
+ obj = php3_list_find((*handle)->value.lval, &type);
+ method = (*jenv)->NewStringUTF(jenv, function_name->element.value.str.val);
+ (pval*)(long)result = return_value;
+
+ (*jenv)->CallStaticVoidMethod(jenv, php_reflect, invoke,
+ obj, method, _java_makeArray(arg_count, arguments), result);
+
+ (*jenv)->DeleteLocalRef(jenv, method);
+
+ }
+
+ efree(arguments);
+ pval_destructor(&function_name->element);
+
+ checkError((pval*)(long)result);
+}
+
+/***************************************************************************/
+
+static pval _java_getset_property
+ (zend_property_reference *property_reference, jobjectArray value)
+{
+ pval presult;
+ jlong result = 0;
+ pval **pobject;
+ jobject obj;
+ int type;
+
+ /* get the property name */
+ zend_llist_element *element = property_reference->elements_list.head;
+ zend_overloaded_element *property=(zend_overloaded_element *)element->data;
+ jstring propName =
+ (*jenv)->NewStringUTF(jenv, property->element.value.str.val);
+
+ /* get the object */
+ zend_hash_index_find(property_reference->object->value.obj.properties,
+ 0, (void **) &pobject);
+ obj = php3_list_find((*pobject)->value.lval,&type);
+ (pval*)(long)result = &presult;
+ var_uninit(&presult);
+
+ if (!obj || (type!=le_jobject)) {
+ php_error(E_ERROR,
+ "Attempt to access a Java property on a non-Java object");
+ } else {
+ /* invoke the method */
+ jmethodID gsp = (*jenv)->GetStaticMethodID(jenv, php_reflect, "GetSetProp",
+ "(Ljava/lang/Object;Ljava/lang/String;[Ljava/lang/Object;J)V");
+ (*jenv)->CallStaticVoidMethod
+ (jenv, php_reflect, gsp, obj, propName, value, result);
+ }
+
+ (*jenv)->DeleteLocalRef(jenv, propName);
+ pval_destructor(&property->element);
+ return presult;
+}
+
+pval java_get_property_handler
+ (zend_property_reference *property_reference)
+{
+ pval presult = _java_getset_property(property_reference, 0);
+ checkError(&presult);
+ return presult;
+}
+
+
+int java_set_property_handler
+ (zend_property_reference *property_reference, pval *value)
+{
+ pval presult = _java_getset_property
+ (property_reference, _java_makeArray(1, &value));
+ return checkError(&presult) ? FAILURE : SUCCESS;
+}
+
+/***************************************************************************/
+
+static void _php3_java_destructor(void *jobject) {
+ (*jenv)->DeleteGlobalRef(jenv, jobject);
+}
+
+PHP_MINIT_FUNCTION(java) {
+ INIT_OVERLOADED_CLASS_ENTRY(java_class_entry, "java", NULL,
+ java_call_function_handler,
+ java_get_property_handler,
+ java_set_property_handler);
+
+ register_internal_class(&java_class_entry);
+
+ le_jobject = register_list_destructors(_php3_java_destructor,NULL);
+
+ REGISTER_INI_ENTRIES();
+ return SUCCESS;
+}
+
+
+PHP_MSHUTDOWN_FUNCTION(java) {
+ UNREGISTER_INI_ENTRIES();
+ if (jvm) jvm_destroy();
+ return SUCCESS;
+}
+
+function_entry java_functions[] = {
+ {NULL, NULL, NULL}
+};
+
+
+static PHP_MINFO_FUNCTION(java) {
+ DISPLAY_INI_ENTRIES();
+}
+
+php3_module_entry java_module_entry = {
+ "java",
+ java_functions,
+ PHP_MINIT(java),
+ PHP_MSHUTDOWN(java),
+ NULL,
+ NULL,
+ PHP_MINFO(java),
+ STANDARD_MODULE_PROPERTIES
+};
+
+DLEXPORT zend_module_entry *get_module(void) { return &java_module_entry; }
+
+/***************************************************************************/
+
+JNIEXPORT void JNICALL Java_net_php_reflect_setResultFromString
+ (JNIEnv *jenv, jobject self, jlong result, jstring value)
+{
+ const char *valueAsUTF = (*jenv)->GetStringUTFChars(jenv, value, 0);
+ pval *presult = (pval*)(long)result;
+ presult->type=IS_STRING;
+ presult->value.str.len=strlen(valueAsUTF);
+ presult->value.str.val=emalloc(presult->value.str.len+1);
+ strcpy(presult->value.str.val, valueAsUTF);
+ (*jenv)->ReleaseStringUTFChars(jenv, value, valueAsUTF);
+}
+
+JNIEXPORT void JNICALL Java_net_php_reflect_setResultFromLong
+ (JNIEnv *jenv, jobject self, jlong result, jlong value)
+{
+ pval *presult = (pval*)(long)result;
+ presult->type=IS_LONG;
+ presult->value.lval=(long)value;
+}
+
+JNIEXPORT void JNICALL Java_net_php_reflect_setResultFromDouble
+ (JNIEnv *jenv, jobject self, jlong result, jdouble value)
+{
+ pval *presult = (pval*)(long)result;
+ presult->type=IS_DOUBLE;
+ presult->value.dval=value;
+}
+
+JNIEXPORT void JNICALL Java_net_php_reflect_setResultFromBoolean
+ (JNIEnv *jenv, jobject self, jlong result, jboolean value)
+{
+ pval *presult = (pval*)(long)result;
+ presult->type=IS_BOOL;
+ presult->value.lval=value;
+}
+
+JNIEXPORT void JNICALL Java_net_php_reflect_setResultFromObject
+ (JNIEnv *jenv, jobject self, jlong result, jobject value)
+{
+ /* wrapper the java object in a pval object */
+ pval *presult = (pval*)(long)result;
+ pval *handle;
+
+ if (presult->type != IS_OBJECT) {
+ presult->type=IS_OBJECT;
+ presult->value.obj.ce=&java_class_entry;
+ presult->value.obj.properties = (HashTable *) emalloc(sizeof(HashTable));
+ presult->is_ref=1;
+ presult->refcount=1;
+ zend_hash_init(presult->value.obj.properties, 0, NULL, PVAL_PTR_DTOR, 0);
+ };
+
+ handle = (pval *) emalloc(sizeof(pval));
+ handle->type = IS_LONG;
+ handle->value.lval =
+ php3_list_insert((*jenv)->NewGlobalRef(jenv,value), le_jobject);
+ pval_copy_constructor(handle);
+ INIT_PZVAL(handle);
+ zend_hash_index_update(presult->value.obj.properties, 0,
+ &handle, sizeof(pval *), NULL);
+}
+
+JNIEXPORT void JNICALL Java_net_php_reflect_setException
+ (JNIEnv *jenv, jobject self, jlong result, jstring value)
+{
+ pval *presult = (pval*)(long)result;
+ Java_net_php_reflect_setResultFromString(jenv, self, result, value);
+ presult->type=IS_EXCEPTION;
+}
diff --git a/ext/rpc/java/java.dsp b/ext/rpc/java/java.dsp
new file mode 100644
index 0000000000..0281dbf7bc
--- /dev/null
+++ b/ext/rpc/java/java.dsp
@@ -0,0 +1,254 @@
+# Microsoft Developer Studio Project File - Name="java" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=java - Win32 Debug_TS
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "java.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "java.mak" CFG="java - Win32 Debug_TS"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "java - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "java - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "java - Win32 Debug_TS" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "java - Win32 Release_TS" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "java - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "..\..\Release"
+# PROP BASE Intermediate_Dir "..\..\Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "..\..\Release"
+# PROP Intermediate_Dir "..\..\Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /YX /FD /c
+# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\.." /I "..\..\libzend" /I "$(JAVA_HOME)\include\win32" /I "$(JAVA_HOME)\include" /I "..\..\..\bindlib_w32" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "COMPILE_DL" /YX /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x40d /d "NDEBUG"
+# ADD RSC /l 0x40d /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"..\..\Release/php_java.dll" /libpath:"$(JAVA_HOME)\lib" /libpath:"..\..\Release"
+
+!ELSEIF "$(CFG)" == "java - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "..\..\Debug"
+# PROP BASE Intermediate_Dir "..\..\Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "..\..\Debug"
+# PROP Intermediate_Dir "..\..\Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /YX /FD /GZ /c
+# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "..\.." /I "..\..\libzend" /I "$(JAVA_HOME)\include\win32" /I "$(JAVA_HOME)\include" /I "..\..\..\bindlib_w32" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "COMPILE_DL" /D ZEND_DEBUG=1 /FR /YX /FD /GZ /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x40d /d "_DEBUG"
+# ADD RSC /l 0x40d /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /out:"..\..\Debug/php_java.dll" /pdbtype:sept /libpath:"$(JAVA_HOME)\lib" /libpath:"..\..\Debug"
+
+!ELSEIF "$(CFG)" == "java - Win32 Debug_TS"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "..\..\Debug_TS"
+# PROP BASE Intermediate_Dir "..\..\Debug_TS"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "..\..\Debug_TS"
+# PROP Intermediate_Dir "..\..\Debug_TS"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "..\.." /I "..\..\..\libzend" /I "$(JAVA_HOME)\include\win32" /I "$(JAVA_HOME)\include" /I "..\..\..\bindlib_w32" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "COMPILE_DL" /FR /YX /FD /GZ /c
+# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "..\.." /I "..\..\libzend" /I "$(JAVA_HOME)\include\win32" /I "$(JAVA_HOME)\include" /I "..\..\..\bindlib_w32" /D "_DEBUG" /D ZEND_DEBUG=1 /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "COMPILE_DL" /D "ZTS" /FR /YX /FD /GZ /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x40d /d "_DEBUG"
+# ADD RSC /l 0x40d /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib php4ts.lib /nologo /dll /debug /machine:I386 /out:"..\..\Debug_TS/php_java.dll" /pdbtype:sept /libpath:"$(JAVA_HOME)\lib" /libpath:"..\..\Debug_TS"
+
+!ELSEIF "$(CFG)" == "java - Win32 Release_TS"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "..\..\Release_TS"
+# PROP BASE Intermediate_Dir "..\..\Release_TS"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "..\..\Release_TS"
+# PROP Intermediate_Dir "..\..\Release_TS"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MD /W3 /GX /O2 /I "..\.." /I "..\..\..\libzend" /I "$(JAVA_HOME)\include\win32" /I "$(JAVA_HOME)\include" /I "..\..\..\bindlib_w32" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "COMPILE_DL" /YX /FD /c
+# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\.." /I "..\..\libzend" /I "$(JAVA_HOME)\include\win32" /I "$(JAVA_HOME)\include" /I "..\..\..\bindlib_w32" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "COMPILE_DL" /D "ZTS" /YX /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x40d /d "NDEBUG"
+# ADD RSC /l 0x40d /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib php4ts.lib /nologo /dll /machine:I386 /out:"..\..\Release_TS/php_java.dll" /libpath:"$(JAVA_HOME)\lib" /libpath:"..\..\Release_TS"
+
+!ENDIF
+
+# Begin Target
+
+# Name "java - Win32 Release"
+# Name "java - Win32 Debug"
+# Name "java - Win32 Debug_TS"
+# Name "java - Win32 Release_TS"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=.\java.c
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# Begin Source File
+
+SOURCE=.\php_java.h
+# End Source File
+# End Group
+# Begin Group "Java Files"
+
+# PROP Default_Filter "java"
+# Begin Source File
+
+SOURCE=.\reflect.java
+
+!IF "$(CFG)" == "java - Win32 Release"
+
+# Begin Custom Build
+OutDir=.\..\..\Release
+TargetName=php_java
+InputPath=.\reflect.java
+
+"$(OutDir)\php_java.jar" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ if not exist net mkdir net
+ if not exist net\php mkdir net\php
+ copy $(InputPath) net\php > nul
+ $(JAVA_HOME)\bin\javac net\php\reflect.java
+ $(JAVA_HOME)\bin\jar c0f $(OutDir)\php_java.jar net\php\*.class
+ erase net\php\reflect.*
+ rmdir net\php
+ rmdir net
+
+# End Custom Build
+
+!ELSEIF "$(CFG)" == "java - Win32 Debug"
+
+# Begin Custom Build
+OutDir=.\..\..\Debug
+TargetName=php_java
+InputPath=.\reflect.java
+
+"$(OutDir)\php_java.jar" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ if not exist net mkdir net
+ if not exist net\php mkdir net\php
+ copy $(InputPath) net\php > nul
+ $(JAVA_HOME)\bin\javac -g net\php\reflect.java
+ $(JAVA_HOME)\bin\jar c0f $(OutDir)\php_java.jar net\php\*.class
+ erase net\php\reflect.*
+ rmdir net\php
+ rmdir net
+
+# End Custom Build
+
+!ELSEIF "$(CFG)" == "java - Win32 Debug_TS"
+
+# Begin Custom Build
+OutDir=.\..\..\Debug_TS
+TargetName=php_java
+InputPath=.\reflect.java
+
+"$(OutDir)\php_java.jar" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ if not exist net mkdir net
+ if not exist net\php mkdir net\php
+ copy $(InputPath) net\php > nul
+ $(JAVA_HOME)\bin\javac -g net\php\reflect.java
+ $(JAVA_HOME)\bin\jar c0f $(OutDir)\php_java.jar net\php\*.class
+ erase net\php\reflect.*
+ rmdir net\php
+ rmdir net
+
+# End Custom Build
+
+!ELSEIF "$(CFG)" == "java - Win32 Release_TS"
+
+# Begin Custom Build
+OutDir=.\..\..\Release_TS
+TargetName=php_java
+InputPath=.\reflect.java
+
+"$(OutDir)\php_java.jar" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ if not exist net mkdir net
+ if not exist net\php mkdir net\php
+ copy $(InputPath) net\php > nul
+ $(JAVA_HOME)\bin\javac net\php\reflect.java
+ $(JAVA_HOME)\bin\jar c0f $(OutDir)\php_java.jar net\php\*.class
+ erase net\php\reflect.*
+ rmdir net\php
+ rmdir net
+
+# End Custom Build
+
+!ENDIF
+
+# End Source File
+# End Group
+# Begin Source File
+
+SOURCE=.\jtest.php
+# End Source File
+# End Target
+# End Project
diff --git a/ext/rpc/java/jawt.php b/ext/rpc/java/jawt.php
new file mode 100644
index 0000000000..db06949100
--- /dev/null
+++ b/ext/rpc/java/jawt.php
@@ -0,0 +1,28 @@
+<?
+
+ // this example makes about as much sense from a web server perspective as,
+ // say, launching and interacting with Microsoft word. <grin>
+
+ $frame = new Java("java.awt.Frame", "Zend");
+ $button = new Java("java.awt.Button", "Hello Java world!");
+ $frame->add("North", $button);
+ $frame->validate();
+ $frame->pack();
+ $frame->visible = True;
+
+ $thread = new Java("java.lang.Thread");
+ $thread->sleep(10000);
+
+ $frame->dispose();
+
+ // Odd behavior noted with Sun JVMs:
+ //
+ // 1) $thread->destroy() will fail with a NoSuchMethodError exception.
+ // 2) The call to (*jvm)->DestroyJVM(jvm) made when PHP terminates
+ // will hang, unless _BOTH_ the calls to pack and setVisible above
+ // are removed.
+ //
+ // Even more odd: both effects are seen with a 100% Java implementation
+ // of the above!
+
+?>
diff --git a/ext/rpc/java/jver.php b/ext/rpc/java/jver.php
new file mode 100644
index 0000000000..7df8c07ac4
--- /dev/null
+++ b/ext/rpc/java/jver.php
@@ -0,0 +1,15 @@
+<?
+
+ $system = new Java("java.lang.System");
+ print "Java version=".$system->getProperty("java.version")." <br>\n";
+ print "Java vendor=".$system->getProperty("java.vendor")." <p>\n\n";
+ print "OS=".$system->getProperty("os.name")." ".
+ $system->getProperty("os.version")." on ".
+ $system->getProperty("os.arch")." <br>\n";
+
+ $formatter = new Java("java.text.SimpleDateFormat",
+ "EEEE, MMMM dd, yyyy 'at' h:mm:ss a zzzz");
+
+ print $formatter->format(new Java("java.util.Date"))."\n";
+
+?>
diff --git a/ext/rpc/java/reflect.java b/ext/rpc/java/reflect.java
new file mode 100644
index 0000000000..07c5ccc717
--- /dev/null
+++ b/ext/rpc/java/reflect.java
@@ -0,0 +1,186 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP version 4.0 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997, 1998, 1999 The PHP Group |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 2.0 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available at through the world-wide-web at |
+ | http://www.php.net/license.html. |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Author: Sam Ruby (rubys@us.ibm.com) |
+ +----------------------------------------------------------------------+
+ */
+
+package net.php;
+
+import java.lang.reflect.*;
+import java.beans.*;
+
+class reflect {
+
+ static { System.loadLibrary("php_java"); }
+
+ //
+ // Native methods
+ //
+ private static native void setResultFromString(long result, String value);
+ private static native void setResultFromLong(long result, long value);
+ private static native void setResultFromDouble(long result, double value);
+ private static native void setResultFromBoolean(long result, boolean value);
+ private static native void setResultFromObject(long result, Object value);
+ private static native void setException(long result, String value);
+
+ //
+ // Helper routines which encapsulate the native methods
+ //
+ static void setResult(long result, Object value) {
+ if (value == null) return;
+
+ if (value instanceof java.lang.String) {
+
+ setResultFromString(result, (String)value);
+
+ } else if (value instanceof java.lang.Number) {
+
+ if (value instanceof java.lang.Integer ||
+ value instanceof java.lang.Short ||
+ value instanceof java.lang.Byte) {
+ setResultFromLong(result, ((Number)value).longValue());
+ } else {
+ /* Float, Double, BigDecimal, BigInteger, Double, Long, ... */
+ setResultFromDouble(result, ((Number)value).doubleValue());
+ }
+
+ } else if (value instanceof java.lang.Boolean) {
+
+ setResultFromBoolean(result, ((Boolean)value).booleanValue());
+
+ } else {
+
+ setResultFromObject(result, value);
+
+ }
+ }
+
+ static void setException(long result, Throwable e) {
+ if (e instanceof InvocationTargetException) {
+ Throwable t = ((InvocationTargetException)e).getTargetException();
+ if (t!=null) e=t;
+ }
+
+ setException(result, e.toString());
+ }
+
+ //
+ // Create an new instance of a given class
+ //
+ public static void CreateObject(String name, Object args[], long result) {
+ try {
+ Constructor cons[] = Class.forName(name).getConstructors();
+ for (int i=0; i<cons.length; i++) {
+ if (cons[i].getParameterTypes().length == args.length) {
+ setResult(result, cons[i].newInstance(args));
+ return;
+ }
+ }
+
+ // for classes which have no visible constructor, return the class
+ // useful for classes like java.lang.System and java.util.Calendar.
+ if (args.length == 0) {
+ setResult(result, Class.forName(name));
+ return;
+ }
+
+ throw new InstantiationException("No matching constructor found");
+
+ } catch (Exception e) {
+ setException(result, e);
+ }
+ }
+
+ //
+ // Invoke a method on a given object
+ //
+ public static void Invoke
+ (Object object, String method, Object args[], long result)
+ {
+ try {
+
+ for (Class jclass = object.getClass();;jclass=(Class)object) {
+ Method methods[] = jclass.getMethods();
+ for (int i=0; i<methods.length; i++) {
+ if (methods[i].getName().equalsIgnoreCase(method) &&
+ methods[i].getParameterTypes().length == args.length) {
+ setResult(result, methods[i].invoke(object, args));
+ return;
+ }
+ }
+
+ // try a second time with the object itself, if it is of type Class
+ if (!(jclass instanceof Class) || (jclass==object)) break;
+ }
+
+ throw new NoSuchMethodException(method);
+
+ } catch (Exception e) {
+ setException(result, e);
+ }
+ }
+
+ //
+ // Get or Set a property
+ //
+ public static void GetSetProp
+ (Object object, String prop, Object args[], long result)
+ {
+ try {
+
+ for (Class jclass = object.getClass();;jclass=(Class)object) {
+ BeanInfo beanInfo = Introspector.getBeanInfo(jclass);
+ PropertyDescriptor props[] = beanInfo.getPropertyDescriptors();
+ for (int i=0; i<props.length; i++) {
+ if (props[i].getName().equalsIgnoreCase(prop)) {
+ Method method;
+ if (args!=null && args.length>0) {
+ method=props[i].getWriteMethod();
+ } else {
+ method=props[i].getReadMethod();
+ }
+ setResult(result, method.invoke(object, args));
+ return;
+ }
+ }
+
+ Field jfields[] = jclass.getFields();
+ for (int i=0; i<jfields.length; i++) {
+ if (jfields[i].getName().equalsIgnoreCase(prop)) {
+ if (args!=null && args.length>0) {
+ jfields[i].set(object, args[0]);
+ } else {
+ setResult(result, jfields[i].get(object));
+ }
+ return;
+ }
+ }
+
+ // try a second time with the object itself, if it is of type Class
+ if (!(jclass instanceof Class) || (jclass==object)) break;
+ }
+
+ } catch (Exception e) {
+ setException(result, e);
+ }
+ }
+
+ //
+ // Helper routines for the C implementation
+ //
+ public static Object MakeArg(boolean b) { return new Boolean(b); }
+ public static Object MakeArg(long l) { return new Long(l); }
+ public static Object MakeArg(double d) { return new Double(d); }
+}