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 | \ No newline at end of file | 10 | \ No newline at end of file |