|
|
LXIX. PHP / Java Integration
There are two possible ways to bridge PHP and Java: you can either
integrate PHP into a Java Servlet
environment, which is the more stable and efficient solution,
or integrate Java support into PHP. The former is provided by a SAPI
module that interfaces with the Servlet server, the latter by this
Java extension.
The Java extension provides a simple and effective means for creating and
invoking methods on Java objects from PHP. The JVM is created using JNI,
and everything runs in-process.
| Внимание | Это расширение является
ЭКСПЕРИМЕНТАЛЬНЫМ. Поведение этого расширения,
включая имена его функций и относящуюся к нему документацию, может
измениться в последующих версиях PHP без уведомления. Используйте
это расширение на свой страх и риск. |
You need a Java VM installed on your machine to use this extension.
Это расширение PECL
не поставляется вместе с PHP.
В PHP 4 исходные файлы этого расширения PECL
могут быть найдены в директории ext/ внутри исходных файлов
PHP или по ссылке PECL выше.
In order to use these functions you must compile PHP with Java support by
using the --with-java[=DIR] where DIR
points to the base install directory of your JDK. This extension can only
be built as a shared extension. Additional build extensions can be found
in php-src/ext/java/README.
Windows users will enable php_java.dll inside
of php.ini in order to use these functions.
В PHP 4 этот DLL находится в
директории extensions/ внутри директории бинарного
дистрибутива PHP для Windows.
Вы можете скачать DLL этого
расширения PECL со страницы
PHP Downloads или
http://snaps.php.net/.
Замечание:
In order to enable this module on a Windows environment with PHP <=
4.0.6, you must make jvm.dll available to your
systems PATH. No additional DLL is needed for PHP versions > 4.0.6.
Поведение этих функций зависит от установок в php.ini.
Таблица 1. Java configuration options | Name | Default | Changeable | Changelog |
|---|
| java.class.path | NULL | PHP_INI_ALL | | | java.home | NULL | PHP_INI_ALL | | | java.library.path | NULL | PHP_INI_ALL | | | java.library | JAVALIB | PHP_INI_ALL | |
Для подробного описания констант
PHP_INI_*, обратитесь к документации функции ini_set().
Данное расширение не определяет никакие типы ресурсов. Данное расширение не определяет никакие константы.
Пример 1. Java Example |
<?php
$system = new Java('java.lang.System');
echo 'Java version=' . $system->getProperty('java.version') . '<br />';
echo 'Java vendor=' . $system->getProperty('java.vendor') . '<br />';
echo 'OS=' . $system->getProperty('os.name') . ' ' .
$system->getProperty('os.version') . ' on ' .
$system->getProperty('os.arch') . ' <br />';
$formatter = new Java('java.text.SimpleDateFormat',
"EEEE, MMMM dd, yyyy 'at' h:mm:ss a zzzz");
echo $formatter->format(new Java('java.util.Date'));
?>
|
|
Пример 2. AWT Example |
<?php
$frame = new Java('java.awt.Frame', 'PHP');
$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();
?>
|
|
Notes:
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 useful as it provides access to classes
like java.lang.System which expose most of their
functionallity through static methods.
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.
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 of the class
(fields and methods) can be accessed.
Exceptions raised result in PHP warnings, and NULL results. The
warnings may be eliminated by prefixing the method call with an
"@" sign. The following APIs may be used to retrieve and reset
the last error:
Overload resolution is in general a hard problem given the
differences in types between the two languages. The PHP Java
extension employs a simple, but fairly effective, metric for
determining which overload is the best match.
Additionally, method names in PHP are not case sensitive, potentially
increasing the number of overloads to select from.
Once a method is selected, the parameters are coerced if necessary,
possibly with a loss of data (example: double precision floating point
numbers will be converted to boolean).
In the tradition of PHP, arrays and hashtables may pretty much
be used interchangably. Note that hashtables in PHP may only be
indexed by integers or strings; and that arrays of primitive types
in Java can not be sparse. Also note that these constructs are
passed by value, so may be expensive in terms of memory and time.
The Java Servlet SAPI builds upon the mechanism defined by the Java
extension to enable the entire PHP processor to be run as a servlet.
The primary advantage of this from a PHP perspective is that web servers
which support servlets typically take great care in pooling and reusing
JVMs. Build instructions for the Servlet SAPI module can be found in
php4/sapi/README.
Notes:
While this code is intended to be able to run on any servlet engine,
it has only been tested on Apache's Jakarta/tomcat to date. Bug
reports, success stories and/or patches required to get this code
to run on other engines would be appreciated.
PHP has a habit of changing the working directory. sapi/servlet will
eventually change it back, but while PHP is running the servlet engine
may not be able to load any classes from the CLASSPATH which are
specified using a relative directory syntax, or find the work directory
used for administration and JSP compilation tasks.
add a note
User Contributed Notes
PHP / Java Integration
Tom
23-Aug-2007 08:31
For those who have had the same problems with the php-Java Bridge,
here's a tutorial how to use the well supported soap extension to call Java methods:
http://rwatsh.blogspot.com/2007/03/
integrating-java-and-php-web-services.html
Since PHP5 soap extension is part of the PHP, so this is much easier to set up
than this php to java bridge, which crashed regularly.
Tom
Vikas Kumar
24-Jul-2007 10:46
wamp5_1.7.2.exe+jdk1.5.0_10 integration error
extension=php_java.dll
[java]
java.home="C:\Program Files\Java\jdk1.5.0_10; C:\Program Files\Java\jdk1.5.0_10\lib"
java.class.path="C:\wamp\php\ext\JavaBridge.jar; C:\Program Files\Java\jdk1.5.0_10\lib"
java.library.path="C:\wamp\php\ext; C:\Program Files\Java\jdk1.5.0_10\lib"
java.library="C:\Program Files\Java\jdk1.5.0_10\jre\bin\server\jvm.dll"
frey_thom76 at yahoo dot de
21-Apr-2006 06:16
The previous note is very misleading:
Switching from the Apache- to the CGI SAPI doesn't solve the fundamental problem that PHP4's ext/php_java continously allocates a new VM until the machine runs out of resources ("Fatal error: Unable to Create Java Virtual Machine")
The mentioned JavaBridge works well with PHP 4 (I use it since one year now)
It is not necessary to switch to Apache 2 to run PHP 4 and PHP 5 side-by-side
tobozo at phpsecure dot info
19-Apr-2006 08:06
Workaround for Win32 / Apache / PHP4 users that do not wish to switch from SAPI to CGI :
Java Bridge is a great project, and it's too bad I *have* to upgrade to php5 to see it working. One more reason not to use php5.
I have a production server running a few intranet applications and other php utilities, on a w2k platform with Apache-1.3.33 and php-4.3.10.
I need to have java working along with php on this production server, and I do not wish to upgrade all php applications to php5, nor do I wish to switch to Apache2 to get php4 and php5 running together.
So my choice went to ext/php_java. Of course I've had the usual issues ...
"Fatal error: Unable to Create Java Virtual Machine"
Basically the workaround for this thread issue is to " use CGI instead of SAPI "
But CGI is slower than SAPI, what about performances for all my applications ?
Well there is a (clumsy) solution : use both CGI and SAPI, keeping SAPI for the regular php work, and creating a new mime type and extension in the httpd.conf for the php files invoking java.
I chose to use the '.jhp' extension (yeah, sounds horrible but still, it's nicer than '.phava'), here's a copy of my settings :
my php.ini :
--------------
[Java]
extension=php_java.dll
java.class.path = C:\php4-Win32\extensions\php_java.jar
java.home = c:\jdk-1.5
java.library = c:\jdk-1.5\jre\bin\server\jvm.dll
my httpd.conf :
------------------
ScriptAlias /jhp/ "C:/php4-Win32/"
AddType application/x-httpd-jhp .jhp
Action application/x-httpd-jhp /jhp/php.exe
The Server :
--------------
Windows 2000 (fr) SP4
Apache/1.3.33 (Win32)
Php 4.3.10 (SAPI + CGI)
Java version=1.5.0_06
meaton53 at hotmail dot com
08-Mar-2006 11:46
I just wanted to post this for people that were having the same troubles that I was having. I am running OES SuSe Linux 9-1. I started this adventure because I needed to connect to a progress database via PHP. And I couldn't use ODBC drivers because the progress ODBC drivers were simply to old for unixODBC and iODBC (progress 9.1c). So I had to use JDBC with this wonderful PHP extension along with the PHP-Java Bridge found at:
http://sourceforge.net/projects/php-java-bridge
So Just for some notes, in the PHP.INI file I had to have:
extension=java.so
[java]
java.java_home=/usr/local/java
java.classpath=.:/usr/progress/dlc91c/java/progress.jar
:/usr/progress/dlc91c/java/jdbc.jar
java.libpath=.:/usr/progress/dlc91c/lib
:/usr/local/lib/php/extensions
And be careful because lots of sites tell you that the two varibles above are java.class.path, and java.library.path.
And also to be able to connect to a progress database from java in Linux you have to set your LD_ASSUME_KERNEL varible to 2.4.0 to do this simply add to you profile.local file:
export LD_ASSUME_KERNEL=2.4.0.
If you want to know why please email me and I will tell you.
rabisultan at gmail dot com
07-Feb-2006 07:40
If you get this error
Fatal error: Unable to create Java Virtual Machine in
it can be fixed by modifying your php.ini file, you will need to add in the path to the JRE's lib folder.
My php.ini file (php4/Apache2):
java.class.path= "e:\minerva\php\extensions\php_java.jar; c:\j2sdk1.4.2_08\jre\lib; C:\j2sdk1.4.2_08"
java.home = "c:\j2sdk1.4.2_08\bin; c:\j2sdk1.4.2_08\jre\lib"
java.library = "c:\j2sdk1.4.2_08\jre\bin\server\jvm.dll"
java.library.path= "e:\minerva\PHP\extensions; c:\j2sdk1.4.2_08\jre\lib"
m mokhtar at gmail dot com
30-Oct-2005 11:03
Getting PHP JavaBridge to work with PHP5 on windows server:
====================================
1- Install Java J2EE 1.5 + JDK 1.4 (which includes application server/deploy tool/etc...)
2- download pecl-5.0.5-Win32.zip and php-java-bridge_2.0.8.zip, which will include
extra dll(s)
- unpack pecl pkg to your extensions folder, in PHP5 its ext.
- unpack java-Bridge to root php folder, in my case its simply C:\PHP
Note: the java-Bridge inculdes new versions of certain files like php_java.dll
so, it would be wise to rename your old files that came with PECL pkg for example
file_old, to rollback at anytime.
In order to deploy/test Java-Bridge .war onto your java application server follow these steps
http://cvs.sourceforge.net/viewcvs.py/php-java-bridge/php-java-bridge/
INSTALL.WINDOWS?view=markup
Note: move JavaBridge.jar to your extensions folder. and in test.php file that came
with Java-Brdige package change line java_require("test/arrayToString.jar");
to java_require("tests.php4/arrayToString.jar");
Add the following to your php.ini file and restart server:-
java.classpath = "location of JavaBridge.jar file...i.e. to your PHP extensions folder\
JavaBridge.jar,also any other extra java files that you'll be instanciating using your php script"
java.java_home = "location of jdk\bin"
java.libpath = "location of php_java.dll file...i.e. also to your PHP extensions folder"
happy integration
Cheers!!
beoran at gmail dot com
25-May-2005 05:24
The php-java-bridge mentioned below is indeed the way to go. It also works fine on a php 4.3.2 Linux web server. I think I can reccomend it.
ing dot ldf at gmail dot com
06-May-2005 11:38
Reading the other post... i can run java with php.
OS: Win 2000p
PHPDev 4.2
Java j2sdk1.4.2_01
my php.ini file is set like this:
[Java]
java.class.path = "C:\php\php\extensions\php_java.jar; C:\j2sdk1.4.2\jre\lib;C:\j2sdk1.4.2;"
java.home = "C:\j2sdk1.4.2_01\bin"
java.library = "C:\j2sdk1.4.2_01\jre\bin\server\jvm.dll"
java.library.path = "C:\php\php\extensions"
I have a great doubt about this..... JVM runs fine the first time, then broke.... and send a message like this:
Fatal error: Unable to create Java Virtual Machine in localhost\pag1.php on line 37
jost2345 at yahoo dot de
31-Aug-2004 05:08
The PHP/Java bridge that has been posted some time ago is now available on sourceforge.net. It contains several bugfixes and is meant to be used as a replacement for the expermental PHP4 java bridge.
http://sourceforge.net/projects/php-java-bridge/
So please don't send me private e-mails anymore to obtain the sourcecode for the bridge.
PHP/5 users may want to wait for the official PHP/Java bridge, which I expect to appear in a few years when java contains the appropriate hooks.
okapi at yahoo dot com
26-Aug-2004 10:05
As mentioned prior, Zend is working to be the first of an official servlet / scripting integration. I've been testing their reference implementation that's available on the JSR 223 site and it's working pretty good. Some minor issues around the edges, but been working with one of their developers to fix it. So far, pretty good.
drgroove at myway dot com
07-Aug-2004 04:33
@ smc+phpman
Zend/PHP is likely awaiting the finalization of JSR223, which seeks to allow scripting languages a much clearer form of communication to/from Java.
http://jcp.org/en/jsr/detail?id=223
This is a joint effort between Sun & Zend, among others. PHP will be the first language supported out of this JSR effort, others (such as Perl) will follow.
- DrGroove
Moderator, Devshed.com PHP forum
a9702466 at gmx dot net
03-Mar-2004 09:08
The Java Servlet SAPI works fine in a non-threading
environment. If you want to use threads (normal case) you
have to do several things to get it work:
- get the patched files from
http://www.pelikan-it.com/download.html
- replace the sapi/servlet/servlet.java and
sapi/servlet/servlet.c file by the patched files
- build the php like this
./configure --with-tsrm-pthreads \
--with-servlet=/opt/resin --with-java=/opt/java \
--prefix=/opt/php-4.3.4
The primary problem is, that the request and response
objects are stored as global instance-variables of the servlet
which will be overwritten by other threads invoking the
servlet (remember: just on servlet-object for all threads!) and
all crashes. I changed the servlet to pass the request and
response objects to the java- and native-methods (where
required) to prevent the problem.
Once you have solved this problem it works fine and needs
unlike the java-extension just one jvm.
norman at junkonline dot com
29-Feb-2004 04:16
This works fine on MacOS X (Panther). The one trick is, you need to symlink "java.so" in your php extensions directory to "libphp_java.jnilib".
Here's the relevant section from my php.ini file for anyone who needs it:
[Java]
java.class.path = "/usr/local/lib/java/php_java.jar"
java.home = "/System/Library/Frameworks/JavaVM.framework/Versions/1.4.2/Home"
java.library.path = "/usr/local/lib/php/extensions/no-debug-non-zts-20020429"
extension=java.so
You may have decided to put php_java.jar somewhere other than where I did.
For some reason, setting java.library in the ini file causes this to fail, so I left it out and things worked flawlessly without it. YMMV.
Thomas
25-Feb-2004 07:44
The documentation is missing an important note:
The PHP/JAVA bridge only works on threaded http servers such as IIS, it does NOT work on http servers such as APACHE which fork off (sub-)processes.
The reason for this is that for each new request APACHE fork()'s off a new and independed copy of itself, initializes the java VM and eventually passes control over to VM until the request is finished. If the request is finished, the child with the java VM go to the apache pool.
That means that after a while hundreds (up to MAX-PROCESSES) of java VM's are in the apache pool each of them eating away up to 64MB. The machine may sooner or later crash because it ran out of memory. (If you have luck, the bridge will not run at all because apache was not statically linked to the pthreads library).
Although another PHP/Java bridge exists that does not have this problem (do a google search for "A new PHP/JAVA module"), the java binding (used by both bridges) has also problems one must be aware of. For example if one creates a Properties() object, one will receive a reference to it and may ask this reference for its values. However, if one invokes a method that returns a Properties() object, one will receive an array of values, not a reference to the Properties() object.
In short: If you want to use java from php in IIS, you can use this bridge. BUT if you want to use java from php in APACHE, you must use a socket approach (for an example see "A new PHP/JAVA module").
georgedaswani at hotmail dot com
02-Feb-2004 02:39
I was able to compile java support in no problem and got it working sun jdk 1.4.2_03 (linux)
make sure JAVA_HOME is set
make sure LD_LIBRARY_PATH has
$JAVA_HOME/jre/lib/i386
on php.ini
[Java]
java.home = "/opt/j2sdk1.4.2_03"
java.class.path = "/opt/php/lib/php/php_java.jar:/opt/php/java-packages"
java.library.path = "/opt/php/lib/php/extensions/no-debug-zts-20020429"
extension_dir= "/opt/php/lib/php/extensions/no-debug-zts-20020429"
extension = java.so
It's import to note that APACHE 2 needs to be compiled using "PREFORK" instead of a thread based else the java stuff will work for a minute, then stop working with the following error
"PHP Fatal error: Unable to create Java Virtual Machine"
Seems that the extension is not thread safe.
golob a with tail gimb little spot org
03-Jun-2003 06:57
This module allows PHP to interact with some interesting pieces of software - for one, it allows PHP to convert XML FO files into PDF/PS/... with the use of Apache FOP processor.
Here's an example:
<?
$basedir = new Java("java.io.File", ".");
$outdir = new Java("java.io.File", "out");
$outdir->mkdirs();
$fofile = new Java("java.io.File", $basedir, "xml/fo/helloworld.fo");
$pdffile = new Java("java.io.File", $outdir, "ResultFO2PDF.pdf");
echo "Input: ".$fofile->toString()."\n";
echo "Output: ".$pdffile->toString()."\n";
$driver = new Java("org.apache.fop.apps.Driver");
$logger = new Java("org.apache.avalon.framework.logger.ConsoleLogger");
$driver->setLogger($logger);
$driver->setRenderer($driver->RENDER_PDF);
$out = new Java("java.io.FileOutputStream", $pdffile);
$driver->setOutputStream($out);
$in = new Java("java.io.FileInputStream", $fofile);
$driver->setInputSource(new Java("org.xml.sax.InputSource", $in));
$driver->run();
$in->close();
$out->close();
?>
raggha at hotmail dot com
13-Jan-2003 02:45
Just wanted to make available the solution I found posted on
http://bugs.php.net/bug.php?id=18600
to solve the typical "Fatal error: Unable to Create Java Virtual Machine" trouble for Win32 users (thanks buddy):
[12 Dec 2002 9:19am] Alberto.Sarini@libero.it
Hi there,
I'm confirming C
|
|