Native methods in Java
I have spent some time learning what are Java Native methods and that 开发者_如何学Gothey are implemented in platform dependent code(mostly C).
But where can I find those native implementations of Java? eg : sleep(long millis) method of Thread class is native. But where is its implementation code???
The native code is implemented within the JVM (Java Virtual Machine). The Java developer isn't supposed to worry about their implementation as they relate to the inner working of the virtual machine. However, you can write your own native methods using JNI or see how they are implemented for a specific JVM.
But where can I find those native implementations of Java?
You'll have to download the complete source of some JDK. In OpenJDK for instance, you'll find lots of files related to threads:
./jdk/src/share/native/java/lang/Thread.c
You can find the implementations of these functions in the source code of your JRE. E.g. the source code of OpenJDK 6 is here.
Each JVM has its own implementation. You may find the implementation of OpenJDK here : http://openjdk.java.net/
The implementation of these code is in the source code of the OpenJDK, located at github.com/openjdk/jdk .
Example for java.lang.Runtime:
- src/java.base/share/classes/java/lang/Runtime.java - Java Code
- src/java.base/share/native/libjava/Runtime.c - Native code
Native code for the garbage collection method System.gc()
:
JNIEXPORT void JNICALL
Java_java_lang_Runtime_gc(JNIEnv *env, jobject this)
{
JVM_GC();
}
JVM_ENTRY_NO_ENV(void, JVM_GC(void))
JVMWrapper("JVM_GC");
if (!DisableExplicitGC) {
Universe::heap()->collect(GCCause::_java_lang_system_gc);
}
JVM_END
Reference
- Java Native Methods Essentials
A native method in Java is a method that is written in a language other than Java and can be called from a Java program.
Such methods can be useful in some situations, for example, if you need to interact with the operating system or with executable files that are not supported by Java.
In order to call a native method, you must first write it in a non-Java language, such as C/C++. Then it must be compiled into a library with the extension ".dll" for Windows or ".so" for Linux.
After that, you need to use the keyword "native" in the method description in Java. For example, to call a native method named "myNativeMethod", its description in Java might look like this:
public native void myNativeMethod();
You then need to call the special System.loadLibrary() method to load the library with native code before calling the native method. Example:
System.loadLibrary("myLibrary");
where "myLibrary" is the filename of the library you compiled.
Finally, you can call your native method just like any other Java method:
myNativeMethod();
Native methods can be useful in some cases, but use them with caution, as they can cause problems with the security, stability, and portability of the application.
Here is an example of calling a native method in Java, the library of which is written in assembler:
- Create class with native method:
public class NativeLibrary {
static {
System.loadLibrary("native");
}
public native int add(int a, int b);
}
- Create a dynamic library in assembler (e.g. for Linux):
section .data ; Data section
section .text ; Code section
global _add ; Declare the global symbol "_add"
_add: ; Start of function "_add"
push ebp ; We store the stack base register on the stack
mov ebp, esp ; We set the stack base register
mov eax, [ebp+8] ; a is the first argument of the function, stored on the stack with an 8-byte offset
mov ebx, [ebp+12] ; b is the second argument of the function, stored on the stack with a 12-byte offset
add eax, ebx ; Add "a" and "b"
mov esp, ebp ; We restore the stack register
pop ebp ; We restore the stack base register
ret; We return the result
- Build a dynamic library:
nasm -f elf32 native.asm ; We compile the file on the assembler
gcc -shared -m32 -o libnative.so native.o ; We create a dynamic library "libnative.so"
- run:
public class Main {
public static void main(String[] args) {
NativeLibrary lib = new NativeLibrary();
int sum = lib.add(2, 3); // call method "add"
System.out.println(sum); // output data in console
}
}
精彩评论