diff --git a/openbr/plugins/jni.cmake b/openbr/plugins/jni.cmake new file mode 100644 index 0000000..3a40ffa --- /dev/null +++ b/openbr/plugins/jni.cmake @@ -0,0 +1,12 @@ +set(BR_WITH_JAVA ON CACHE BOOL "Use Java Code") + +if (${BR_WITH_JAVA}) + find_package(JNI REQUIRED) + find_package(JAVA REQUIRED) + set(BR_THIRDPARTY_SRC ${BR_THIRDPARTY_SRC} plugins/jni.cpp) + set(BR_THIRDPARTY_LIBS ${BR_THIRDPARTY_LIBS} ${JNI_LIBRARIES}) + + include_directories(${JAVA_INCLUDE_PATH}) + include_directories(${JAVA_INCLUDE_PATH2}) + +endif() diff --git a/openbr/plugins/jni.cpp b/openbr/plugins/jni.cpp new file mode 100644 index 0000000..446a1fc --- /dev/null +++ b/openbr/plugins/jni.cpp @@ -0,0 +1,102 @@ +//Need to include location of jvm.dll (jdk version) and its parent directory in the environment variables + +#include +#include "openbr_internal.h" +#include "openbr/core/resource.h" +#include + +namespace br +{ + +/*! + * \ingroup initializers + * \brief Initialize JNI + * \author Jordan Cheney \cite jcheney + */ +class JNIInitializer : public Initializer +{ + Q_OBJECT + public: + static JavaVM* jvm; + static JavaVMInitArgs vm_args; + + void initialize() const + { + JNIEnv *env; + JavaVMOption options[1]; + + //Location of Java files + QByteArray classpath = QString("-Djava.class.path=").append(Globals->sdkPath).append(QString("/share/openbr/Java/jniLibraries/")).toLocal8Bit(); + char *charClasspath = classpath.data(); + + options[0].optionString = charClasspath; + vm_args.version = JNI_VERSION_1_6; + vm_args.nOptions = 1; + vm_args.options = options; + vm_args.ignoreUnrecognized = JNI_FALSE; + + JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args); + + Globals->abbreviations.insert("JNIHelloWorld","Open+JNI(HelloWorld)"); + } + + void finalize() const + { + jvm->DestroyJavaVM(); + } +}; + +JavaVM *JNIInitializer::jvm; +JavaVMInitArgs JNIInitializer::vm_args; + +BR_REGISTER(Initializer, JNIInitializer) + +/*! + * \ingroup transforms + * \brief Execute Java code from OpenBR using the JNI + * \author Jordan Cheney \cite jcheney + */ + +class JNITransform : public UntrainableTransform +{ + Q_OBJECT + Q_PROPERTY(QString className READ get_className WRITE set_className RESET reset_className STORED false) + BR_PROPERTY(QString, className, "") + + void project(const Template &src, Template &dst) const + { + JNIEnv *env; + + //Attach current thread to the thread of the JavaVM and access env + JNIInitializer::jvm->AttachCurrentThreadAsDaemon((void**)&env, NULL); + if (JNIInitializer::jvm->GetEnv(reinterpret_cast(&env), JNI_VERSION_1_6) != JNI_OK) { + qFatal("Failed to initialize JNI environment"); + } + + //Convert QString to const char* + QByteArray tmpClass = className.toLocal8Bit(); + const char* charClassName = tmpClass.constData(); + + //Call java method + jclass cls = env->FindClass(charClassName); + if (cls == NULL) { qFatal("Class not found"); } + jmethodID mid = env->GetStaticMethodID(cls, "project", "(Ljava/lang/String;)V"); + if (mid == NULL) { qFatal("MethodID not found"); } + + QByteArray tmp = src.file.name.toLocal8Bit(); + const char* fileName = tmp.constData(); + + //Convert char* to java compatible string + jstring jfileName = env->NewStringUTF(fileName); + + env->CallStaticObjectMethod(cls, mid, jfileName); + + JNIInitializer::jvm->DetachCurrentThread(); + } +}; + +BR_REGISTER(Transform, JNITransform) + +} // namespace br + +#include "jni.moc" diff --git a/share/openbr/Java/jniLibraries/HelloWorld.jar b/share/openbr/Java/jniLibraries/HelloWorld.jar new file mode 100644 index 0000000..41cbbb3 --- /dev/null +++ b/share/openbr/Java/jniLibraries/HelloWorld.jar diff --git a/share/openbr/Java/jniLibraries/HelloWorld.java b/share/openbr/Java/jniLibraries/HelloWorld.java new file mode 100644 index 0000000..7cf7b0e --- /dev/null +++ b/share/openbr/Java/jniLibraries/HelloWorld.java @@ -0,0 +1,9 @@ +public class HelloWorld { + public static void project(String imgPath) { + System.out.println(); + System.out.println("Welcome to the OpenBR JNI transform! The image path string " + imgPath + " has been passed here from C++."); + 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."); + 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'"); + System.out.println(); + } +} \ No newline at end of file