Commit fc7593c35a68b663a807cd00d3e199888acaa237
1 parent
248a35a4
Basic JNI transform with basic framework for calling Java from OpenBR
Showing
4 changed files
with
123 additions
and
0 deletions
openbr/plugins/jni.cmake
0 → 100644
| 1 | +set(BR_WITH_JAVA ON CACHE BOOL "Use Java Code") | |
| 2 | + | |
| 3 | +if (${BR_WITH_JAVA}) | |
| 4 | + find_package(JNI REQUIRED) | |
| 5 | + find_package(JAVA REQUIRED) | |
| 6 | + set(BR_THIRDPARTY_SRC ${BR_THIRDPARTY_SRC} plugins/jni.cpp) | |
| 7 | + set(BR_THIRDPARTY_LIBS ${BR_THIRDPARTY_LIBS} ${JNI_LIBRARIES}) | |
| 8 | + | |
| 9 | + include_directories(${JAVA_INCLUDE_PATH}) | |
| 10 | + include_directories(${JAVA_INCLUDE_PATH2}) | |
| 11 | + | |
| 12 | +endif() | ... | ... |
openbr/plugins/jni.cpp
0 → 100644
| 1 | +//Need to include location of jvm.dll (jdk version) and its parent directory in the environment variables | |
| 2 | + | |
| 3 | +#include <limits> | |
| 4 | +#include "openbr_internal.h" | |
| 5 | +#include "openbr/core/resource.h" | |
| 6 | +#include <jni.h> | |
| 7 | + | |
| 8 | +namespace br | |
| 9 | +{ | |
| 10 | + | |
| 11 | +/*! | |
| 12 | + * \ingroup initializers | |
| 13 | + * \brief Initialize JNI | |
| 14 | + * \author Jordan Cheney \cite jcheney | |
| 15 | + */ | |
| 16 | +class JNIInitializer : public Initializer | |
| 17 | +{ | |
| 18 | + Q_OBJECT | |
| 19 | + public: | |
| 20 | + static JavaVM* jvm; | |
| 21 | + static JavaVMInitArgs vm_args; | |
| 22 | + | |
| 23 | + void initialize() const | |
| 24 | + { | |
| 25 | + JNIEnv *env; | |
| 26 | + JavaVMOption options[1]; | |
| 27 | + | |
| 28 | + //Location of Java files | |
| 29 | + QByteArray classpath = QString("-Djava.class.path=").append(Globals->sdkPath).append(QString("/share/openbr/Java/jniLibraries/")).toLocal8Bit(); | |
| 30 | + char *charClasspath = classpath.data(); | |
| 31 | + | |
| 32 | + options[0].optionString = charClasspath; | |
| 33 | + vm_args.version = JNI_VERSION_1_6; | |
| 34 | + vm_args.nOptions = 1; | |
| 35 | + vm_args.options = options; | |
| 36 | + vm_args.ignoreUnrecognized = JNI_FALSE; | |
| 37 | + | |
| 38 | + JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args); | |
| 39 | + | |
| 40 | + Globals->abbreviations.insert("JNIHelloWorld","Open+JNI(HelloWorld)"); | |
| 41 | + } | |
| 42 | + | |
| 43 | + void finalize() const | |
| 44 | + { | |
| 45 | + jvm->DestroyJavaVM(); | |
| 46 | + } | |
| 47 | +}; | |
| 48 | + | |
| 49 | +JavaVM *JNIInitializer::jvm; | |
| 50 | +JavaVMInitArgs JNIInitializer::vm_args; | |
| 51 | + | |
| 52 | +BR_REGISTER(Initializer, JNIInitializer) | |
| 53 | + | |
| 54 | +/*! | |
| 55 | + * \ingroup transforms | |
| 56 | + * \brief Execute Java code from OpenBR using the JNI | |
| 57 | + * \author Jordan Cheney \cite jcheney | |
| 58 | + */ | |
| 59 | + | |
| 60 | +class JNITransform : public UntrainableTransform | |
| 61 | +{ | |
| 62 | + Q_OBJECT | |
| 63 | + Q_PROPERTY(QString className READ get_className WRITE set_className RESET reset_className STORED false) | |
| 64 | + BR_PROPERTY(QString, className, "") | |
| 65 | + | |
| 66 | + void project(const Template &src, Template &dst) const | |
| 67 | + { | |
| 68 | + JNIEnv *env; | |
| 69 | + | |
| 70 | + //Attach current thread to the thread of the JavaVM and access env | |
| 71 | + JNIInitializer::jvm->AttachCurrentThreadAsDaemon((void**)&env, NULL); | |
| 72 | + if (JNIInitializer::jvm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) { | |
| 73 | + qFatal("Failed to initialize JNI environment"); | |
| 74 | + } | |
| 75 | + | |
| 76 | + //Convert QString to const char* | |
| 77 | + QByteArray tmpClass = className.toLocal8Bit(); | |
| 78 | + const char* charClassName = tmpClass.constData(); | |
| 79 | + | |
| 80 | + //Call java method | |
| 81 | + jclass cls = env->FindClass(charClassName); | |
| 82 | + if (cls == NULL) { qFatal("Class not found"); } | |
| 83 | + jmethodID mid = env->GetStaticMethodID(cls, "project", "(Ljava/lang/String;)V"); | |
| 84 | + if (mid == NULL) { qFatal("MethodID not found"); } | |
| 85 | + | |
| 86 | + QByteArray tmp = src.file.name.toLocal8Bit(); | |
| 87 | + const char* fileName = tmp.constData(); | |
| 88 | + | |
| 89 | + //Convert char* to java compatible string | |
| 90 | + jstring jfileName = env->NewStringUTF(fileName); | |
| 91 | + | |
| 92 | + env->CallStaticObjectMethod(cls, mid, jfileName); | |
| 93 | + | |
| 94 | + JNIInitializer::jvm->DetachCurrentThread(); | |
| 95 | + } | |
| 96 | +}; | |
| 97 | + | |
| 98 | +BR_REGISTER(Transform, JNITransform) | |
| 99 | + | |
| 100 | +} // namespace br | |
| 101 | + | |
| 102 | +#include "jni.moc" | ... | ... |
share/openbr/Java/jniLibraries/HelloWorld.jar
0 → 100644
No preview for this file type
share/openbr/Java/jniLibraries/HelloWorld.java
0 → 100644
| 1 | +public class HelloWorld { | |
| 2 | + public static void project(String imgPath) { | |
| 3 | + System.out.println(); | |
| 4 | + System.out.println("Welcome to the OpenBR JNI transform! The image path string " + imgPath + " has been passed here from C++."); | |
| 5 | + System.out.println("To incorporate your Java code into OpenBR assemble a jar file will of the relevant classes and save it in the openbr/share/openbr/Java/jniLibraries folder."); | |
| 6 | + System.out.println("For documentation and additional resources on the JNI visit 'https://docs.oracle.com/javase/1.5.0/docs/guide/jni/specs/functions.html'"); | |
| 7 | + System.out.println(); | |
| 8 | + } | |
| 9 | +} | |
| 0 | 10 | \ No newline at end of file | ... | ... |