php-java-bridge NEWS -- history of user-visible changes.

Please send bug reports, questions and suggestions to
<php-java-bridge-users@lists.sourceforge.net>.

Version 3.1.0:

* The windows default location has been changed from c:\php5 to
c:\php.

* The servlet SAPI now supports HTTPS. The default communication port
is 127.0.0.1:9157 (see java.hosts in the WEB-INF/.../php*.ini). For
tomcat for example add the following entry marked with a + to the
conf/server.xml:

  <Service name="Catalina">
  [...]
+  <Connector port="9157" address="127.0.0.1"/>
  [...]
  </Service>

* The extension_dir/lib directory is no longer scanned by the
DynamicJavaBridgeClassLoader. All Java .jar and .class files located
in this directory are added to the system class path when the virtual
machine starts. This means that this directory can now contain impure
java libraries (=libraries which use the java native interface). But
this also means that the dynamic loader doesn't know whether a lib in
this directory has been changed or added unless this lib has been
required using `java_require("lib.jar")' or with
`require_once("lib/class_Name.php")', which uses java_require()
internally.

* The ikvmc.exe and ICSharpCode.SharpZipLib.dll IKVM.AWT.WinForms.dll
IKVM.GNU.Classpath.dll IKVM.Runtime.dll are now included. This means
that it is now possible to access .NET dll's without installing
additional software; ./configure --with-mono && make && make install is
enough to load/call .NET or Mono .dlls from PHP -- .NET or Mono must
be installed, of course.

* It is now possible to convert Java libraries into PHP code. 
For example the command java -jar JavaBridge.jar --convert
/usr/share/pear lucene.jar creates PHP lucene classes from
the Java lucene.jar. When the PHP/Java Bridge has been configured to
run without Java (./configure w/o the "--with-java" argument), the
created PHP lucene classes can be used directly from PHP code, Java is
not needed anymore. Only the java.so or php_java.dll file and the
generated Lucene PHP classes are required, for example:

<?php
require_once("lucene/org_apache_lucene_search_IndexSearcher.php")
require_once("lucene/org_apache_lucene_search_PhraseQuery.php")
require_once("lucene/org_apache_lucene_index_Term.php")

$searcher = new org_apache_lucene_search_IndexSearcher(getcwd());
$term = new org_apache_lucene_index_Term("name", "test.php");
$phrase = new org_apache_lucene_search_PhraseQuery();
$phrase->add($term);

$hits = $searcher->search($phrase);
$iter = $hits->iterator();

while($iter->hasNext()) {
  $next = $iter->next();
  $name = $next->get("name");
  echo "found: $name\n";
}
?>

* A binary RPM for RHEL3 is not available anymore. If you want to
install the bridge on RHEL3 please create a binary RPM from the source
RPM.

* Persistent connections: If "java.persistent_connections" is set to
"On", the Apache/Tomcat5 combination delivers a PHP/Java based mix more
or less as fast as Tomcat would deliver an equivalent JSP file.

* Log4j added: If java.log_file is not set, the bridge uses log4j, if
available. The default appender is log4j "chainsaw" (a stupid name for
a log viewer) listening on localhost:4445. Other appenders, for
example jdbc, can be configured by overriding ChainsawLogger.configure
or by calling Util.setLogger(ILogger).

* Improved dynamic loading: java_require(file) is now fail fast. It
checks if local jar files do exist and are accessible. However, urls
are loaded lazily. If the urls could not be loaded, the java_require()
call succeeds but one will receive a ClassNotFoundException later on.

For example:

// java_require(file) is fail fast
try {
  java_require("/usr/share/java/doesNotExist.jar"); // fails
} catch (JavaException $ex) {
  echo "doesNotExist library not installed\n";
  echo $ex->getCause();
}

// java_require(url) is lazy
java_require("http://doesNotExist.com/foo.jar"); // succeeds
...
try {
  $foo = new Java("foo");                        // fails
} catch (JavaException $ex) {
  echo "http://doesNotExist.com/foo.jar:foo.class could not be loaded\n";
  echo $ex->getCause();
}

* A standard global repository for java libraries has been added. The
standalone back-end adds the following standard extension directories
to java.ext.dirs: "/usr/java/packages/lib/ext" and
"/usr/share/java/ext" and, for backward compatibility,
extension_dir/lib (or extension_dir\lib, on windows). All java
libraries located in these directories are loaded
automatically. Example:

# copy log4j.jar to the java.ext.dirs:
cp log4j.jar /usr/share/java/ext

# start the log4j viewer
java -classpath log4j.jar org.apache.log4j.chainsaw.Main &

# start the JavaBridge, the bridge automatically loads log4j and
# writes its log to the running log4j viewer.
java -jar JavaBridge.jar &

* It is now possible to lock the standalone VM so that certain users
cannot (accidently) create arbitrary files, open connections to other
hosts etc. The file "javabridge.policy" has been added to the
standalone container, a default file is located in the extension
directory and denies almost everything. The policy file can be edited
by using the java jdk "policytool". The new option
java.security_policy can be used to set a custom policy file. Example:
java.security.policy="c:/php5/javabridge.policy".  The following
javabridge.policy file example shows how to allow all users to start
threads and call System.exit():

grant {
  permission java.util.PropertyPermission "*", "read";
  permission java.net.SocketPermission "*", "accept, resolve";
  permission java.lang.reflect.ReflectPermission "suppressAccessChecks";

  permission java.lang.RuntimePermission "exitVM";
  permission java.lang.RuntimePermission "modifyThreadGroup";
  permission java.lang.RuntimePermission "modifyThread";
};

* Long-running background threads which were started from the
request-handling JavaBridge thread now receive an InterruptedException,
when the JavaBridge request-handling thread terminates. Long-running
threads such as printer jobs should catch this signal and terminate
as soon as their job is done.


Version 3.0.8:

* When the tomcat or J2EE JavaBridge.war "back-end" is used without an
Apache or IIS front-end, the JavaBridge context now starts a FastCGI
server automatically. This improves performance by more than 300% and
makes the Apache or IIS front-end obsolete. But it requires that 
php-cgi supports FastCGI. If a FastCGI PHP binary is not available,
the first request hangs 1.5 seconds until the FastCGIServlet times
out, the FastCGIServlet is switched off and the normal PhpCGIServlet
takes over. The JavaBridge.war contains FastCGI PHP binaries for
Solaris and Linux. Windows users must compile a FastCGI PHP executable
themselves.

* Security Enhanced Linux modules are supported. FC5 and RHEL5
introduce a SELinux reference policy with support for binary modules.
The old monolithic policy files have been moved to the security
folder, the new policy files are in security/module and are installed
automatically, if install.sh or RPM binaries are used.

* When arrays are passed to procedures or constructors which accept a
collection, the bridge now preserves the element order (a TreeMap is
used as the backing data structure). However, when one of the array
keys is not an exact number (which means that the php array is not an
array but a dictionary), the bridge discards the TreeMap and copies
all bindings into a HashMap data structure and the order of the
elements is not preserved. Example:

echo new java("java.util.Vector", array(1,2,3));
=> [o(Vector):"1,2,3"]

echo new java("java.util.Vector", array(1,2,"foo"=>3));
=> [o(Vector):"3,1,2"]

echo new java("java.util.HashMap", array(1,2,"foo"=>3));
=> [o(HashMap):{"foo"=3,0=1,1=2}]

* It is now possible to selectively switch off the servlet pipe
context server (-Dphp.java.bridge.no_pipe_server=true) and the
socket context server
(-Dphp.java.bridge.no_socket_server=true). Useful for testing
only.

* Some JVM implementations cannot load native libraries more than
once. When the backend is not running within the GNU java VM ("gcj"),
the dynamic loader does no longer try to load native libraries. 
Modify the java.libpath and the java.classpath settings instead,
e.g.: java.libpath=/usr/lib/php/modules:/usr/local/lib
java.classpath=/usr/lib/php/modules/JavaBridge.jar:/usr/local/lib/jni.jar
or read the documentation of your application server for more information.

* Improved automatic start: On windows it is now possible to use a
wrapper binary, for example: java.wrapper="c:/startJava.cmd",
additional options can be set with (example): java.java="javaw
-Dadd.option". On unix the bridge does no longer "busy wait" for the
backend. It uses select so that the startup time for the php-cli
(including the startup time for the backend) is now less than 100ms,
if a native (compiled) backend is used.

* It is now possible to run php interactively. Example session which
uses jdk1.6 "jrunscript":
# install php-java-bridge*.rpm and php-java-bridge-devel*.rpm
/opt/jdk1.6/bin/jrunscript -l php-interactive
php-interactive> $buf = new java("java.lang.StringBuffer", "Hello");
php-interactive> echo $buf;
[o(StringBuffer):"Hello"]
php-interactive> echo "$buf";
Hello
php-interactive> for($i=0; $i<10; $i++) $buf->append($i);
php-interactive> echo $buf->toString()->length();
15

* A "stream" protocol mode has been added. All java bridge XML
requests between java_begin_document() and java_end_document() are
executed asynchronously. Even for local (unix-domain or pipe) channels
this improves performance dramatically. Compared with SOAP, which
usually sends the XML document in one packet, this mode uses less
resources on the web-server side.

* An install script can be used to install the bridge and the backend:
su -c "sh install.sh --verbose"


Version 3.0.7:

* ./configure --with-java=/opt/compile-time/java,/opt/run-time/java:
it is possible to compile a jre runtime path into the bridge. The
default is empty, i.e. the PATH environment variable will be searched
if the bridge has been set up to automatically start the backend.

* When RunJavaBridge is used, it is possible to start the backend with
a non root uid. For example:

  chown apache:apache /usr/lib/php/modules/RunJavaBridge
  chmod 6111 /usr/lib/php/modules/RunJavaBridge

and java.wrapper = /usr/lib/php/modules/RunJavaBridge in the php.ini
(default is: <extension_dir>/RunJavaBridge) will automatically start
the backend as the apache user.
    
* It is now possible to compile the php java extension without java:
./configure --disable-backend creates only the java.so or php_java.dll.

* java => 1.4.2 is required.

* The windows standalone download is not available anymore. The
php_java.dll is now called "java-x86-windows.dll" and can be found in
the JavaBridge.war download.

* The Linux standalone backend has been removed from the
php-java-bridge RPM download. The linux java.so is now called
"java-x86-linux.so" and can be found in the JavaBridge.war download.

* The Linux RPM has been split into 4 separate RPM files:

  php-java-bridge*.rpm: contains the basic files; java extension for
  PHP/Apache HTTP server and a simple backend which automatically
  starts and stops when the HTTP server starts/stops. The bridge log
  appears in the http server error log.

  php-java-bridge-standalone*.rpm: contains the standalone service
  script. Conflicts with the tomcat backend. The tomcat backend is more
  than 2 times faster but less secure; it uses named pipes instead of
  abstract local "unix domain" sockets. The standalone backend is now
  started as the apache user.

  php-java-bridge-tomcat*.rpm: contains the tomcat backend. Conflicts
  with the standalone backend.

  php-java-bridge-devel*.rpm: contains the development documentation
  and the development files needed to create java applications with
  embedded PHP scripts: JavaBridge.jar, script-api.jar and php-script.jar.

* The JavaBridge.war now contains php 5.1.2 binaries for Solaris
(x86), Linux (x86 and ppc64), Windows (x86).

* php4 is supported again (switch to php5 or php6, if you can).


Version 3.0.3:

* Communication via named pipes: When the backend is running inside a
  Unix servlet engine or application server, the bridge uses named pipes
  instead of TCP sockets. This communication channel is 1.5 times faster
  than unix domain sockets and 2 times faster than TCP sockets. TCP
  sockets are still used on systems which do not support standard Unix
  named pipes (Windows).

* Because of the above change the bridge now works with the "Sun Java
  System Application Server Platform Edition 8" on Unix.

* TCP sockets only listen on the local (127.0.0.1) interface unless
  the system property "php.java.bridge.promiscuous" is set to true.

* The apache jsf "myfaces" implementation, which caused problems with
  various application servers or servlet engines, has been replaced by
  JSF 1.1.01.

Version 3.0.2:

* Backward compatibility with 2.0.8: The java.servlet can now have
  three values:

    On  : Selects the default servlet context, which is
          /JavaBridge/JavaBridge.php

    Off : Switches off the HTTP tunnel

    User: Selects the "current" servlet context. A request:
          http://foo.com/context1/test.php connects test.php to the
          backend: http://<java.hosts[0]>/context1/test.phpjavabridge. 

          Example:
          [java]
          java.hosts=127.0.0.1:8080
          java.servlet=User

          Request:
          http://foo.com/contextA/order.php

          Then order.php sends a PUT request to the backend:
          http://127.0.0.1:8080/contextA/order.phpjavabridge
      
* The servlet mapping for PhpJavaServlet has been
  removed. java.servlet=User or
  java.servlet=/JavaBridge/PhpJavaServlet.phpjavabridge can be used instead.

* When the java VM was started as a child of apache (OPTION#3) and
  apache sent out a kill signal to all childs in its process group, the
  guard process (which observes the VM) could be killed. After that one
  had to kill the java child manually. Since version 3.0.2 the guard
  detaches from the apache process group, too

* The PHP5/PHP6 array access and iterator interface should be much
  faster now. Especially the array access was incredibly inefficient
  as it allocated a new instance of PhpMap for each access.


Version 3.0.1:

* JSR223 API: It is now possible to run php scripts from java. Scripts
  are invoked using a CPS style, a CGI binary is started if necessary
  (if Apache/IIS are not running).

   Example:

   PhpScriptEngine engine = new PhpScriptEngine();
   engine.put("key", "testVal");
   // Hold the script from 127.0.0.1:80 (Apache pool) hostage ...
   engine.eval(new URLReader(new URL("http://127.0.0.1:80/HelloWorld.php")));
   // ... call the php procedure HelloWorld.php::java_get_server_name() ...
   System.out.println(((Invocable)engine).call("java_get_server_name", new Object[]{}));
   // ... and release the script.
   engine.release();

  See the configure option --enable-script.

* Java Server Faces: It is possible to embed php scripts into
  frameworks. Requires php-faces.jar (see configure option
  --enable-faces=<myFaces.jar>). The implementation works with the RI
  and Apache myfaces implementation (included in the unsupported
  folder). See examples/java-server-faces for details.

* PHP 4 is no longer supported (the bridge still works with php4).

* The bridge no longer coerces return values. If you want to 
  cast a java string into a php string, use the cast operator, e.g:

    $string = new java("java.lang.String", "{HelloWorld}");
    $substring = $string->substring(1);
    $substring = $substring(0, $substring->length()-1);

    echo "Result: $substring"; // implicit cast
    echo (string)$substring;   // explicit cast
  
* When running in a servlet engine or application server, the bridge now
  supports a multi-user environment. Example tomcat setup which contains:

    webapps/userA/...
                  WEB-INF/lib/{JavaBridge.jar,php-servlet.jar}
                  WEB-INF/cgi/{php.ini,php-cgi-i386-linux.sh,java.so}
                  {sessionSharing.php,sessionSharing.jsp}
    
    webapps/userB/...
                  WEB-INF/lib/{JavaBridge.jar,php-servlet.jar}
                  WEB-INF/cgi/{php.ini,php-cgi-i386-linux.sh,java.so}
                  {sessionSharing.php,sessionSharing.jsp}


  Browser request for:

    http://myhost.com/userA/sessionSharing.php
    http://myhost.com/userA/sessionSharing.jsp

  Creates cookie with a PATH value: path=/userA


  Same browser request for:

    http://myhost.com/userB/sessionSharing.php
    http://myhost.com/userB/sessionSharing.jsp

  Creates cookie with a PATH value: path=/userB

  
* An administrator may setup a FastCGI PHP server or Apache/IIS as a
  frontend so that users don't have to copy their own php binaries into
  their WEB-INF/cgi/ folder. 
 
  1) Example: Apache/IIS/mod_jk connector:


  internet
  clients  <->  :80--->  Apache/IIS                          --->  J2EE AS
                            |    |                          /  /    |   |
                            |   mod_jk <-- jsp/servlet req./  /     |   |
                            |                                /     jsp  |
                            ---- php                        /           |
                            ---- php  <-- P-J-B PROTOCOL --/           servlet
                                 ...                                     ...

  J2EE port not visible to internet clients. Apache/IIS document root
  not used.

    
  2) Example: a shared document directory:


                :80--->  Apache/IIS
            /                |
           / php req.        ---- php
          /                  ---- php  <--| 
                                  ...     |
  internet                                |
  clients                                 |
          \                               |P-J-B
           \jsp/servlet req.              |PROTOCOL
            \                             |
                                          |
           |--> :8080--> J2EE AS          |
           |                 |            |
           |                 ---- jsp     |
           |                 ---- servlet |
           |                      ...     |
           -------------------------------|

  Apache/IIS and J2EE ports are accessible from the
  internet. Apache/IIS and the J2EE AS share the same document root.

  #2 is the recommended setup. Framework requests (e.g.: hello.jsf)
  go to port 8080, initial requests to :80 can be forwarded to the
  framework using the following php code:

  <?php
  // hello backing implementation
  function jsfValidateEntry(...) {...}
  ...
  // check if we're called from the JSF framework, redirect to
  // self.jsf otherwise.
  function redirect() {
    $target=dirname($_SERVER['PHP_SELF']);
    $name=basename($_SERVER['PHP_SELF'], ".php");
    header ("Location: http://$_SERVER[HTTP_HOST]:8080$target/$name.jsf");
  }
  java_context()->call(java_closure()) || redirect();
  ?>
