Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/283.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用JVM构建PHP扩展,需要实现思想_Php_C_Jvm_Java Native Interface - Fatal编程技术网

使用JVM构建PHP扩展,需要实现思想

使用JVM构建PHP扩展,需要实现思想,php,c,jvm,java-native-interface,Php,C,Jvm,Java Native Interface,我正在开发一个PHP5扩展,它使用JNI调用Java类。到目前为止,扩展和执行此操作的核心函数已经准备就绪,并且在单线程的每个进程环境中都能正常工作。因此,在命令行PHPCLI上使用php脚本中的extensions类函数不会有任何问题。 现在将该PHP扩展用作apache模块,我在通过JNI创建JVM时遇到了问题。使用模块的第一个调用工作正常,在第一个调用运行时以及在第一个调用完成后,不会创建JVM,并返回代码小于0的JNI_ERR。我发现,每个进程一次只能有一个JVM是一个限制。我使用-X开

我正在开发一个PHP5扩展,它使用JNI调用Java类。到目前为止,扩展和执行此操作的核心函数已经准备就绪,并且在单线程的每个进程环境中都能正常工作。因此,在命令行PHPCLI上使用php脚本中的extensions类函数不会有任何问题。 现在将该PHP扩展用作apache模块,我在通过JNI创建JVM时遇到了问题。使用模块的第一个调用工作正常,在第一个调用运行时以及在第一个调用完成后,不会创建JVM,并返回代码小于0的JNI_ERR。我发现,每个进程一次只能有一个JVM是一个限制。我使用-X开关测试并运行运行apache的模块,只需要一个工人

我在现阶段对模块的设计如下:

扩展构造函数创建JVM并进行一些初始化。 然后我有一些方法来调用和处理java类,比如传递参数等,并执行java类的一些方法。 我的扩展析构函数释放所有使用的资源,并销毁以前在构造函数中创建的JVM。 嗯,首先我想,这一切都会成功,但事实并非如此。不是现在实施的方式。所以我对如何解决这个问题的想法有点纠结

我的问题是: 我应该在哪里创建JVM,以及如何在线程化环境中正确地将其称为JNI Env PHP作为Apache模块。我想我必须在模块初始化时使用JNI_CreateJavaVM在某处创建JVM,然后使用AttachCurrentThread/DetachCurrentThread?!如果另一个线程试图连接到JVM线程,但已经有另一个线程连接到它,会发生什么?我必须在这里做一些锁紧装置吗?或者在扩展类方法中创建JVM,在该方法中调用所有与Java相关的方法,并在同一扩展类方法的末尾销毁JVM?我一点也不喜欢这个主意。尽管我认为它不能解决每个进程有多个JVM的问题

我希望事情不要变得太复杂

因此,基本上,我的问题是在哪里实现JVM创建/销毁调用,以及如何访问JNI环境来调用Java类方法。最后但并非最不重要的一点是,这是否是我努力实现的目标


一些开发细节:我的平台是Linux/UbuntuLucid10.04LTS,使用源代码编译的Apache2和PHP5.2.16。模块和核心函数是用C语言开发的,Java JRE是6.0.22 Oracle下载的。

我会在模块加载时创建JVM实例initvoid函数或apache调用的东西,并在fini上销毁它


如果我没记错的话,您可以通过AttachCurrentThread将多个线程连接到JVM。但是您需要确保返回的指针只在该线程中使用。我建议使用线程本地存储。您可以在创建线程时使用0初始化指针,并在新线程对函数的第一次调用中执行附加操作。

我将在模块加载时创建JVM实例\u initvoid函数或apache调用自身的东西,并在\u fini时销毁它


如果我没记错的话,您可以通过AttachCurrentThread将多个线程连接到JVM。但是您需要确保返回的指针只在该线程中使用。我建议使用线程本地存储。您可以在创建线程时用0初始化指针,并在新线程对函数的第一次调用中执行附加操作。

谢谢您的回答!你的建议听起来很有道理。当Apache启动时,它调用PHP_MINIT_函数,我想我可以在那里创建JVM。在Apache关机时,调用PHP_MSHUTDOWN_函数。我对所有与对象相关的变量使用Zend对象存储,除了存储在结构中的Env句柄之外,这里还有JVM句柄。它应该是线程安全的。因此,如果我理解正确,每当我想在扩展的类方法中使用JVM时,我只是附加到那个JVM,调用Java东西并在方法中分离?不需要创建额外的线程,对吗?Apache使用线程或分叉进程。因此,函数不太可能总是从同一线程调用。附加和分离可能会非常昂贵,所以我会避免每次函数调用都使用附加和分离。到目前为止,这个建议似乎有效。我在php_minit中创建JVM,并在php_mshutton中销毁它。JVM对象是全局定义的,我不认为,我需要在模块启动/关闭时注意线程安全。然后模块类构造函数连接到JVM,析构函数再次分离。jvmjni相关对象JNIEnv等存储在结构中,由zend对象存储安全地处理。似乎我可以为我的JNIJavaFCT调用一些php类方法包装器而没有任何问题。它还没有完成,布
至少到目前为止我还不知道。谢谢你的回答!你的建议听起来很有道理。当Apache启动时,它调用PHP_MINIT_函数,我想我可以在那里创建JVM。在Apache关机时,调用PHP_MSHUTDOWN_函数。我对所有与对象相关的变量使用Zend对象存储,除了存储在结构中的Env句柄之外,这里还有JVM句柄。它应该是线程安全的。因此,如果我理解正确,每当我想在扩展的类方法中使用JVM时,我只是附加到那个JVM,调用Java东西并在方法中分离?不需要创建额外的线程,对吗?Apache使用线程或分叉进程。因此,函数不太可能总是从同一线程调用。附加和分离可能会非常昂贵,所以我会避免每次函数调用都使用附加和分离。到目前为止,这个建议似乎有效。我在php_minit中创建JVM,并在php_mshutton中销毁它。JVM对象是全局定义的,我不认为,我需要在模块启动/关闭时注意线程安全。然后模块类构造函数连接到JVM,析构函数再次分离。jvmjni相关对象JNIEnv等存储在结构中,由zend对象存储安全地处理。似乎我可以为我的JNIJavaFCT调用一些php类方法包装器而没有任何问题。它还没有完成,但至少到目前为止我还没有得到Apache segfaults。