Java Native Access

Java Native Access (JNA) is a community-developed library that provides Java programs easy access to native shared libraries without using the Java Native Interface. JNA's design aims to provide native access in a natural way with a minimum of effort. No boilerplate or generated glue code is required.

Java Native Access
Original author(s)Todd Fast, Timothy Wall, Liang Chen
Initial releaseMay 9, 2007 (2007-05-09)
Stable release
5.5.0 / July 19, 2019 (2019-07-19)[1]
Repository
Written inC and Java
Operating systemWindows, macOS, Android, AIX, FreeBSD, GNU/Linux, OpenBSD, Solaris, Windows Mobile
PlatformJava 1.4 or later (for JNA 3.5.2 or earlier), Java 1.6 for JNA 4.0.0 and later
Size1.83 MB (archived)
TypeSoftware Library
LicenseLGPL version 2.1 or later and (from version 4.0 onward) the Apache Software License, version 2.0
Websitegithub.com/java-native-access/jna

Architecture

The JNA library uses a small native library called foreign function interface library (libffi) to dynamically invoke native code. The JNA library uses native functions allowing code to load a library by name and retrieve a pointer to a function within that library, and uses libffi library to invoke it, all without static bindings, header files, or any compile phase. The developer uses a Java interface to describe functions and structures in the target native library. This makes it quite easy to take advantage of native platform features without incurring the high development overhead of configuring and building JNI code.

JNA is built and tested on macOS, Microsoft Windows, FreeBSD / OpenBSD, Solaris, GNU with Linux, AIX, Windows Mobile, and Android. It is also possible to tweak and recompile the native build configurations to make it work on most other platforms that run Java.

Mapping types

The following table shows an overview of types mapping between Java and native code and supported by the JNA library.[2]

C Type Size Java Language Type Common Windows Types
char 8-bit integer byte BYTE, TCHAR
short 16-bit short short WORD
wchar_t 16/32-bit character char WCHAR, TCHAR
int 32-bit integer int DWORD
int boolean value boolean BOOL
long 32/64-bit integer NativeLong LONG
long long, __int64 64-bit integer long LONGLONG
float 32-bit FP float
double 64-bit FP double
char* C string String LPCTSTR
void* pointer Pointer LPVOID, HANDLE, LPXXX

Note: The meaning of TCHAR changes between char and wchar_t according to some preprocessor definitions. LPCTSTR follows.

Memory byte alignment for data structures

Native libraries have no standardized memory byte alignment flavor. JNA defaults to an OS platform specific setting, that can be overridden by a library specific custom alignment. If the alignment details are not given in the documentation of the native library, the correct alignment must be determined by trial and error during implementation of the Java wrapper.

Example

The following program loads the local C standard library implementation and uses it to call the printf function.

Note: The following code is portable and works the same on Windows and GNU+Linux / Unix / macOS platforms.

import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.Platform;

/** Simple example of native library declaration and usage. */
public class HelloWorld {
    public interface CLibrary extends Library {
        CLibrary INSTANCE = (CLibrary) Native.loadLibrary(
            (Platform.isWindows() ? "msvcrt" : "c"), CLibrary.class);
        void printf(String format, Object... args);
    }

    public static void main(String[] args) {
        CLibrary.INSTANCE.printf("Hello, World\n");
        for (int i = 0; i < args.length; i++) {
            CLibrary.INSTANCE.printf("Argument %d: %s\n", i, args[i]);
        }
    }
}

The following program loads the C POSIX library and uses it to call the standard mkdir function.

Note: The following code is portable and works the same on POSIX standards platforms.

import com.sun.jna.Library;
import com.sun.jna.Native;

/** Simple example of native C POSIX library declaration and usage. */
public class ExampleOfPOSIX {
    public interface POSIX extends Library {
	    public int chmod(String filename, int mode);
	    public int chown(String filename, int user, int group);
	    public int rename(String oldpath, String newpath);
	    public int kill(int pid, int signal);
	    public int link(String oldpath, String newpath);
	    public int mkdir(String path, int mode);
	    public int rmdir(String path);
    }

    public static void main(String[] args) {
        POSIX posix = (POSIX) Native.loadLibrary("c", POSIX.class);
	    posix.mkdir("/tmp/newdir", 0777);
	    posix.rename("/tmp/newdir","/tmp/renamedir");
    }
}

The program below loads the Kernel32.dll and uses it to call the Beep and Sleep functions.

Note: The following code works only on Windows platforms.

import com.sun.jna.Library;
import com.sun.jna.Native;

/** Simple example of Windows native library declaration and usage. */
public class BeepExample {
    public interface Kernel32 extends Library {
        // FREQUENCY is expressed in hertz and ranges from 37 to 32767
        // DURATION is expressed in milliseconds
        public boolean Beep(int FREQUENCY, int DURATION);
        public void Sleep(int DURATION);
    }

    public static void main(String[] args) {
	    Kernel32 lib = (Kernel32) Native.loadLibrary("kernel32", Kernel32.class);
	    lib.Beep(698, 500);
	    lib.Sleep(500);
	    lib.Beep(698, 500);
    }
}

Adoption

Java Native Access is known to be used in the following projects:

  • Armed Bear Common Lisp, using JNA for its CFFI implementation[3]
  • JRuby, using JNA for POSIX functionality[4][5]
  • Freedom for Media in Java (FMJ)[6]
  • IntelliJ IDEA IDE by the company JetBrains
  • OpenSearchServer, an open source search engine and web crawler
  • SVNKit, a pure Java Subversion client library with optional native library integration through the JNA
  • VLC media player, via the vlcj library[7]
  • Cyberduck FTP, SFTP, WebDAV, Cloud Files & Amazon S3 Browser for macOS
  • Log4j, a library of native log appenders[8]
  • Hudson and Jenkins continuous integration servers
  • Webdriver
  • YAJSW (Yet Another Java Service Wrapper)
  • Cassandra, an open source distributed database from the Apache Software Foundation uses JNA[9]
gollark: I saw you were asking about Zig.
gollark: Hello!
gollark: That's a weird bee.
gollark: I mean, you've functionally left anyway. But still.
gollark: You just said it.

See also

References

  1. "Release 5.5.0". Groups.google.com. 2019-10-30.
  2. "Default Type Mappings". jna.dev.java.net. Retrieved 2011-08-02.
  3. "asdf/cffi – armedbear". Abcl.org. Retrieved 7 December 2018.
  4. Nutter, Charles Oliver (2 September 2007). "Java Native Access + JRuby = True POSIX". Retrieved 7 December 2018.
  5. "JNA brings native code to JRuby". infoq.com. 2007-09-05. Retrieved 2010-05-22.
  6. "Home - FMJ". Fmj-sf.net. Retrieved 7 December 2018.
  7. "vlcj". Capricasoftware.co.uk. Caprica Software Limited. Retrieved 2018-10-23.
  8. "dblock/log4jna". GitHub. Retrieved 2018-10-23.
  9. "apache/cassandra". GitHub. Retrieved 7 December 2018.
This article is issued from Wikipedia. The text is licensed under Creative Commons - Attribution - Sharealike. Additional terms may apply for the media files.