Support native code only usage of JVM
jpphillips opened this issue · comments
Here is what I have:
HelloWorld.java
package com.test;
public class HelloWorld {
public void sayHello(String msg) {
System.out.println("Hello from Java: " + msg);
}
}
Compile it:
$ javac com/test/HelloWorld.java
The Google JNI-BIND C++ code:
#include "jni_bind_release.h"
// 1: Setup JNI Bind in your OnLoad call (needed only once).
std::unique_ptr < jni::JvmRef < jni::kDefaultJvm >> jvm;
extern "C" {
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM * pjvm, void * ) {
jvm.reset(new jni::JvmRef < jni::kDefaultJvm > (pjvm));
return JNI_VERSION_1_6;
}
}
int main() {
// 2: Define the class
static constexpr jni::Class kClass {
"com.test.HelloWorld",
jni::Method {
"sayHello",
jni::Return < void > {},
jni::Params < jstring > {}
}
};
// 3: Use the class
jni::LocalObject < kClass > obj {}; // Constructs new instance.
obj("sayHello", "a cool string from C++");
return 0;
}
I have the JNI-BIND sources inside a local jni_bind folder. So to compile the code above I do on a Mac:
$ tree -L 1
.
├── HelloWorld.cpp
├── com
└── jni_bind
$ tree com
com
└── test
├── HelloWorld.class
└── HelloWorld.java
C++ compilation:
$ clang++ -std=c++17 -I./jni_bind -I"$JAVA_HOME/include"
-I"$JAVA_HOME/include/darwin/" HelloWorld.cpp -o HelloWorld
And it compiles fine, great!
But now when I run it, I get a segmentation fault because it is not able to find the ./com/test/HelloWorld.class
file to load.
$ ./HelloWorld
zsh: segmentation fault ./HelloWorld
Setting the CLASSPATH does not work either:
$ CLASSPATH=. ./HelloWorld
zsh: segmentation fault CLASSPATH=. ./HelloWorld
Perhaps I have to set JavaVMOption
with -Djava.class.path=.
to pass to its embedded JVM? But how would I go about doing that?
Ah wow, so, it's great that you're able to compile and run, although, it looks like you're driving control of the binary entirely through native.
While this is actually possible, I don't have the sample released yet. Unfortunately, I think you need to initiate control from Java, and send it to native.
If you really want this as native only (i.e. you deliberately wanted control to emanate from native), please change the bug name and file it against me. It would be helpful for me to understand what folks would find most useful to help adoption of the library.
Very nice project! Congratulations for the hard and meticulous work you did there. I'm maintaining a GitHub repo (JavaToCppAndBack) with an assortment of examples of Java to C++ and C++ to Java integration. I would love to include a JNI-BIND HelloWorld there eventually!
That is very kind, I appreciate the compliment! It has been a tremendous amount of work so it is nice that it is getting closer to being in people's hands. I'd love to be used by other projects, although to start i imagine that would be done most simply through the Bazel/WORKSPACE mechanisms.
If you would like to file a new issues for "Distribution to third party projects" that would be great, although, realistically I'm afraid I need to address other issues for the 1.0 release. In the meantime, any mentions/stars help the project gain traction which I would be very grateful for 🙂