tests: add engine `nitg-sg` for --semi-global
[nit.git] / lib / java.nit
index a1e7c4f..de82015 100644 (file)
 # limitations under the License.
 
 # Supporting services for the FFI with Java
+#
+# This modules relies on `Sys::jvm`, `Sys::jni_env` and
+# `Sys::create_default_jvm` to get a handle on a JVM. You can adapt the
+# behavior of the FFI and services in this module by redefing
+# `Sys::create_default_jvm` and supply your own JVM object. You can manage
+# multiple java thread by switching the current environment in a redef
+# of `Sys::jni_env`, and multiple JVM using `Sys::jvm`.
+#
+# The module `jvm` gives more control over the JVM instances and wraps
+# most of JNI functions. You can use it to further customize the behavior 
+# of your code.
 module java is
        c_compiler_option("-I $(JAVA_HOME)/include/")
        c_linker_option("-L $(JNI_LIB_PATH) -ljvm")
@@ -38,7 +49,6 @@ redef class Sys
        fun jvm=(jvm: JavaVM) do jvm_cache = jvm
 
        # Current main `JniEnv`
-       # FIXME support threaded Java
        fun jni_env: JniEnv
        do
                if jni_env_cache == null then create_default_jvm
@@ -49,7 +59,7 @@ redef class Sys
        fun jni_env=(jni_env: JniEnv) do jni_env_cache = jni_env
 
        # Called by `jvm` and `jni_env` to instanciate a Java Virual Machine.
-       # Used mostly for FFI with Java.
+       # Used mostly for the FFI with Java.
        protected fun create_default_jvm
        do
                var builder = new JavaVMBuilder
@@ -63,6 +73,21 @@ redef class Sys
                self.jvm = jvm
                self.jni_env = builder.jni_env.as(not null)
        end
+
+       # Get a Java class by its name from the current `jni_env`
+       fun load_jclass(name: NativeString): JClass import jni_env `{
+               JNIEnv *nit_ffi_jni_env = Sys_jni_env(recv);
+
+               // retreive the implementation Java class
+               jclass java_class = (*nit_ffi_jni_env)->FindClass(nit_ffi_jni_env, name);
+               if (java_class == NULL) {
+                       fprintf(stderr, "Nit FFI with Java error: failed to load class.\\n");
+                       (*nit_ffi_jni_env)->ExceptionDescribe(nit_ffi_jni_env);
+                       exit(1);
+               }
+
+               return java_class;
+       `}
 end
 
 # A standard Java string `java.lang.String`
@@ -131,4 +156,11 @@ redef extern class JavaObject
                JNIEnv *env = Sys_jni_env(sys);
                (*env)->DeleteGlobalRef(env, recv);
        `}
+
+       # Delete this local reference
+       fun delete_local_ref import sys, Sys.jni_env `{
+               Sys sys = JavaObject_sys(recv);
+               JNIEnv *env = Sys_jni_env(sys);
+               (*env)->DeleteLocalRef(env, recv);
+       `}
 end