/jnhw

JNI Header Wrapper a lightwight alternative to JNA or JNR (V 4.0.0-SNAPSHOT in branch FFM uses JEP 454: Foreign Function & Memory API)

Primary LanguageJava

Java Native Header Wrapper (JNHW)

JNI Header Wrapper a lightweight alternative to JNA or JNR and a helper to resolve a native lib by name and libtool version.

Unlike JNR or JNA

A running "real life" comparison can be found here: JNHW-Example: Compare JNHW, JNR, JNA.

Add this dependency for POSIX.

<dependency>
    <groupId>de.ibapl.jnhw</groupId>
    <artifactId>de.ibapl.jnhw.posix</artifactId>
    <version>[3.0.0,4.0.0)</version>
</dependency>

and this for the Windows API

<dependency>
    <groupId>de.ibapl.jnhw</groupId>
    <artifactId>de.ibapl.jnhw.winapi</artifactId>
    <version>[3.0.0,4.0.0)</version>
</dependency>

Usage

Error Handling

If an native error occured and the called function flags an error condition to the caller. One calls for ISO C errno and for the windows API GetLastError(). this is done in the jni wrapper which throws the checked exception NativeErrorException in that case.

State

Branch master

Test Platform VM version Hotspot VM (Java Foreign) Zero VM (Java Foreign) Hotspot VM (JNI) Zero VM (JNI)
aarch64-linux-gnu 19.0.1 success 2023-01-26 success 2023-01-27 success 2023-01-27 crashed 2023-01-27
arm-linux-gnueabihf 19.0.1 n.a. 2023-01-26 n.a. 2023-01-26 success 2023-01-26 success 2023-01-26
i386-linux-gnu 19.0.1 n.a. 2023-01-26 n.a. 2023-01-26 success 2023-01-26 success 2023-01-26
mipsel-linux-gnu 19.0.1 n.a. 2023-01-26 n.a. 2023-01-26 n.a. 2023-01-26 success 2023-01-26
mips64el-linux-gnu 19.0.1 n.a. 2023-01-27 n.a. 2023-01-27 n.a. 2023-01-27
powerpc-linux-gnu 19.0.1 n.a. 2023-01-26 n.a. 2023-01-26 n.a. 2023-01-26 crashed 2023-01-26
powerpc64le-linux-gnu 19.0.1 n.a. 2023-01-26 n.a. 2023-01-26 success 2023-01-26 success 2023-01-26
riscv64-linux-gnu 19.0.1 n.a. 2023-01-26 n.a. 2023-01-26 success 2023-01-26 success 2023-01-26
s390x-linux-gnu 19.0.1 n.a. 2023-01-26 n.a. 2023-01-26 success 2023-01-26 success 2023-01-26
x86_64-apple-darwin 19.0.1 success 2023-01-27 n.a. 2023-01-27 success 2023-01-26 n.a. 2023-01-27
x86_64-freebsd-bsd 19.0.1 success 2023-01-27 n.a. 2023-01-26 success 2023-01-27 n.a. 2023-01-26
x86_64-openbsd-bsd 19.0.1 no OpenJDK19 2023-01-27 no OpenJDK19 2023-01-27 no OpenJDK19 2023-01-27 no OpenJDK19 2023-01-27
x86_64-linux-gnu 19.0.1 success 2023-01-26 crashed 2023-01-26 success 2023-01-26 success 2023-01-26
x86_64-windows-pe32+ 19.0.1 success 2023-01-26 n.a. 2023-01-27 success 2023-01-27 zero n.a. 2023-01-27

n.a. ... the VM and/or feature are not available.

Demos

Hello World

See subdirectory it/hello-world/. run mvn exec:java -Dexec.mainClass="de.ibapl.jnhw.it.hello_world.App" in it/hello_world.

POSIX

Import Unistd in a static manner so the code may become less noisy.

package de.ibapl.jnhw.it.hello_world;

import de.ibapl.jnhw.NativeErrorException;
//Import only the needed define from the wrapper of posix's unistd.h.h
import static de.ibapl.jnhw.posix.Unistd.STDOUT_FILENO;
//Import only the needed method from the wrapper of iso c's unistd.h.h
import static de.ibapl.jnhw.posix.Unistd.write;

public class Posix {

	public static void sayHello() throws NativeErrorException {
		int bytesWritten = write(STDOUT_FILENO, "Hello World! from POSIX\n".getBytes());
                System.out.println("Bytes written: " + bytesWritten);
	}

}

Windows API

package de.ibapl.jnhw.it.hello_world;

import de.ibapl.jnhw.NativeErrorException;
//Import only the needed define from the wrapper of processenv.h
import static de.ibapl.jnhw.winapi.Winbase.STD_OUTPUT_HANDLE;
//Import only the needed method from the wrapper of processenv.h
import static de.ibapl.jnhw.winapi.ProcessEnv.GetStdHandle;
//Import only the needed method from the wrapper of fileapi.h
import static de.ibapl.jnhw.winapi.Fileapi.WriteFile;

public class Windows {

	public static void sayHello() throws NativeErrorException {
		int bytesWritten = WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), "Hello World! from WIN API\n".getBytes());
                System.out.println("Bytes written: " + bytesWritten);
	}

}

create a file named test.c and include the needed headers. run

gcc  -dD -dI -E test.c  | less

to see the preprocessed defines