【发布时间】:2016-06-05 15:02:48
【问题描述】:
我遇到了以下情况:C++ 服务器应用程序正在侦听传入的客户端连接。在每次客户端连接尝试时,都会生成一个新会话。此会话将调用特定服务,具体取决于服务 id,该服务 id 在来自客户端的序列化数据中提供。一旦结果从服务到达,会话就会将数据发送到客户端。
该场景中的缺陷是,该服务是用 Java 实现的。
所以我的问题是:
- 如果有新的客户端请求到达,如何使用 C++ 中的 VM 引用实例化和调用 Java 服务类?
我知道为此我需要一个 Java VM。而且因为 C++ 服务器类将首先从 Java 应用程序调用(通过 SWIG 生成的包装器),我想我可能会将此应用程序的 VM 引用传递给我的服务器类(以及之后的会话)。
但是:
- 如何在我的 Java 代码中获取对当前 VM 的引用?
通常,Java 应用程序在启动服务器后什么都不做。也许我将不得不让它保持空闲以保持 VM 参考有效?关于 C++ 和 Java 交互中对服务的并发调用(除了服务内部的正常并发处理),我有什么特别需要担心的吗?
例子:
//Java Service
public class JMyService{
public String loadContactInformation(int userid){
return "test";
}
}
//C++ (very simplified)
class Session{
public:
//[...]
void handleWrite(){
vm = getVMReference(); //is saved beforehand
if(serviceId == CONTACT_INFO){
//todo call JMyService.loadContactInformation
}
}
}
我已经看到了this question,但我不得不承认这个解决方案很难理解,而且还不清楚提问者想要达到什么目的。在this post 中,作者正在使用Java 内置类型做类似的事情,但似乎代码生成器不能用于自己的Java 类型。我也知道that a new VM can be generated 可以完成这项工作,但如果可能的话,我想使用现有的。
编辑
to 1) 我不确定,但是当我使用 C++ 服务器类加载库时,jint JNI_OnLoad(JavaVM *vm, void *reserved); 方法可能可用于获取指向 VM 的指针。不幸的是,Oracle documentation 没有解释这个问题。有人可能有这方面的经验吗?
【问题讨论】:
-
为什么不用Java写完整的东西来消除问题呢?
-
具有很多功能的 C++ 库已经存在。但我同意你的观点,如果一切都是 Java 代码,它会更容易,也许也更易于维护。
标签: java c++ jvm java-native-interface