Read Me
What is the PHP/Java Bridge?
----------------------------
The PHP/Java Bridge is PHP module which connects the PHP object system
with the java or ECMA 335 object system.
Please read the ABOUT.HTM contained in the download archive or
http://php-java-bridge.sf.net for more information.
Build and execution instructions:
---------------------------------
NOTE: If you have Security Enhanced Linux, you must update the policy
and tag the files with the correct SEL contexts, please see below, or
please install the binary RPM instead.
In the directory php-java-bridge-p.x.y type:
java -version # 1.4 or above (1.4.2_02 or IBM VM recommended)
gcc --version # 3.2.3 or above.
apachectl -version # Apache 1.3 or above.
php-config --version # PHP 4.3.2 or above.
make null --version # GNU make 3.79 or above
phpize &&
./configure --with-java=/opt/IBMJava2-14 &&
make &&
su -c "make install"
If your administrator allows you to dynamically load extensions, you
can now test the extension by invoking the test.php with the
command: php ./test.php.
Please see the output of ./configure --help=recursive for further
configure options.
------------------------------------
Permanently activate the module
-------------------------------
To permanently activate the extension for all users please add the
following lines to the php.ini or add a file java.ini to the
directory that contains the php module descriptions (usually
/etc/php.d/) with the following content:
extension = java.so
[java]
java.log_level="3"
java.log_file="/var/log/php-java-bridge.log"
java.socketname="/var/run/.php-java-bridge_socket"
Re-start the web server, for example with the command:
apachectl restart
OPTION 1: You can use local sockets to connect to a local backend.
Copy the executable php-java-bridge to /usr/sbin, make it executable
with the command "chmod +x /usr/sbin/php-java-bridge" and start it:
/usr/sbin/php-java-bridge
This option is available on Security Enhanced Linux.
OPTION 2: You can use TCP/IP sockets to communicate with different
backends on different hosts. Disable the java.socketname option,
start the backends on all hosts and ports, for example with the
command:
/usr/sbin/php-java-bridge
and re-start the web server to activate this setting. The above
command starts 2 backends on the local host. Additional backends can
be started with (e.g.):
`
`php-config --extension-dir`/RunJavaBridge backend5.log
A multicast packet is send and the bridge selects the first backend
which has a load <12. If, for some reason, multicasts don't work on
your system you can use the java.hosts option instead. The following
example directs the bridge to two backends running on the local host:
java.hosts="127.0.0.1:9167;127.0.0.1:9168".
This option is available on Security Enhanced Linux.
OPTION 3: You can start the bridge as a sub-process of apache. Disable
java.hosts and java.socketname, stop all backends and re-start apache.
Check if apache has started java as a sub-process. For example with
the commands:
apachectl restart
pstree | fgrep httpd
Starting or re-starting the bridge with the apache web server is
convenient during development but not recommended for production
systems. This option cannot be used on Security Enhanced Linux.
Check the status:
echo "<?php phpinfo()?>" | php | fgrep "java status"
Other configuration options which should have been set up by the
configure script but which can be changed later are:
java.libpath = <system dependent path to natcJavaBridge.so>
java.classpath = <system dependent path to JavaBridge.jar>
java.java_home = <system dependent path to the java install dir>
java.java = <system dependent path to the java binary>
java.socketname= <hard-coded socketname to start the VM separately>
java.hosts = <add. bridge hosts e.g.: server1:9167;server2:9168>
Please first look at the output of phpinfo() to see the original
values.
The java.hosts setting specifies additional hosts running the
PHP/Java Bridge; it should be used only if multicast datagrams
don't work on your system.
---------------------------------------------
Starting the PHP/Java Bridge automatically
------------------------------------------
When the java.socketname option is not set, the web server will
start or re-start the bridge automatically as a sub-component when the
http service is started or re-started.
However, when running the bridge in a production environment, it is
recommended to start the PHP/Java Bridge as a system service,
independent of the web server. The script "php-java-bridge.service"
can be used on SysV based init systems to automatically start and stop
the bridge as a system service. Please see the RedHat RPM download
for an example.
---------------------------------------------
Deploying into a J2EE/EJB server or a
standard servlet engine
-----------------------------
[to be written for 2.0.7]
------------------------------------
64 Bit issues
-------------
It is possible to compile the bridge into 64 bit code:
phpize && ./configure --with-java=$JAVA_HOME
make CFLAGS="-m64"
The scripts expect that the default JVM found in
$JAVA_HOME/bin/java is a 64 bit VM. Unfortunately this is not true
for the SUN JDK (Linux and Solaris) installation. The SUN JDK
installs the 64 bit VM in some sub-directory of $JAVA_HOME/bin. On
Solaris9 this is $JAVA_HOME/bin/sparcv9. The location on Linux may
depend on the architecture.
Since there is no standard installation directory and we cannot
blindly search all sub-directories, it is your job to direct the
bridge to the 64 bit JVM. The relevant php.ini entry is java.java,
see install instructions above.
------------------------------------
Compiling a CGI binary on Windows
---------------------------------
This operating system has some unusal problems with shared libraries
(DLL's). The autoconf/libtool documentation states:
- Macro: AC_LIBTOOL_WIN32_DLL
This macro should be used if the package has been ported to build
clean dlls on win32 platforms. Usually this means that any
library data items are exported with `__declspec(dllexport)' and
imported with `__declspec(dllimport)'. If this macro is not used,
libtool will assume that the package libraries are not dll clean
and will build only static libraries on win32 hosts.
Until someone ports the sources to use __declspec, we avoid
creating shared libraries on this system. Instead we will
compile the extension into PHP:
1. Install the source code of PHP 4.3.x or higher.
2. Install RedHat's Cygwin (PHP needs autoconf).
3. Delete the java sub-directory from php-4.3.x\ext. Copy the
php-java-bridge directory to the php-x.y.z\ext directory and
rename it to java. Update the "m4_include" paths in
php-x.y.z\ext\java\config.m4 so that they start with "ext/java/":
m4_include(ext/java/tests.m4/function_checks.m4)
m4_include(ext/java/tests.m4/java_check_broken_stdio_buffering.m4)
...
m4_include(ext/java/tests.m4/java_check_broken_gcc_installation.m4)
4. Invoke autoconf to register our java module within the PHP build
tree:
buildconf.bat --force
Instead of running "buildconf" you can also use autoconf directly:
autoconf
Then configure and compile php as usual:
.\configure --with-java=%JAVA_HOME%
make
This will create a php binary with the PHP/Java Bridge included.
You can then copy the sapi\cgi\php executable into the CGI directory
of your IIS web server. Before you start the web server, you must
start the java bridge backend, for example by double-clicking on
.\modules\JavaBridge.jar.
Windows uses TCP/IP sockets instead of unix domain sockets. If you
want to change the java.socketname from its default (which is 9167),
you must use an integer. For example:
java.socketname=9168
------------------------------------
Loading on-demand with dl()
---------------------------
It is possible to load the bridge for each new request, for example
with:
<?php
if (!extension_loaded('java')) {
if (!dl("java.so")) {
exit(1);
}
}
phpinfo();
?>
However, this feature is meant for testing, only. For a production
system it is recommended to compile PHP in save mode (which switches
off the dl() function) and to activate all modules in the global
php ini file.
------------------------------------
Recognized CFLAGS
-----------------
During compilation you can use the following CFLAGS.
* -DJAVA_COMPILE_DEBUG: Enables the assert() statement and other
debug code.
* -DJAVA_COMPILE_DEBUG -O0 -g3: Include full debug information into
the binary.
* -m64: Build 64 bit code. Required if you run a 64 bit JVM.
* -m32: Build 32 bit code. Required if you run a 32 bit JVM on a 64
bit system.
* -DCFG_JAVA_SOCKET_INET: Disables local ("unix domain")
sockets on systems which support them.
Example: make CFLAGS="-m64"
------------------------------------
Log levels
----------
You can set the java.log_level to 5 values:
0: Log nothing, not even fatal errors.
1: Log fatal system errors such as "out of memory error".
2: Log java exceptions.
3: Log info messages such as "loading jar xyz.jar from http://xy.com"
4: Log debug messages, including the c/s communication protocol.
The default log level is 1.
---------------------------------------------
GCJ/GNU Java issues
-------------------
gcc3.4 cannot invoke virtual functions from jni code. Please apply
the gcc3.4-broken-jni-method-lookup.patch or use gcc 3.3.3 or gcc 4.x
instead.
Running the PHP/Java Bridge under GCJ/GNU Java is supported on Linux
and Solaris only. If you run FreeBSD 5.3, please use Sun, Blackdown
or IBM java instead.
------------------------------------
Security Enhanced Linux
-----------------------
SELinux is an implementation of a flexible and fine-grained
mandatory access control architecture implemented in the Linux kernel.
It is used in recent Linux distributions such as Debian or RedHat
Fedora Core 3.
A system component running on a SELinux kernel must declare
exactly a) which resources of the operating system it needs in order
to function properly and b) what it provides to other components.
The PHP/Java Bridge distribution contains two policy files,
"php-java-bridge.te" and "php-java-bridge.fc". The
"php-java-bridge.te" declares the javabridge_t domain and the
resources it requires. httpd and user domains are granted connect,
read and write to the PHP/Java Bridge server socket, which is
"@var/run/.php-java-bridge_socket" in the Linux abstract namespace,
and file create/read/write in the tmp_t. Everything else (connections
to other servers, file access, ...) is currently denied.
The "php-java-bridge.fc" contains the file contexts for the PHP/Java
Bridge and the log.
Installation:
-------------
The following discussion assumes that you have a RedHat Linux system
and you are running SELinux with the targeted policy.
1. Install selinux-policy-targeted-sources-*.rpm, for example with
the command:
rpm -i selinux-policy-targeted-sources-1.17.30-2.19.noarch.rpm
2. Update the policy files with the PHP/Java Bridge policy:
su -c "sh update_policy.sh /etc/selinux/targeted/src/policy"
If the default policy is too restrictive and e.g. you want to use the
PHP/Java Bridge to connect to your J2EE server(s), you can temporarily
set the policy to "permissive", for example with the command "setenforce
Permissive". Connect to the server, then extract the permissions
from the audit log, for example with the command "audit2allow -d", then
append them at the end of the "php-java-bridge.te" file and load the
updated policy into the kernel. Don't forget to switch back, for
example with "setenforce Enforcing".
------------------------------------
Loading user classes and libraries
----------------------------------
Although it is possible to manipulate the java.classpath to direct
java to individual classes, this "feature" should not be used.
Custom libraries should be stored in one of the system directories,
either /usr/share/java (or one of its sub-directories) or
java.libpath/lib (or one of its sub-directories) and they shall have
the following format: <name>-<version>.jar. For example:
/usr/share/java/batStore/batStore-1.0.jar.
The global repository /usr/share/java shall be used if the library
is for general interest, otherwise the java.libpath/lib repository may
be used. Please look up the java.libpath from the output
of the test.php or from phpinfo().
When Security Enhanced Linux is configured to allow the PHP/Java
Bridge to make HTTP URL connections to different servers or if
Security Enhanced Linux is switched off in the linux kernel, java
libraries may also be loaded from HTTP URLs.
Java libraries can be created from .class files with the following
command:
jar cvf myLibrary-0.1.jar *.class
The libraries can be linked into the php files at run-time with the
command:
java_require("<library1>;<libraryN>");
For example:
<?php
// process order
java_require("j2ee.jar;batStore/batStore-1.0.jar");
order(...);
?>
Since java does not yet support library versions, the PHP/Java
Bridge must be re-started when a new library version is deployed. This
means that the repositories shall contain only one version of batStore
at the same time. -- The ECMA 335 CLR supports this very well
so in theory the problem could be solved by compiling the .jar file
into a ECMA 335 dll (e.g. with the command: ikvmc batStore-1.0.jar)
and to use assembly loading instead, please see the
tests.mono+net/load_assembly.php for details).
------------------------------------
PHP 5 issues
------------
All PHP 5 versions < 5.0.4 crash when the dl() function is
used. They first unload the module and then try to invoke its
shutdown method.
If you use one of these versions, please add an entry to the
php.ini, see install instructions above.
------------------------------------
UTF-8
-----
Since PHP does not support Unicode the PHP/Java Bridge uses UTF-8 to
convert characters into the host representation. All strings are
created with new String(..., "UTF-8") and all internal String->byte[]
conversions use getBytes("UTF-8").
If you have old PHP files which are not UTF-8 encoded, you can
change the default encoding with java_set_file_encoding(). For
example:
java_set_file_encoding("ISO-8859-1");
For a list of available encodings please see the documentation of
the JVM's file.encoding system property.
The java_set_file_encoding() primitive only affects java.lang.String
creation and internal conversions, it does not alter the JVM's
file.encoding system property nor does it change the behaviour of
methods which use the file.encoding property, getBytes() for
example. If you use:
$str=new String("Cześć! -- שלום -- Grüß Gott -- Dobrý deň");
echo $str->getBytes();
the output conversion depends on the file.encoding system property
which in turn depends on the process' LANG environment variable. You
can check the file.encoding with the test.php script, see above.
Please see the utf8*.php tests in the tests.php4 folder to see how
to use different input and output conversions.
To be portable please do not use conversions which depend on the
JVM's file.encoding. They are easy to avoid, the above example
should have been written as:
$str=new String("Cześć! -- שלום -- Grüß Gott -- Dobrý deň");
echo $str;
------------------------------------
Mailing List
------------
Please report bugs/problems to the mailing list:
php-java-bridge-users@lists.sourceforge.net