X-Git-Url: http://nitlanguage.org diff --git a/lib/java/java.nit b/lib/java/java.nit index 6358430..116f40d 100644 --- a/lib/java/java.nit +++ b/lib/java/java.nit @@ -1,7 +1,5 @@ # This file is part of NIT ( http://www.nitlanguage.org ). # -# Copyright 2014 Alexis Laferrière -# # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -26,175 +24,7 @@ # 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 - cflags "-I $(JAVA_HOME)/include/ -I $(JAVA_HOME)/include/linux/" - ldflags "-L $(JNI_LIB_PATH) -ljvm" - new_annotation extra_java_files -end - -import jvm - -redef class Sys - private var jvm_cache: nullable JavaVM = null - private var jni_env_cache: nullable JniEnv = null - - # Default Java Virtual Machine to use (will be instantiated using - # `create_default_jvm` if not already set) - fun jvm: JavaVM - do - if jvm_cache == null then create_default_jvm - return jvm_cache.as(not null) - end - - # Sets the current default Java Virtual Machine (use with `jni_env=`) - fun jvm=(jvm: JavaVM) do jvm_cache = jvm - - # Current main `JniEnv` - fun jni_env: JniEnv - do - if jni_env_cache == null then create_default_jvm - return jni_env_cache.as(not null) - end - - # Sets the current default JNI env (use with `jvm=`) - fun jni_env=(jni_env: JniEnv) do jni_env_cache = jni_env - - # Called by `jvm` and `jni_env` to instantiate a Java Virtual Machine. - # Used mostly for the FFI with Java. - protected fun create_default_jvm - do - var builder = new JavaVMBuilder - - # By default, look for Java classes in a jar file the same directory as the executable - builder.options.add "-Djava.class.path={sys.program_name}.jar" - - var jvm = builder.create_jvm - assert jvm != null else print "JVM creation failed" - - 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); - - // retrieve 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` -# -# Converted to a Nit string using `to_s`, or to a C string with `to_cstring`. -# Created using `String::to_java_string` or `NativeString::to_java_string`. -extern class JavaString in "Java" `{ java.lang.String `} - super JavaObject - - # Get the string from Java and copy it to Nit memory - fun to_cstring: NativeString import sys, Sys.jni_env `{ - Sys sys = JavaString_sys(recv); - JNIEnv *env = Sys_jni_env(sys); - - // Get the data from Java - const jbyte *java_cstr = (char*)(*env)->GetStringUTFChars(env, recv, NULL); - jsize len = (*env)->GetStringUTFLength(env, recv); - - // Copy it in control of Nit - char *nit_cstr = (char*)malloc(len+1); - memcpy(nit_cstr, java_cstr, len); - nit_cstr[len] = '\0'; - - // Free JNI ref and return - (*env)->ReleaseStringUTFChars(env, recv, java_cstr); - return nit_cstr; - `} - - redef fun to_s do return to_cstring.to_s -end - -redef class NativeString - # Get a Java string from this C string - # - # This instance is only valid until the next execution of Java code. - # You can use `new_local_ref` to keep it longer. - fun to_java_string: JavaString import sys, Sys.jni_env `{ - Sys sys = JavaString_sys(recv); - JNIEnv *env = Sys_jni_env(sys); - return (*env)->NewStringUTF(env, recv); - `} -end - -redef class Text - # Get `self` as a `JavaString` - fun to_java_string: JavaString do return to_cstring.to_java_string -end - -redef extern class JavaObject - - # Returns a global reference to the Java object behind this reference - # - # You must use a global reference when keeping a Java object - # across execution of Java code, per JNI specification. - fun new_global_ref: SELF import sys, Sys.jni_env `{ - Sys sys = JavaObject_sys(recv); - JNIEnv *env = Sys_jni_env(sys); - return (*env)->NewGlobalRef(env, recv); - `} - - # Delete this global reference - fun delete_global_ref import sys, Sys.jni_env `{ - Sys sys = JavaObject_sys(recv); - 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); - `} - - # Pops the current local reference frame and return a valid reference to self - # - # Similar to `JavaVM::pop_local_frame` but returns a value. - fun pop_from_local_frame: SELF - do - var jni_env = sys.jni_env - return pop_from_local_frame_with_env(jni_env) - end - - private fun pop_from_local_frame_with_env(jni_env: JniEnv): SELF `{ - return (*jni_env)->PopLocalFrame(jni_env, recv); - `} - - # Is `self` null in Java? - # - # Since Java type system doesn't have the same `nullable` concept as Nit's, - # the two systems are not directly compatible. Any Nit instances of - # `JavaObject` may hold a Java null. - # - # To benefit from the safer type system of Nit, it is recommended to check - # the return of all extern methods implemented in Java to ensure the value - # is not a Java null. In case it is, you should replace it by a normal Nit - # `null`. - fun is_java_null: Bool in "Java" `{ return recv == null; `} - - # `JavaString` representation of `self` using Java's `toString` - fun to_java_string: JavaString in "Java" `{ return recv.toString(); `} +module java - # Use Java's `toString` for any `JavaObject` - redef fun to_s - do - if is_java_null then return super - return to_java_string.to_s - end -end +import base +import collections