FAQ
Hi,

I'm trying to use the PHP / Java integration (the module in ext/java).
My problem is that the Java Virtual Machine is thrown out regularly by
the PHP engine.

What happens is that the function jvm_create() gets called regularly
when requesting new pages using the Java extension, from the function
java_call_function_handler():

    if (!JG(jenv)) jvm_create(TSRMLS_C);

It seems that JG(jenv) gets to be 0 every once in a while. One problem
is that on none such occasion is jvm_destroy() called, which could lead
to resource leaks.

What I'm looking for is that the JVM would not be discarded on a regular
basis, but it would remain persistent. Unfortunately I can't find the
mechanism that removes it (so as to disable it).

I was looking at the documentation for extending PHP, especially at
http://www.php.net/manual/en/phpdevel.php#phpdevel-addfunc-reslist
Maybe this is the way to go? If so, can someone elaborate on the use of
this functionality? I can't really grasp how to use this based on the
description there (i.e. what does 'type of resource' mean, etc.)


Akos

Search Discussions

  • Ivan Ristic at Dec 4, 2002 at 2:27 pm

    What I'm looking for is that the JVM would not be discarded on a regular
    basis, but it would remain persistent.
        I do not think that is possible, unless PHP engine itself
        is contained within a single process (and runs multithreaded).
        Which it isn't (under Apache 1.x & , at least).

        You can perhaps try to use it the other way around, have PHP
        run inside a Java VM. You can also try to get the source code
        for the Java extension from the CVS as some patches have
        been submitted recently.

        Ideal solution for Java integration would be to have a single
        JVM running as a separate process, and to have the PHP communicate
        with it using some efficient protocol. This can be done right
        now although I do not think that the current Java extension
        works like this. However...

        I have "heard" (can someone confirm this, please) that ZE2
        handles foreign (i.e. non-PHP) object nicely and that you
        will be able to have classes and objects that feel like
        normal object but would in fact execute outside the engine.

        If the above is correct I would prefer to wait for ZE2 in
        order to integrate my PHP and my Java. On a similar note,
        is someone working on a ZE2-compatible extension at the
        moment? I might be interesting to work on it.

        There is one relevant project, see http://www.vl-srm.net
        (integrates PHP and PHP, not PHP and Java, but the method
        is the same).

    Bye,
    Ivan
  • Akos Maroy at Dec 4, 2002 at 2:47 pm

    Ivan Ristic wrote:
    I do not think that is possible, unless PHP engine itself
    is contained within a single process (and runs multithreaded).
    Which it isn't (under Apache 1.x & , at least).
    I'm not familiar in general with the PHP engine, so my questions may be
    quite stupid. Anyway:

    How is a persistent database connection handled then? e.g. in the mysql
    module?

    looking at the mysql module source code, it seems that there is a list
    called persistent_list, used in such a manner:

    zend_hash_find(&EG(persistent_list), hashed_details,
    hashed_details_length+1, (void **) &le

    would this provide some persistnece? If yes, how to use it exaclty? (I
    couldn't make it work myself.)


    It seems to me that libphp_java.so is unloaded every once in a while.
    For example, global static variable defined in the module get
    re-initialized every once in a while. Is this so?


    I can't see a call to JNI_DestroyJavaVM() anywhere in the java module
    source code. Isn't this a possible reason for resource leaks? Or are
    modules that cleverly unloaded?


    Akos
  • Brad LaFountain at Dec 4, 2002 at 3:25 pm

    --- Akos Maroy wrote:
    Ivan Ristic wrote:
    I do not think that is possible, unless PHP engine itself
    is contained within a single process (and runs multithreaded).
    Which it isn't (under Apache 1.x & , at least).
    I'm not familiar in general with the PHP engine, so my questions may be
    quite stupid. Anyway:

    How is a persistent database connection handled then? e.g. in the mysql
    module?

    looking at the mysql module source code, it seems that there is a list
    called persistent_list, used in such a manner:

    zend_hash_find(&EG(persistent_list), hashed_details,
    hashed_details_length+1, (void **) &le

    would this provide some persistnece? If yes, how to use it exaclty? (I
    couldn't make it work myself.)


    It seems to me that libphp_java.so is unloaded every once in a while.
    For example, global static variable defined in the module get
    re-initialized every once in a while. Is this so?
    Are you sure its getting unloaded or is it starting up in another httpd?

      - Brad



    __________________________________________________
    Do you Yahoo!?
    Yahoo! Mail Plus - Powerful. Affordable. Sign up now.
    http://mailplus.yahoo.com
  • Maróy Ákos at Dec 4, 2002 at 3:38 pm

    Brad LaFountain wrote:
    Are you sure its getting unloaded or is it starting up in another httpd?
    I'm not sure which. The only thing I see is that global static variables
    in the shared object have their values re-initialized.


    Akos
  • Ivan Ristic at Dec 4, 2002 at 4:22 pm

    How is a persistent database connection handled then? e.g. in the mysql
    module?
        Apache 1.x pre-creates a number of server processes. Each process
        handles a certain number of requests (one at a time), and then
        dies. It is then replaced with an another server process. The number
        of processes can vary depending on the load and the configuration.

        Database connections (and other resources) are persistent on the
        per-server-process level. What this means that an open connection
        in one server process cannot be reused from within another
        server process.

        When using PHP with IIS, on the other hand, you only have one
        process and only one set of persistent connections.

        Since creating a 100% thread safe PHP (PHP meaning the core engine
        plus the libraries) is practically impossible, I would say that
        PHP will go the FastCGI route, even on Windows.

    Bye,
    Ivan
  • Akos Maroy at Dec 5, 2002 at 9:12 am

    Ivan Ristic wrote:

    How is a persistent database connection handled then? e.g. in the
    mysql module?


    Apache 1.x pre-creates a number of server processes. Each process
    handles a certain number of requests (one at a time), and then
    dies. It is then replaced with an another server process. The number
    of processes can vary depending on the load and the configuration.

    Database connections (and other resources) are persistent on the
    per-server-process level. What this means that an open connection
    in one server process cannot be reused from within another
    server process.
    I see. This is sad news indeed. But is this really a closest one can get
    with apache? None of the other extension libraries for apache, like
    nsapi, provides the notion of persistent resources shared among all
    apache requestst?


    Akos
  • Ivan Ristic at Dec 5, 2002 at 9:54 am

    Database connections (and other resources) are persistent on the
    per-server-process level. What this means that an open connection
    in one server process cannot be reused from within another
    server process.
    I see. This is sad news indeed.
        From the web serving point of view it isn't. Since Apache usually
        interfaces to all kinds of modules and programs, the fact that
        processes die naturally from time to time helps remove cumulative
        errors.

        From the PHP point of view, you can get problems with persistent
        database connections on a very high load site, that's true. But
        that's about the only problem. Sure, you can't build a persistent
        storage of information in the server but that's a minor issue.

    But is this really a closest one can get
    with apache? None of the other extension libraries for apache, like
    nsapi, provides the notion of persistent resources shared among all
    apache requestst?
        No. The only way to do it is to get away from Apache processes
        and use Apache only as an interface to your single process. This
        is how all Java servlet containers do it. Take a look at Jserv
        (called mod_jk these days).

        I once hacked Jserv to work with my C++ application, that was fun.
        It worked (as a single persistent process) but I have found that
        the speed was about the same as the CGI version of the same
        thing (under moderate usage and working with MySQL) that the
        additional trouble of having a different process that you have
        to start and monitor, plus make sure that you free memory
        correctly and handle multithreading - is simply not worth it.

        (BTW, isn't nsapi the API for the Netscape web server?)

    Bye,
    Ivan
  • Maróy Ákos at Dec 5, 2002 at 10:05 am

    Ivan Ristic wrote:
    From the web serving point of view it isn't. Since Apache usually
    interfaces to all kinds of modules and programs, the fact that
    processes die naturally from time to time helps remove cumulative
    errors.
    IMHO this is a last-resort safeguard to prevent a system from falling
    due to badly written applications. But this can not be a reason for
    deciding on the architecture.
    From the PHP point of view, you can get problems with persistent
    database connections on a very high load site, that's true. But
    that's about the only problem. Sure, you can't build a persistent
    storage of information in the server but that's a minor issue.
    It's not a minor issue. Using persistent objects that are expensive to
    aquire is a common pattern, which can improve performance significantly.
    The above scenario prevents exactly that.

    I guess this is more of an apache issue then a PHP issue. I'd have to
    look more closely at the apache sources to investigate further.
    correctly and handle multithreading - is simply not worth it.
    By my measurements, it is worth it.
    (BTW, isn't nsapi the API for the Netscape web server?)
    Yes, it is.


    Akos
  • Ivan Ristic at Dec 5, 2002 at 10:14 am

    From the PHP point of view, you can get problems with persistent
    database connections on a very high load site, that's true. But
    that's about the only problem. Sure, you can't build a persistent
    storage of information in the server but that's a minor issue.
    It's not a minor issue. Using persistent objects that are expensive to
    aquire is a common pattern, which can improve performance significantly.
    The above scenario prevents exactly that.
        Right, but you can still use shared memory, or, you can store
        persistent objects onto the filesystem. We've done the later
        with satisfactory results.

    I guess this is more of an apache issue then a PHP issue. I'd have to
    look more closely at the apache sources to investigate further.
        Apache 2 resolves this problem. You can configure it to
        run multithreaded. Still, the issue of having a stable PHP remains.

        Plus, PHP has no mechanisms to handle multithreaded access from
        user space, you would have to use shared memory locks or file
        system locks.


    Bye,
    Ivan
  • Maróy Ákos at Dec 5, 2002 at 10:17 am

    Ivan Ristic wrote:
    Right, but you can still use shared memory, or, you can store
    persistent objects onto the filesystem. We've done the later
    with satisfactory results.
    Point taken. But this only allows to share resources that can be copied
    into and from IPC shared memory. Some resources (like open database
    connections, or a JVM) are not like that, even though they are expensive
    to create.
    Apache 2 resolves this problem. You can configure it to
    run multithreaded. Still, the issue of having a stable PHP remains.
    Interesting. Does PHP run with apache 2?


    Akos
  • Derick Rethans at Dec 5, 2002 at 10:21 am

    On Thu, 5 Dec 2002, Maróy Ákos wrote:

    Ivan Ristic wrote:
    Right, but you can still use shared memory, or, you can store
    persistent objects onto the filesystem. We've done the later
    with satisfactory results.
    Point taken. But this only allows to share resources that can be copied
    into and from IPC shared memory. Some resources (like open database
    connections, or a JVM) are not like that, even though they are expensive
    to create.
    Have a look at www.vl-srm.net, and more even the article about it @
    http://www.vl-srm.net/doc/articles/php-almanac-2002.php (the part about
    Bananas might be th emost relevant thing).

    Derick

    --

    -------------------------------------------------------------------------
      Derick Rethans http://derickrethans.nl/
      PHP Magazine - PHP Magazine for Professionals http://php-mag.net/
    -------------------------------------------------------------------------
  • Maróy Ákos at Dec 5, 2002 at 10:31 am

    Derick Rethans wrote:
    Have a look at www.vl-srm.net, and more even the article about it @
    http://www.vl-srm.net/doc/articles/php-almanac-2002.php (the part about
    Bananas might be th emost relevant thing).
    Thanks for the info. Though I could implement a similar deamon in java,
    and call it through XML PRC or other similar way via a network socket.
    (As my original intention was to fire up a JVM and call java functions
    from there.) But using network sockets is far mor expensive than calling
    through JNI. In my case, it seems that such a solution would not worth it.


    Akos
  • Derick Rethans at Dec 5, 2002 at 10:34 am

    On Thu, 5 Dec 2002, Maróy Ákos wrote:

    Derick Rethans wrote:
    Have a look at www.vl-srm.net, and more even the article about it @
    http://www.vl-srm.net/doc/articles/php-almanac-2002.php (the part about
    Bananas might be th emost relevant thing).
    Thanks for the info. Though I could implement a similar deamon in java,
    and call it through XML PRC or other similar way via a network socket.
    (As my original intention was to fire up a JVM and call java functions
    from there.) But using network sockets is far mor expensive than calling
    through JNI. In my case, it seems that such a solution would not worth it.
    You can use UNIX domain sockets, which boosts performance a _lot_. And
    SRM has no XML bloat as overhead.

    Derick

    --

    -------------------------------------------------------------------------
      Derick Rethans http://derickrethans.nl/
      PHP Magazine - PHP Magazine for Professionals http://php-mag.net/
    -------------------------------------------------------------------------
  • Ivan Ristic at Dec 5, 2002 at 10:32 am

    Right, but you can still use shared memory, or, you can store
    persistent objects onto the filesystem. We've done the later
    with satisfactory results.
    Point taken. But this only allows to share resources that can be copied
    into and from IPC shared memory. Some resources (like open database
    connections, or a JVM) are not like that, even though they are expensive
    to create.
        True.

    Apache 2 resolves this problem. You can configure it to
    run multithreaded. Still, the issue of having a stable PHP remains.
    Interesting. Does PHP run with apache 2?
        It depends on who you ask. I haven't tried it myself but from what
        I've read on this mailing list - it works for some people, some
        other people have problems.


    Bye,
    Ivan
  • Akos Maroy at Dec 5, 2002 at 10:44 am

    Ivan Ristic wrote:
    You can perhaps try to use it the other way around, have PHP
    run inside a Java VM. You can also try to get the source code
    how would this work? can you send me pointers?


    Akos
  • Ivan Ristic at Dec 5, 2002 at 10:56 am

    You can perhaps try to use it the other way around, have PHP
    run inside a Java VM. You can also try to get the source code
    how would this work? can you send me pointers?
        There is a servlet which accepts requests and uses native
        code from libphp4.so to execute them. At the same time,
        the Java extension is used to provide access to Java
        objects from PHP itself.

        Everything you need is in the PHP source, go to
        folders /sapi/servlet and /ext/java for instructions.

        Actually, get the fresh source from CVS, it will work better.

        Last time I tried this it worked, but barely (on Linux with
        JDK 1.4). I plan to try it again today since new patches have
        been added in the meantime.

    Bye,
    Ivan
  • Maróy Ákos at Dec 5, 2002 at 11:03 am

    Ivan Ristic wrote:
    There is a servlet which accepts requests and uses native
    code from libphp4.so to execute them. At the same time,
    the Java extension is used to provide access to Java
    objects from PHP itself.
    but the ext/java as it is would not be suitable, as it would spawn new
    JVMs every once in a while (thus it would use a different JVM then the
    one that called the PHP page). the solution would be to pass the JVM
    somehow to the PHP page (maybe as a global variable?), and then make it
    use that JVM when executing JNI calls.

    So a solution would be then:

    - from java, use JNI to call function in libphp4.so
    - libphp4.so, properly called, would execute a PHP script
    - this PHP script could call java functions through JNI, using a JVM
    passed to it somehow

    Where can I find documentation for calling libphp4.so? How do I execute
    a PHP script by calling some functions in libphp4.so?


    Akos
  • Ivan Ristic at Dec 5, 2002 at 11:19 am

    There is a servlet which accepts requests and uses native
    code from libphp4.so to execute them. At the same time,
    the Java extension is used to provide access to Java
    objects from PHP itself.

    but the ext/java as it is would not be suitable, as it would spawn new
    JVMs every once in a while (thus it would use a different JVM then the
    one that called the PHP page).
        No, I have been told (by someone, I do not remember) that if you
        use PHP as a servlet ext/java would use the same JVM. I haven't
        check to see whether that is correct.

    Where can I find documentation for calling libphp4.so? How do I execute
    a PHP script by calling some functions in libphp4.so?
        /sapi/servlet


    Bye,
    Ivan
  • Akos Maroy at Dec 5, 2002 at 11:21 am

    Ivan Ristic wrote:
    No, I have been told (by someone, I do not remember) that if you
    use PHP as a servlet ext/java would use the same JVM. I haven't
    check to see whether that is correct.
    sound good, I'll take a look.


    Akos
  • Akos Maroy at Dec 5, 2002 at 2:00 pm

    Ivan Ristic wrote:
    No, I have been told (by someone, I do not remember) that if you
    use PHP as a servlet ext/java would use the same JVM. I haven't
    check to see whether that is correct.
    My experiences:

    using php-4.2.3, calling plain php pages from Tomcat seem to be OK. But
    when calling java code from within the PHP code, I get a native mode
    exception:


    Unexpected Signal : 11 occurred at PC=0x4DAD935E
    Function=zend_hash_index_update_or_next_insert+0x3A
    Library=/.../php-4.2.3/libs/libphp4.so

    Current Java thread:
              at net.php.reflect.setResultFromObject(Native Method)
              at net.php.reflect.setResult(reflect.java:105)
              at net.php.servlet.readCookies(servlet.java:92)
              at net.php.servlet.send(Native Method)
              at net.php.servlet.service(servlet.java:188)
              at net.php.servlet.service(servlet.java:212)
              at javax.servlet.http.HttpServlet.service(HttpServlet.java:853)



    I also tried the CVS version, but I can't even compile it:


    /.../php4/sapi/servlet/servlet.c: In function Java_net_php_servlet_startup':
    /.../php4/sapi/servlet/servlet.c:261: warning: passing arg 2 of
    `php_module_startup' from incompatible pointer type
    make: *** No rule to make target `sapi/servlet/java.c', needed by
    `sapi/servlet/java.lo'. Stop.


    What java.c is expected here? The same as in ext/java ?


    Akos
  • Tony J. White at Dec 5, 2002 at 6:23 pm

    On Wed, 4 Dec 2002, [ISO-8859-2] Maróy Ákos wrote:
    What happens is that the function jvm_create() gets called regularly
    when requesting new pages using the Java extension, from the function
    java_call_function_handler():

    if (!JG(jenv)) jvm_create(TSRMLS_C);
    Actually, the JVM is unloaded by php. In the latest CVS the code from
    destroy_jvm() has been removed that tried to dlclose() the JVM. This was
    done because it is impossible to dlclose() a JVM because DestroyJavaVM()
    is broken in all JNI implementations.

    It the code you reference JG(env) is a global variable that is the jenv of
    the currently running JVM. Of course a new JVM needs to be created by every
    instance of PHP (so every httpd child in apache). The code is misleading
    because in past versions of PHP, the module tried to unload the JVM and load it
    again every time a ini setting was changed. This code should be removed
    and jvm_create() should be instead placed in the PHP_MINIT() function, that
    way the JVM will be loaded when apache is started instead of the first time
    java() is used by PHP. I'll get to it eventually unless someone beats me to
    it.

    -Tony
  • Maróy Ákos at Dec 5, 2002 at 6:30 pm

    Tony J. White wrote:
    Actually, the JVM is unloaded by php. In the latest CVS the code from
    destroy_jvm() has been removed that tried to dlclose() the JVM. This was
    done because it is impossible to dlclose() a JVM because DestroyJavaVM()
    is broken in all JNI implementations.
    I see. But if you dlclose()-it, what happens to open resources, like
    open file descriptors, network sockets, etc? It seems to be a crude way
    of unloading the JVM...


    Akos
  • Tony J. White at Dec 5, 2002 at 7:49 pm

    On Thu, 5 Dec 2002, [ISO-8859-2] Maróy Ákos wrote:
    Actually, the JVM is unloaded by php. In the latest CVS the code from
    I see. But if you dlclose()-it, what happens to open resources, like
    open file descriptors, network sockets, etc? It seems to be a crude way
    of unloading the JVM...
    Oops! That should have read "the JVM is _NOT_ unloaded by php.".

    Once loaded the JVM remains loaded by the PHP process. When php scripts
    finish or variables are unset() DeleteLocalRef() is called on the JVM to
    allow the JVM to garbage collect unused resources, but the JVM remains
    running.

    -Tony
  • Akos Maroy at Dec 5, 2002 at 10:24 pm

    Tony J. White wrote:
    Once loaded the JVM remains loaded by the PHP process. When php scripts
    finish or variables are unset() DeleteLocalRef() is called on the JVM to
    allow the JVM to garbage collect unused resources, but the JVM remains
    running.
    This is contrary to my experiences. But we have discussed this earlier
    today.


    Akos
  • Tony J. White at Dec 6, 2002 at 4:03 pm

    This is contrary to my experiences. But we have discussed this earlier
    today.
    After reviewing the thread, I think the problem you are experiencing is related
    to the fact that each instance of PHP is running a seperate JVM. It's not
    that the JVM is being destroyed.

    Therefore when you have apache running with say 5 httpd children, you will be
    running 5 seperate JVM's each with it's own environment. So if you tried
    to keep a Java variable active from request to request, it would disappear
    once your apache KeepAliveTimeout was up.

    Does that sound about right?

    -Tony
  • Akos Maroy at Dec 6, 2002 at 5:06 pm

    Tony J. White wrote:
    After reviewing the thread, I think the problem you are experiencing is related
    to the fact that each instance of PHP is running a seperate JVM. It's not
    that the JVM is being destroyed.

    Therefore when you have apache running with say 5 httpd children, you will be
    running 5 seperate JVM's each with it's own environment. So if you tried
    to keep a Java variable active from request to request, it would disappear
    once your apache KeepAliveTimeout was up.

    Does that sound about right?
    well, I traced it and _never_ saw a call to jvm_destroy() in the java
    extension code.

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupphp-dev @
categoriesphp
postedDec 4, '02 at 10:08a
activeDec 6, '02 at 5:06p
posts27
users5
websitephp.net

People

Translate

site design / logo © 2022 Grokbase