JAVA-26394 Move java-native to core-java modules (#15092)

This commit is contained in:
anuragkumawat
2023-11-04 14:53:37 +05:30
committed by GitHub
parent 36a30dcda8
commit df78df7a81
38 changed files with 4 additions and 5 deletions
+11
View File
@@ -0,0 +1,11 @@
## JNI
This module contains articles about the Java Native Interface (JNI).
### Relevant Articles:
- [Guide to JNI (Java Native Interface)](https://www.baeldung.com/jni)
- [Using JNA to Access Native Dynamic Libraries](https://www.baeldung.com/java-jna-dynamic-libraries)
- [Check if a Java Program Is Running in 64-Bit or 32-Bit JVM](https://www.baeldung.com/java-detect-jvm-64-or-32-bit)
- [How to use JNIs RegisterNatives() method?](https://www.baeldung.com/jni-registernatives)
- [Custom DLL Load Fixing the “java.lang.UnsatisfiedLinkError” Error](https://www.baeldung.com/java-custom-dll-load-fixing-the-java-lang-unsatisfiedlinkerror-error)
+40
View File
@@ -0,0 +1,40 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>java-native</artifactId>
<name>java-native</name>
<parent>
<groupId>com.baeldung.core-java-modules</groupId>
<artifactId>core-java-modules</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<dependencies>
<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna-platform</artifactId>
<version>${jna.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<!-- we don't want to reuse JVMs here ! -->
<reuseForks>false</reuseForks>
</configuration>
</plugin>
</plugins>
</build>
<properties>
<jna.version>5.6.0</jna.version>
</properties>
</project>
@@ -0,0 +1,48 @@
#include "com_baeldung_jni_ExampleObjectsJNI.h"
#include <iostream>
/*
* Class: com_baeldung_jni_ExampleObjectsJNI
* Method: createUser
* Signature: (Ljava/lang/String;D)Lcom/baeldung/jni/UserData;
*/
JNIEXPORT jobject JNICALL Java_com_baeldung_jni_ExampleObjectsJNI_createUser
(JNIEnv *env, jobject thisObject, jstring name, jdouble balance){
// Create the object of the class UserData
jclass userDataClass = env->FindClass("com/baeldung/jni/UserData");
jobject newUserData = env->AllocObject(userDataClass);
// Get UserData fields to set
jfieldID nameField = env->GetFieldID(userDataClass , "name", "Ljava/lang/String;");
jfieldID balanceField = env->GetFieldID(userDataClass , "balance", "D");
// Set the values of the new object
env->SetObjectField(newUserData, nameField, name);
env->SetDoubleField(newUserData, balanceField, balance);
// Return the created object
return newUserData;
}
/*
* Class: com_baeldung_jni_ExampleObjectsJNI
* Method: printUserData
* Signature: (Lcom/baeldung/jni/UserData;)Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_baeldung_jni_ExampleObjectsJNI_printUserData
(JNIEnv *env, jobject thisObject, jobject userData){
// Find the class method id
jclass userDataClass = env->GetObjectClass(userData);
jmethodID methodId = env->GetMethodID(userDataClass, "getUserInfo", "()Ljava/lang/String;");
// Call the object method and get the result
jstring result = (jstring)env->CallObjectMethod(userData, methodId);
// Print the result
std::cout << "C++: User data is: " << env->GetStringUTFChars(result, NULL) << std::endl;
return result;
}
@@ -0,0 +1,29 @@
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_baeldung_jni_ExampleObjectsJNI */
#ifndef _Included_com_baeldung_jni_ExampleObjectsJNI
#define _Included_com_baeldung_jni_ExampleObjectsJNI
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_baeldung_jni_ExampleObjectsJNI
* Method: createUser
* Signature: (Ljava/lang/String;D)Lcom/baeldung/jni/UserData;
*/
JNIEXPORT jobject JNICALL Java_com_baeldung_jni_ExampleObjectsJNI_createUser
(JNIEnv *, jobject, jstring, jdouble);
/*
* Class: com_baeldung_jni_ExampleObjectsJNI
* Method: printUserData
* Signature: (Lcom/baeldung/jni/UserData;)V
*/
JNIEXPORT jstring JNICALL Java_com_baeldung_jni_ExampleObjectsJNI_printUserData
(JNIEnv *, jobject, jobject);
#ifdef __cplusplus
}
#endif
#endif
@@ -0,0 +1,34 @@
#include "com_baeldung_jni_ExampleParametersJNI.h"
#include <iostream>
#include <string>
/*
* Class: com_baeldung_jni_ExampleParametersJNI
* Method: sumIntegers
* Signature: (II)J
*/
JNIEXPORT jlong JNICALL Java_com_baeldung_jni_ExampleParametersJNI_sumIntegers (JNIEnv* env, jobject thisObject, jint first, jint second){
std::cout << "C++: The numbers received are : " << first << " and " << second << std::endl;
return (long)first + (long)second;
}
/*
* Class: com_baeldung_jni_ExampleParametersJNI
* Method: sayHelloToMe
* Signature: (Ljava/lang/String;Z)Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_baeldung_jni_ExampleParametersJNI_sayHelloToMe (JNIEnv* env, jobject thisObject, jstring name, jboolean isFemale){
const char* nameCharPointer = env->GetStringUTFChars(name, NULL);
std::cout << "C++: The string received is: " << nameCharPointer << std::endl;
std::string title;
if(isFemale){
title = "Ms. ";
}
else{
title = "Mr. ";
}
std::string fullName = title + nameCharPointer;
return env->NewStringUTF(fullName.c_str());
}
@@ -0,0 +1,29 @@
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_baeldung_jni_ExampleParametersJNI */
#ifndef _Included_com_baeldung_jni_ExampleParametersJNI
#define _Included_com_baeldung_jni_ExampleParametersJNI
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_baeldung_jni_ExampleParametersJNI
* Method: sumIntegers
* Signature: (II)J
*/
JNIEXPORT jlong JNICALL Java_com_baeldung_jni_ExampleParametersJNI_sumIntegers
(JNIEnv*, jobject, jint, jint);
/*
* Class: com_baeldung_jni_ExampleParametersJNI
* Method: sayHelloToMe
* Signature: (Ljava/lang/String;Z)Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_baeldung_jni_ExampleParametersJNI_sayHelloToMe
(JNIEnv*, jobject, jstring, jboolean);
#ifdef __cplusplus
}
#endif
#endif
@@ -0,0 +1,13 @@
#include "com_baeldung_jni_HelloWorldJNI.h"
#include <iostream>
/*
* Class: com_baeldung_jni_HelloWorldJNI
* Method: sayHello
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_baeldung_jni_HelloWorldJNI_sayHello (JNIEnv* env, jobject thisObject) {
std::string hello = "Hello from C++ !!";
std::cout << hello << std::endl;
return env->NewStringUTF(hello.c_str());
}
@@ -0,0 +1,21 @@
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_baeldung_jni_HelloWorldJNI */
#ifndef _Included_com_baeldung_jni_HelloWorldJNI
#define _Included_com_baeldung_jni_HelloWorldJNI
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_baeldung_jni_HelloWorldJNI
* Method: sayHello
* Signature: ()V
*/
JNIEXPORT jstring JNICALL Java_com_baeldung_jni_HelloWorldJNI_sayHello
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
@@ -0,0 +1,21 @@
#include "com_baeldung_jni_RegisterNativesHelloWorldJNI.h"
#include <iostream>
JNIEXPORT jstring JNICALL hello (JNIEnv* env, jobject thisObject) {
std::string hello = "Hello from registered native C++ !!";
std::cout << hello << std::endl;
return env->NewStringUTF(hello.c_str());
}
static JNINativeMethod methods[] = {
{"sayHello", "()Ljava/lang/String;", (void*) &hello },
};
JNIEXPORT void JNICALL Java_com_baeldung_jni_RegisterNativesHelloWorldJNI_register (JNIEnv* env, jobject thsObject) {
jclass clazz = env->FindClass("com/baeldung/jni/RegisterNativesHelloWorldJNI");
(env)->RegisterNatives(clazz, methods, sizeof(methods)/sizeof(methods[0]));
}
@@ -0,0 +1,29 @@
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_baeldung_jni_RegisterNativesHelloWorldJNI */
#ifndef _Included_com_baeldung_jni_RegisterNativesHelloWorldJNI
#define _Included_com_baeldung_jni_RegisterNativesHelloWorldJNI
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_baeldung_jni_RegisterNativesHelloWorldJNI
* Method: sayHello
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_baeldung_jni_RegisterNativesHelloWorldJNI_sayHello
(JNIEnv *, jobject);
/*
* Class: com_baeldung_jni_RegisterNativesHelloWorldJNI
* Method: register
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_com_baeldung_jni_RegisterNativesHelloWorldJNI_register
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
@@ -0,0 +1,6 @@
REM Create the header with javac -h . ClassName.java
REM Remember to set your JAVA_HOME env var
g++ -c -I%JAVA_HOME%\include -I%JAVA_HOME%\include\win32 com_baeldung_jni_HelloWorldJNI.cpp -o com_baeldung_jni_HelloWorldJNI.o
g++ -c -I%JAVA_HOME%\include -I%JAVA_HOME%\include\win32 com_baeldung_jni_ExampleParametersJNI.cpp -o com_baeldung_jni_ExampleParametersJNI.o
g++ -c -I%JAVA_HOME%\include -I%JAVA_HOME%\include\win32 com_baeldung_jni_ExampleObjectsJNI.cpp -o com_baeldung_jni_ExampleObjectsJNI.o
g++ -shared -o ..\..\..\native\win32\native.dll com_baeldung_jni_HelloWorldJNI.o com_baeldung_jni_ExampleParametersJNI.o com_baeldung_jni_ExampleObjectsJNI.o -Wl,--add-stdcall-alias
@@ -0,0 +1,7 @@
# Create the header with javac -h . ClassName.java
# Remember to set your JAVA_HOME env var
g++ -c -fPIC -I${JAVA_HOME}/include -I${JAVA_HOME}/include/linux com_baeldung_jni_HelloWorldJNI.cpp -o com_baeldung_jni_HelloWorldJNI.o
g++ -c -fPIC -I${JAVA_HOME}/include -I${JAVA_HOME}/include/linux com_baeldung_jni_ExampleParametersJNI.cpp -o com_baeldung_jni_ExampleParametersJNI.o
g++ -c -fPIC -I${JAVA_HOME}/include -I${JAVA_HOME}/include/linux com_baeldung_jni_ExampleObjectsJNI.cpp -o com_baeldung_jni_ExampleObjectsJNI.o
g++ -shared -fPIC -o ../../../native/linux_x86_64/libnative.so com_baeldung_jni_HelloWorldJNI.o com_baeldung_jni_ExampleParametersJNI.o com_baeldung_jni_ExampleObjectsJNI.o -lc
# Don't forget to set java.library.path to point to the folder where you have the libnative you're loading.
@@ -0,0 +1,7 @@
# Create the header with javac -h . ClassName.java
# Remember to set your JAVA_HOME env var
g++ -c -fPIC -I${JAVA_HOME}/include -I${JAVA_HOME}/include/darwin com_baeldung_jni_HelloWorldJNI.cpp -o com_baeldung_jni_HelloWorldJNI.o
g++ -c -fPIC -I${JAVA_HOME}/include -I${JAVA_HOME}/include/darwin com_baeldung_jni_ExampleParametersJNI.cpp -o com_baeldung_jni_ExampleParametersJNI.o
g++ -c -fPIC -I${JAVA_HOME}/include -I${JAVA_HOME}/include/darwin com_baeldung_jni_ExampleObjectsJNI.cpp -o com_baeldung_jni_ExampleObjectsJNI.o
g++ -c -fPIC -I${JAVA_HOME}/include -I${JAVA_HOME}/include/darwin com_baeldung_jni_RegisterNativesHelloWorldJNI.cpp -o com_baeldung_jni_RegisterNativesHelloWorldJNI.o
g++ -dynamiclib -o ../../../native/macos/libnative.dylib com_baeldung_jni_HelloWorldJNI.o com_baeldung_jni_ExampleParametersJNI.o com_baeldung_jni_ExampleObjectsJNI.o com_baeldung_jni_RegisterNativesHelloWorldJNI.o -lc
@@ -0,0 +1,13 @@
#include "com_baeldung_unsatisfiedlink_JniUnsatisfiedLink.h"
#include <iostream>
/*
* Class: com_baeldung_unsatisfiedlink_JniUnsatisfiedLink
* Method: test
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_baeldung_unsatisfiedlink_JniUnsatisfiedLink_test (JNIEnv* env, jobject thisObject) {
std::string test = "Test OK";
std::cout << test << std::endl;
return env->NewStringUTF(test.c_str());
}
@@ -0,0 +1,21 @@
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_baeldung_unsatisfiedlink_JniUnsatisfiedLink */
#ifndef _Included_com_baeldung_unsatisfiedlink_JniUnsatisfiedLink
#define _Included_com_baeldung_unsatisfiedlink_JniUnsatisfiedLink
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_baeldung_unsatisfiedlink_JniUnsatisfiedLink
* Method: test
* Signature: ()V
*/
JNIEXPORT jstring JNICALL Java_com_baeldung_unsatisfiedlink_JniUnsatisfiedLink_test
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
@@ -0,0 +1,22 @@
#!/bin/bash
# Create the header with javac -h . ClassName.java
# Remember to set your JAVA_HOME env var
# Don't forget to set java.library.path to point to the folder where you have the lib you're loading.
MYSELF="$(readlink -f "$0")"
MYDIR="${MYSELF%/*}"
cd "$MYDIR"
class_name=com_baeldung_unsatisfiedlink_JniUnsatisfiedLink
lib_name=test
g++ -c -fPIC -I"${JAVA_HOME}/include" -I"${JAVA_HOME}/include/linux" ${class_name}.cpp -o ${class_name}.o
g++ -shared -fPIC -o lib${lib_name}.so ${class_name}.o -lc
# 32-bit version
g++ -m32 -c -fPIC -I"${JAVA_HOME}/include" -I"${JAVA_HOME}/include/linux" ${class_name}.cpp -o ${class_name}32.o
g++ -m32 -shared -fPIC -o lib${lib_name}32.so ${class_name}32.o -lc
# dummy version
touch ${class_name}-dummy.o
ls lib*
@@ -0,0 +1,10 @@
package com.baeldung.jna;
import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.Platform;
public interface CMath extends Library {
CMath INSTANCE = Native.load(Platform.isWindows() ? "msvcrt" : "c", CMath.class);
double cosh(double value);
}
@@ -0,0 +1,8 @@
package com.baeldung.jna;
public class Main {
public static void main(String[] args) {
}
}
@@ -0,0 +1,46 @@
package com.baeldung.jna;
import java.util.Collections;
import java.util.Map;
import com.sun.jna.FunctionMapper;
import com.sun.jna.LastErrorException;
import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.NativeLong;
import com.sun.jna.Platform;
import com.sun.jna.Structure;
import com.sun.jna.Structure.FieldOrder;
public interface NativeFS extends Library {
FunctionMapper mapper = (library,method) -> {
if (Platform.isWindows()) {
return "_" + method.getName();
}
else {
return "__x" + method.getName(); // On Linux, stat is actually _xstat
}
};
public NativeFS INSTANCE = Native.load(Platform.isWindows() ? "msvcrt" : "c",
NativeFS.class,
Collections.singletonMap(Library.OPTION_FUNCTION_MAPPER, mapper));
int stat(String path, Stat stat) throws LastErrorException;
@FieldOrder({"st_dev","st_ino","st_mode","st_nlink","st_uid","st_gid","st_rdev","st_size","st_atime","st_mtime","st_ctime"})
public class Stat extends Structure {
public int st_dev;
public int st_ino;
public short st_mode;
public short st_nlink;
public short st_uid;
public short st_gid;
public int st_rdev;
public NativeLong st_size;
public NativeLong st_atime;
public NativeLong st_mtime;
public NativeLong st_ctime;
}
}
@@ -0,0 +1,17 @@
package com.baeldung.jna;
import com.sun.jna.LastErrorException;
import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.Platform;
import com.sun.jna.Pointer;
public interface StdC extends Library {
StdC INSTANCE = Native.load(Platform.isWindows() ? "msvcrt" : "c", StdC.class );
Pointer malloc(long n);
void free(Pointer p);
Pointer memset(Pointer p, int c, long n);
int open(String path, int flags) throws LastErrorException;
int close(int fd) throws LastErrorException;
}
@@ -0,0 +1,19 @@
package com.baeldung.jni;
public class ExampleObjectsJNI {
static {
System.loadLibrary("native");
}
public static void main(String[] args) {
ExampleObjectsJNI instance = new ExampleObjectsJNI();
UserData newUser = instance.createUser("John Doe", 450.67);
instance.printUserData(newUser);
}
public native UserData createUser(String name, double balance);
public native String printUserData(UserData user);
}
@@ -0,0 +1,20 @@
package com.baeldung.jni;
public class ExampleParametersJNI {
static {
System.loadLibrary("native");
}
public static void main(String[] args) {
System.out.println("Java: My full name: " + new ExampleParametersJNI().sayHelloToMe("Martin", false));
long sumFromNative = new ExampleParametersJNI().sumIntegers(456, 44);
System.out.println("Java: The sum coming from native code is: " + sumFromNative);
}
// Declare another method sumIntegers that receives two integers and return a long with the sum
public native long sumIntegers(int first, int second);
// Declare another method sayHelloToMe that receives the name and gender and returns the proper salutation
public native String sayHelloToMe(String name, boolean isFemale);
}
@@ -0,0 +1,15 @@
package com.baeldung.jni;
public class HelloWorldJNI {
static {
System.loadLibrary("native");
}
public static void main(String[] args) {
new HelloWorldJNI().sayHello();
}
// Declare a native method sayHello() that receives no arguments and returns void
public native String sayHello();
}
@@ -0,0 +1,18 @@
package com.baeldung.jni;
public class RegisterNativesHelloWorldJNI {
static {
System.loadLibrary("native");
}
public static void main(String[] args) {
RegisterNativesHelloWorldJNI helloWorldJNI = new RegisterNativesHelloWorldJNI();
helloWorldJNI.register();
helloWorldJNI.sayHello();
}
public native String sayHello();
public native void register();
}
@@ -0,0 +1,11 @@
package com.baeldung.jni;
public class UserData {
public String name;
public double balance;
public String getUserInfo() {
return "[name]=" + name + ", [balance]=" + balance;
}
}
@@ -0,0 +1,24 @@
package com.baeldung.jvmbitversion;
import com.sun.jna.Platform;
public class JVMBitVersion {
public String getUsingSystemClass() {
return System.getProperty("sun.arch.data.model") + "-bit";
}
public String getUsingNativeClass() {
if (com.sun.jna.Native.POINTER_SIZE == 8) {
return "64-bit";
} else if (com.sun.jna.Native.POINTER_SIZE == 4) {
return "32-bit";
} else
return "unknown";
}
public boolean getUsingPlatformClass() {
return (Platform.is64Bit());
}
}
@@ -0,0 +1,15 @@
package com.baeldung.unsatisfiedlink;
public class JniUnsatisfiedLink {
public static final String LIB_NAME = "test";
public static void main(String[] args) {
System.loadLibrary(LIB_NAME);
new JniUnsatisfiedLink().test();
}
public native String test();
public native String nonexistentDllMethod();
}
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
</pattern>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="STDOUT" />
</root>
</configuration>
@@ -0,0 +1,3 @@
grant {
permission java.lang.RuntimePermission "loadLibrary.test";
};
@@ -0,0 +1,18 @@
package com.baeldung.jna;
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.Test;
import com.sun.jna.Native;
import com.sun.jna.Platform;
class CMathUnitTest {
@Test
void whenCallNative_thenSuccess() {
CMath lib = Native.load(Platform.isWindows() ? "msvcrt" : "c", CMath.class);
double result = lib.cosh(0);
assertEquals(1.0,result);
}
}
@@ -0,0 +1,38 @@
package com.baeldung.jna;
import static org.junit.Assert.fail;
import static org.junit.jupiter.api.Assertions.assertEquals;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import org.junit.jupiter.api.Test;
import com.baeldung.jna.NativeFS.Stat;
import com.sun.jna.LastErrorException;
import com.sun.jna.Platform;
public class NativeFSUnitTest {
@Test
public void whenCallNative_thenSuccess() throws IOException {
NativeFS lib = NativeFS.INSTANCE;
File f = Files.createTempFile("junit", ".bin").toFile();
f.deleteOnExit();
Stat stat = new Stat();
try {
if (Platform.isWindows()) {
int rc = lib.stat(f.getAbsolutePath(), stat);
assertEquals(0, rc);
assertEquals(0,stat.st_size.longValue());
}
}
catch(LastErrorException error) {
fail("stat failed: error code=" + error.getErrorCode());
}
}
}
@@ -0,0 +1,47 @@
package com.baeldung.jna;
import static org.junit.jupiter.api.Assertions.*;
import org.junit.BeforeClass;
import org.junit.jupiter.api.Test;
import com.sun.jna.Native;
import com.sun.jna.Platform;
import com.sun.jna.Pointer;
class StdCUnitTest {
@BeforeClass
public static void setupProtectedMode() {
Native.setProtected(true);
}
@Test
public void whenMalloc_thenSuccess() {
StdC lib = StdC.INSTANCE;
Pointer p = lib.malloc(1024);
p.setMemory(0l, 1024l, (byte) 0);
lib.free(p);
}
@Test
public void whenAccessViolation_thenShouldThrowError() {
// Running this test on Linux requires additional setup using libjsig.so
// Details here: http://java-native-access.github.io/jna/5.6.0/javadoc/overview-summary.html#crash-protection
// IMPORTANT NOTICE: Code for illustration purposes only. DON'T DO THIS IN YOUR OWN CODE
if ( Platform.isWindows()) {
Error e = null;
Pointer p = new Pointer(0l);
try {
p.setMemory(0, 100*1024, (byte) 0);
}
catch(Error err) {
e = err;
}
assertNotNull(e, "Should throw Error");
}
}
}
@@ -0,0 +1,58 @@
package com.baeldung.jni;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import org.junit.Before;
import org.junit.Test;
public class JNINativeManualTest {
@Before
public void setup() {
System.loadLibrary("native");
}
@Test
public void whenNativeHelloWorld_thenOutputIsAsExpected() {
HelloWorldJNI helloWorld = new HelloWorldJNI();
String helloFromNative = helloWorld.sayHello();
assertTrue(!helloFromNative.isEmpty() && helloFromNative.equals("Hello from C++ !!"));
}
@Test
public void whenSumNative_thenResultIsArithmeticallyCorrect() {
ExampleParametersJNI parametersNativeMethods = new ExampleParametersJNI();
assertTrue(parametersNativeMethods.sumIntegers(200, 400) == 600L);
}
@Test
public void whenSayingNativeHelloToMe_thenResultIsAsExpected() {
ExampleParametersJNI parametersNativeMethods = new ExampleParametersJNI();
assertEquals(parametersNativeMethods.sayHelloToMe("Orange", true), "Ms. Orange");
}
@Test
public void whenCreatingNativeObject_thenObjectIsNotNullAndHasCorrectData() {
String name = "Iker Casillas";
double balance = 2378.78;
ExampleObjectsJNI objectsNativeMethods = new ExampleObjectsJNI();
UserData userFromNative = objectsNativeMethods.createUser(name, balance);
assertNotNull(userFromNative);
assertEquals(userFromNative.name, name);
assertTrue(userFromNative.balance == balance);
}
@Test
public void whenNativeCallingObjectMethod_thenResultIsAsExpected() {
String name = "Sergio Ramos";
double balance = 666.77;
ExampleObjectsJNI objectsNativeMethods = new ExampleObjectsJNI();
UserData userData = new UserData();
userData.name = name;
userData.balance = balance;
assertEquals(objectsNativeMethods.printUserData(userData), "[name]=" + name + ", [balance]=" + balance);
}
}
@@ -0,0 +1,26 @@
package com.baeldung.jni.registernatives;
import com.baeldung.jni.RegisterNativesHelloWorldJNI;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
public class JNIRegisterNativesManualTest {
@Before
public void setup() {
System.loadLibrary("native");
}
@Test
public void whenRegisteredNativeHelloWorld_thenOutputIsAsExpected() {
RegisterNativesHelloWorldJNI helloWorld = new RegisterNativesHelloWorldJNI();
helloWorld.register();
String helloFromNative = helloWorld.sayHello();
assertNotNull(helloFromNative);
assertTrue(helloFromNative.equals("Hello from registered native C++ !!"));
}
}
@@ -0,0 +1,45 @@
package com.baeldung.jvmbitversion;
import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.Before;
import org.junit.Test;
import com.sun.jna.Platform;
public class JVMBitVersionUnitTest {
private JVMBitVersion jvmVersion;
@Before
public void setup() {
jvmVersion = new JVMBitVersion();
}
@Test
public void whenUsingSystemClass_thenOutputIsAsExpected() {
if ("64".equals(System.getProperty("sun.arch.data.model"))) {
assertEquals("64-bit", jvmVersion.getUsingSystemClass());
} else if ("32".equals(System.getProperty("sun.arch.data.model"))) {
assertEquals("32-bit", jvmVersion.getUsingSystemClass());
}
}
@Test
public void whenUsingNativeClass_thenResultIsAsExpected() {
if (com.sun.jna.Native.POINTER_SIZE == 8) {
assertEquals("64-bit", jvmVersion.getUsingNativeClass());
} else if (com.sun.jna.Native.POINTER_SIZE == 4) {
assertEquals("32-bit", jvmVersion.getUsingNativeClass());
}
}
@Test
public void whenUsingPlatformClass_thenResultIsAsExpected() {
if (Platform.is64Bit() == Boolean.TRUE) {
assertEquals(Boolean.TRUE, jvmVersion.getUsingPlatformClass());
} else if (com.sun.jna.Native.POINTER_SIZE == 4) {
assertEquals(Boolean.FALSE, jvmVersion.getUsingPlatformClass());
}
}
}
@@ -0,0 +1,105 @@
package com.baeldung.unsatisfiedlink;
import static com.baeldung.unsatisfiedlink.JniUnsatisfiedLink.LIB_NAME;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.io.File;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
public class JniUnsatisfiedLinkManualTest {
static String osLibPrefix = "";
static String osLibSuffix = "";
@BeforeAll
static void setup() {
String osName = System.getProperty("os.name")
.toLowerCase();
if (osName.contains("win")) {
osLibSuffix = ".dll";
} else if (osName.contains("nix") || osName.contains("nux") || osName.contains("mac")) {
osLibPrefix = "lib";
osLibSuffix = ".so";
if (osName.contains("mac")) {
osLibPrefix = "lib";
osLibSuffix = ".dylib";
}
} else {
throw new UnsupportedOperationException("Unsupported operating system: " + osName);
}
}
@Test
public void whenCorrectLibName_thenLibLoaded() {
assertDoesNotThrow(() -> {
System.loadLibrary(LIB_NAME);
new JniUnsatisfiedLink().test();
});
}
@Test
public void whenIncorrectLibName_thenLibNotFound() {
String libName = osLibPrefix + LIB_NAME + osLibSuffix;
Error error = assertThrows(UnsatisfiedLinkError.class, () -> System.loadLibrary(libName));
assertEquals(String.format("no %s in java.library.path", libName), error.getMessage());
}
@Test
public void whenLoadLibraryContainsPathSeparator_thenErrorThrown() {
String libName = "/" + LIB_NAME;
Error error = assertThrows(UnsatisfiedLinkError.class, () -> System.loadLibrary(libName));
assertEquals(String.format("Directory separator should not appear in library name: %s", libName), error.getMessage());
}
@Test
public void whenLoadWithoutAbsolutePath_thenErrorThrown() {
String libName = LIB_NAME;
Error error = assertThrows(UnsatisfiedLinkError.class, () -> System.load(libName));
assertEquals(String.format("Expecting an absolute path of the library: %s", libName), error.getMessage());
}
@Test
public void whenUnlinkedMethod_thenErrorThrown() {
System.loadLibrary(LIB_NAME);
Error error = assertThrows(UnsatisfiedLinkError.class, () -> new JniUnsatisfiedLink().nonexistentDllMethod());
assertTrue(error.getMessage()
.contains("JniUnsatisfiedLink.nonexistentDllMethod"));
}
@Test
public void whenIncompatibleArchitecture_thenErrorThrown() {
Error error = assertThrows(UnsatisfiedLinkError.class, () -> System.loadLibrary(LIB_NAME + "32"));
assertTrue(error.getMessage()
.contains("wrong ELF class: ELFCLASS32"));
}
@Test
public void whenCorruptedFile_thenErrorThrown() {
String libPath = System.getProperty("java.library.path");
assertNotNull(libPath);
String dummyLib = LIB_NAME + "-dummy";
assertTrue(new File(libPath, osLibPrefix + dummyLib + osLibSuffix).isFile());
Error error = assertThrows(UnsatisfiedLinkError.class, () -> System.loadLibrary(dummyLib));
assertTrue(error.getMessage()
.contains("file too short"));
}
}
+1
View File
@@ -199,6 +199,7 @@
<module>core-java-date-operations-1</module>
<!--<module>core-java-datetime-conversion</module>--> <!--JAVA-25433-->
<module>core-java-httpclient</module>
<module>java-native</module>
</modules>
<dependencyManagement>