What is the native keyword in Java for?
Asked Answered
D

10

547

While playing this puzzle (It's a Java keyword trivia game), I came across the native keyword.

What is the native keyword in Java used for?

Disarrange answered 23/5, 2011 at 18:29 Comment(1)
A
367

The native keyword is applied to a method to indicate that the method is implemented in native code using JNI (Java Native Interface).

Aristophanes answered 23/5, 2011 at 18:30 Comment(2)
The actual implementation doesn’t have to use JNI. Certain JRE methods are handled intrinsically by the JVM. In fact, it’s not even mandatory that the implementation is actually native code. It’s just “implemented in a language other than the Java programming language”.Acyclic
How can you go about implementing a method in native code using JNI? How to you tell the JVM to use this code? How do you write your java code to include this code?Bolin
U
535

Minimal runnable example

Main.java

public class Main {
    public native int square(int i);
    public static void main(String[] args) {
        System.loadLibrary("Main");
        System.out.println(new Main().square(2));
    }
}

Main.c

#include <jni.h>
#include "Main.h"

JNIEXPORT jint JNICALL Java_Main_square(
    JNIEnv *env, jobject obj, jint i) {
  return i * i;
}

Compile and run:

sudo apt-get install build-essential openjdk-7-jdk
export JAVA_HOME='/usr/lib/jvm/java-7-openjdk-amd64'
javac Main.java
javah -jni Main
gcc -shared -fpic -o libMain.so -I${JAVA_HOME}/include \
  -I${JAVA_HOME}/include/linux Main.c
java -Djava.library.path=. Main

Output:

4

Tested on Ubuntu 14.04 AMD64. Also worked with Oracle JDK 1.8.0_45.

Example on GitHub for you to play with.

Underscores in Java package / file names must be escaped with _1 in the C function name as mentioned at: Invoking JNI functions in Android package name containing underscore

Interpretation

native allows you to:

  • call a compiled dynamically loaded library (here written in C) with arbitrary assembly code from Java
  • and get results back into Java

This could be used to:

  • write faster code on a critical section with better CPU assembly instructions (not CPU portable)
  • make direct system calls (not OS portable)

with the tradeoff of lower portability.

It is also possible for you to call Java from C, but you must first create a JVM in C: How to call Java functions from C++?

Analogous native extension APIs are also present in many other "VM languages" for the same reasons, e.g. Python, Node.js, Ruby.

Android NDK

The concept is exact the same in this context, except that you have to use Android boilerplate to set it up.

The official NDK repository contains "canonical" examples such as the hello-jni app:

In you unzip an .apk with NDK on Android O, you can see the pre-compiled .so that corresponds to the native code under lib/arm64-v8a/libnative-lib.so.

TODO confirm: furthermore, file /data/app/com.android.appname-*/oat/arm64/base.odex, says it is a shared library, which I think is the AOT precompiled .dex corresponding to the Java files in ART, see also: What are ODEX files in Android? So maybe the Java is actually also run via a native interface?

Example in the OpenJDK 8

Let's find find where Object#clone is defined in jdk8u60-b27.

We will conclude that it is implemented with a native call.

First we find:

find . -name Object.java

which leads us to jdk/src/share/classes/java/lang/Object.java#l212:

protected native Object clone() throws CloneNotSupportedException;

Now comes the hard part, finding where clone is amidst all the indirection. The query that helped me was:

find . -iname object.c

which would find either C or C++ files that might implement Object's native methods. It leads us to jdk/share/native/java/lang/Object.c#l47:

static JNINativeMethod methods[] = {
    ...
    {"clone",       "()Ljava/lang/Object;",   (void *)&JVM_Clone},
};

JNIEXPORT void JNICALL
Java_java_lang_Object_registerNatives(JNIEnv *env, jclass cls)
{
    (*env)->RegisterNatives(env, cls,
                            methods, sizeof(methods)/sizeof(methods[0]));
}

which leads us to the JVM_Clone symbol:

grep -R JVM_Clone

which leads us to hotspot/src/share/vm/prims/jvm.cpp#l580:

JVM_ENTRY(jobject, JVM_Clone(JNIEnv* env, jobject handle))
    JVMWrapper("JVM_Clone");

After expanding a bunch of macros, we come to the conclusion that this is the definition point.

Unweighed answered 4/6, 2015 at 5:48 Comment(4)
Excellent answer. Just a footnote : for a static native Java method, the second parameter of the C++ function is of type jclass and not jobject.Kaifeng
@Kaifeng thanks for the info. Was there a mistake on my answer, or is it just some extra info?Unweighed
@Ciro it's some extra info for those who begin with your example (an answer with about 300 on SO may serve as reference). I've had a function with an incorrect signature called with a mess on the stack, with no error reported (at any of compile, link or run times). Thus I find it important to mention to be careful on this step.Kaifeng
@HuazheYin Sun Zi once said: "the superior non-accepted answer gets more votes than the superior accepted answer, because of upvoters who seek justice". True story. Some related points: cirosantilli.com/#the-machiavellian-stack-overflow-contributorUnweighed
L
436

It marks a method, that it will be implemented in other languages, not in Java. It works together with JNI (Java Native Interface).

Native methods were used in the past to write performance critical sections but with Java getting faster this is now less common. Native methods are currently needed when

  • You need to call a library from Java that is written in other language.

  • You need to access system or hardware resources that are only reachable from the other language (typically C). Actually, many system functions that interact with real computer (disk and network IO, for instance) can only do this because they call native code.

See Also Java Native Interface Specification

Literator answered 23/5, 2011 at 18:41 Comment(8)
This is my understanding I write System.currentTimeMillis() (which is native) in java file and then this to work, JNI will call libraries or some functions written in C or C++ or assembly language and then return some value back to my java code. ex: here currentTimeMillis method invokes a native code with the help of JNI and that native code talks to system resource ex: a timer sitting on motherboard and thus getting return value (system time). correct me, please?Pasteur
@Pasteur methods like currentTimeMillis are part of the JDK and they are annotated with native because the implementation is in the JDK source code itself. It's very unlikely that the implementation uses assembly language; it probably calls an API method of the operating system which the JVM is running on top of. For example on Windows it may call a DLL method GetSystemTime in kernel32.dll. On another OS it will have a different implementation. However when you use native for a method you are writing (as opposed to a JDK method) you have to provide the implementation using JNI.Acuff
This statement is the important one for Native keyword... ' You need to access system or hardware resources that are only reachable from the other language (typically C) ' .Garold
@Kidburla May I ask what you mean by the "implementation is in the JDK source code itself"? currentTimeMillis is marked as native in java.lang.System so it uses JNI, isn't that right?Divulge
@Divulge yes, what you have said is probably true, I'm not sure why I said that in my comment (more than 2 years ago)Acuff
@Divulge not every native method uses JNI. In case of JRE methods, known to the JVM, there can be other mechanisms. E.g. Object.getClass() will not use JNI. But for native application methods that ought to run on different compatible JVMs, JNI is the standard interface.Acyclic
@Acyclic Thanks for the note. In this case, I suppose currentTimeMillis is an application method so would fall under JNI. About the "JRE methods" you mention - what are some good examples? I don't think I've ever called one myself - presumably they're low-level.Divulge
@Divulge There was an example already given: Object::getClass.Motley
A
367

The native keyword is applied to a method to indicate that the method is implemented in native code using JNI (Java Native Interface).

Aristophanes answered 23/5, 2011 at 18:30 Comment(2)
The actual implementation doesn’t have to use JNI. Certain JRE methods are handled intrinsically by the JVM. In fact, it’s not even mandatory that the implementation is actually native code. It’s just “implemented in a language other than the Java programming language”.Acyclic
How can you go about implementing a method in native code using JNI? How to you tell the JVM to use this code? How do you write your java code to include this code?Bolin
F
61

Straight from the Java Language Specification:

A method that is native is implemented in platform-dependent code, typically written in another programming language such as C, C++, FORTRAN,or assembly language. The body of a native method is given as a semicolon only, indicating that the implementation is omitted, instead of a block.

Fitzpatrick answered 23/5, 2011 at 18:51 Comment(0)
P
19

As SLaks answered, the native keyword is for calling native code.

It also used by GWT for implementing javascript methods.

Parting answered 23/5, 2011 at 18:40 Comment(0)
T
13

functions that implement native code are declared native.

The Java Native Interface (JNI) is a programming framework that enables Java code running in a Java Virtual Machine (JVM) to call, and to be called by, native applications (programs specific to a hardware and operating system platform) and libraries written in other languages such as C, C++ and assembly.

http://en.wikipedia.org/wiki/Java_Native_Interface

Thorma answered 6/4, 2012 at 6:45 Comment(0)
V
9

NATIVE is Non access modifier.it can be applied only to METHOD. It indicates the PLATFORM-DEPENDENT implementation of method or code.

Ventura answered 29/11, 2013 at 11:40 Comment(0)
M
8

Java native method provides a mechanism for Java code to call OS native code, either due to functional or performance reasons.

Example:

606  public native int availableProcessors();
617  public native long freeMemory();
630  public native long totalMemory();
641  public native long maxMemory();
664  public native void gc();

In the corresponding Runtime.class file in OpenJDK, located in JAVA_HOME/jmods/java.base.jmod/classes/java/lang/Runtime.class, contains these methods and tagged them with ACC_NATIVE (0x0100), and these methods do not contain the Code attribute, which means these method do not have any actual coding logic in the Runtime.class file:

  • Method 13 availableProcessors: tagged as native and no Code attribute
  • Method 14 freeMemory: tagged as native and no Code attribute
  • Method 15 totalMemory: tagged as native and no Code attribute
  • Method 16 maxMemory: tagged as native and no Code attribute
  • Method 17 gc: tagged as native and no Code attribute

enter image description here

The in fact coding logic is in the corresponding Runtime.c file:

42  #include "java_lang_Runtime.h"
43
44  JNIEXPORT jlong JNICALL
45  Java_java_lang_Runtime_freeMemory(JNIEnv *env, jobject this)
46  {
47      return JVM_FreeMemory();
48  }
49
50  JNIEXPORT jlong JNICALL
51  Java_java_lang_Runtime_totalMemory(JNIEnv *env, jobject this)
52  {
53      return JVM_TotalMemory();
54  }
55
56  JNIEXPORT jlong JNICALL
57  Java_java_lang_Runtime_maxMemory(JNIEnv *env, jobject this)
58  {
59      return JVM_MaxMemory();
60  }
61
62  JNIEXPORT void JNICALL
63  Java_java_lang_Runtime_gc(JNIEnv *env, jobject this)
64  {
65      JVM_GC();
66  }
67  
68  JNIEXPORT jint JNICALL
69  Java_java_lang_Runtime_availableProcessors(JNIEnv *env, jobject this)
70  {
71      return JVM_ActiveProcessorCount();
72  }

And these C coding is compiled into the libjava.so (Linux) or libjava.dll (Windows) file, located at JAVA_HOME/jmods/java.base.jmod/lib/libjava.so:

enter image description here

enter image description here

Reference

Mcnair answered 4/4, 2020 at 18:38 Comment(0)
P
7

native is a keyword in java , which is used to make unimplemented structure(method) like as abstract but it would be a platform dependent such as native code and execute from native stack not java stack.

Predominate answered 23/1, 2013 at 16:16 Comment(0)
S
6
  • native is a keyword in Java, it indicates platform dependent.
  • native methods act as an interface between Java (JNI) and other programming languages.
Sticker answered 18/12, 2015 at 22:55 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.