@ 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.
This commit is contained in:
Sam Ruby 1999-11-09 12:02:22 +00:00
parent 60766eff5a
commit d17a12319f
20 changed files with 2465 additions and 0 deletions

24
ext/java/Makefile.am Normal file
View file

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

132
ext/java/README Normal file
View file

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

3
ext/java/config.h.stub Normal file
View file

@ -0,0 +1,3 @@
#ifndef HAVE_JAVA
#define HAVE_JAVA 0
#endif

59
ext/java/config.m4 Normal file
View file

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

518
ext/java/java.c Normal file
View file

@ -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;
}

254
ext/java/java.dsp Normal file
View file

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

28
ext/java/jawt.php Normal file
View file

@ -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!
?>

15
ext/java/jver.php Normal file
View file

@ -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";
?>

186
ext/java/reflect.java Normal file
View file

@ -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); }
}

24
ext/rpc/Makefile.am Normal file
View file

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

3
ext/rpc/config.h.stub Normal file
View file

@ -0,0 +1,3 @@
#ifndef HAVE_JAVA
#define HAVE_JAVA 0
#endif

24
ext/rpc/java/Makefile.am Normal file
View file

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

132
ext/rpc/java/README Normal file
View file

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

View file

@ -0,0 +1,3 @@
#ifndef HAVE_JAVA
#define HAVE_JAVA 0
#endif

59
ext/rpc/java/config.m4 Normal file
View file

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

518
ext/rpc/java/java.c Normal file
View file

@ -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;
}

254
ext/rpc/java/java.dsp Normal file
View file

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

28
ext/rpc/java/jawt.php Normal file
View file

@ -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!
?>

15
ext/rpc/java/jver.php Normal file
View file

@ -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";
?>

186
ext/rpc/java/reflect.java Normal file
View file

@ -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); }
}