SlideShare a Scribd company logo
1 of 48
Download to read offline
JNA - Let’s C what it’s worth
Author: Idan Sheinberg
whoami
Freelance software developer and all things open-source
Hobbyist software developer and all things open-source
Not much time for other stuff...
Let’s Start From The Begining
JNA - Java Native Access - A means to access C/C++ code from the JVM.
C/C++ (native) code is made accessible to the JNA by compiling it to a shared library.
Yep, that means DLLs (Windows), SOs (Linux) or Dylibs(OSX).
By using JNA, we are able to access native methods as if they were defined inside
standard JVM jars.
Why Should I Even Do That?
Be a Java programmer.
Not (want to) be a C/C++ programmer
Need a functionality/API provided only by native code.
Need to interface with specific hardware only accessible through native code.
Be a masochist/adventurous (maybe the same).
Don’t we already have JNI for that?
JNI is the standard approach for interfacing with code written in C/C++ from the JVM.
With JNI, the programmer must write C/C++ glue code to bridge the access to the actual
native code you’re trying to interface with.
That’s harder than your average Java related programming task,
and also requires proficiency in at least the C.
One might argue that a high-level language with a native
interface should rid its practician from writing native code.
A few more JNI facts
Lots of the low level mechanics in the JVM are implemented using JNI.
⏣ FileOutputStream, SocketInputStream, etc...
JNI allows for full, bi-directional interaction with JVM heap objects.
⏣ It was designed for the purpose of serving as an extension/foundation to the JVM.
⏣ That’s probably the main cause for its sluggish/clumsy design.
JNA, on the other hand, was created to solely ease the access to native code.
⏣ As there’s no(t supposed to be any) C/C++ code to write, there’s no point in dealing with bi-directional
access.
How does JNA work?
JNA uses libffi (Foriegn Function Interface Library) to invoke functions found in compiled
C/C++ code from the JVM:
⏣ JNA uses a JNI (no kidding) library named libjnidispatch to glue libffi and handle type mapping & method
proxying.
⏣ JNA (via libjnidispatch) also provides access to some useful low-level functions - malloc,memset,free,
etc...
⏣ libffi supports many, many CPU architectures, operating systems and compilers, allowing JNA to function
seamlessly regardless of the execution environment.
Working with JNA
A tutorial for the eager beaver.
A quick start
Given the following sample program:
sample-lib.h:
void printer(const char * input);
sample-lib.c:
#include <stdio.h>
#include <sample-lib.h>
void printer(const char * input)
{
printf("Input - %sn",input );
}
A quick start
A matching JNA endpoint class might look like this:
SampleLib.java:
package org.sheinbergon.jna.sample;
import com.sun.jna.Native;
public class SampleLib {
private final static String SAMPLE = "sample-lib";
static {
Native.register(SAMPLE);
}
public static native void printer(String input);
}
Working with structures
Let’s define a C structure and a method to manipulate it:
sample-structure-lib.h:
typedef struct sample_structure {
unsigned long int random;
} SAMPLE_STRUCT;
void random(const SAMPLE_STRUCTURE *);
sample-structure-lib.c:
#include <time.h>
#include <stdlib.h>
#include <sample-structure-lib.h>
void random(const SAMPLE_STRUCT * strct)
{
srand(time(NULL));
strct->number = rand();
}
Working with structures
First, let’s define a matching Structure class in Java:
SampleStruct.java:
package org.sheinbergon.jna.sample;
import com.sun.jna.Structure;
public class SampleStruct extends Structure {
public int number ;
@Override
protected List<String> getFieldOrder() {
return List.of("number");
}
}
Working with structures
Now, for the matching JNA endpoint class:
SampleStructureLib.java:
package org.sheinbergon.jna.sample;
import com.sun.jna.Native;
public class SampleStructureLib {
private final static String SAMPLE_STRUCTURE = "sample-structure-lib";
static {
Native.register(SAMPLE_STRUCTURE);
}
public static native void random(SampleStruct struct);
}
Making DLLs available to the JVM.
The JVM uses the OS library search path to begin with.
⏣ $LD_LIBRARY_PATH and ldconfig on Linux
⏣ %PATH% and Windows/System Directory on Windows.
The local resource classpath should also work.
⏣ Be sure to place library file inside a directory matching the proper CPU architecture - linux-x86-64 for
linux 64 bit, win32-x86-64 for windows 64 bit, etc.
⏣ File suffix/prefix is determined per OS - Loading a DLL named java-jna implies searching for a file named
libjava-jna.so on Linux and java-jna.dll on Windows.
And of course, there’s jna.library.path or java.library.path system properties
Type Mapping
Working with pointers has never been more FUN!
Where’s that manual
Standard JNA Type Mapping - https://github.com/java-native-access/jna/blob/master/www/Mappings.md.
Unfortunately, the list above is lacking big time.
⏣ C/C++ coding conventions encourage passing pointers/references to maintain an efficient and flexible stack.
⏣ As opposed to JAVA, native function declaration does not differentiate between pointers to allocated memory
or garbage.
⏣ Following such rules & guidelines with JNA is a bit trickier, and a lot more confusing. For the very least, it’s
going to take some getting used to.
Pointer
JNA provides us with the Pointer class. As its name implies, it proxies a native pointer.
⏣ Remember, A pointer does not necessarily refer to allocated memory!
Common use cases for mapping types to a Pointer:
⏣ Pointers to types you don’t care about.
⏣ void * method/function argument/return type.
⏣ Instantiating a Structure sub-class.
Pointer
Native code allows you to read any type of data at any offset using a pointer. A JNA
Pointer provide the same functionality:
⏣ Let’s say we have int * cp = ...
⏣ For Pointer jp , calling jp.getInt(0L) is the same as *cp (the int value itself).
⏣ jp.getInt(4L) is the same *(cp+1). Pointer offset in native code matches sizeof(type)
You can also copy entire arrays from native memory.
⏣ jp.getIntArray(0L,5) copies 20 bytes (5 * int32) from the location pointed by p to the JVM heap.
⏣ Useful for reading structure fields populated inside the native code.
ByReference
char * is automatically translated to(and from) String.
But what about other types, like int * for example ?
⏣ Are we dealing with a reference to pre-allocated or unallocated memory ? are we referencing an array or a
single value?
For single value references, JNA provides us with smart(ish) types like IntByReference
⏣ From the Java developer’s point-of-view, they are convenient containers that allow us to pass pointers to a
JNA mapped method, and read the value set in a clearer way.
What about void ** ?
⏣ PointerByReference is your friend.
Memory
A sub class of Pointer, representing allocated native memory
⏣ That’s memory allocated on the native heap, of course.
⏣ Allocation takes place on instance construction (i.e. new Memory(20L)).
Memory is one of the most useful classes when working with JNA:
⏣ Use whenever you need to pre-allocate a buffer to be populated by the innards of native method.
⏣ That’s a pretty common use-case.
Quite simple, ain’t it?
CAVEATS
Things are never that simple...
Structures limitations
Bit-Fields are not supported.
⏣ Aggregate all relevant bit fields onto the nearest type and parse possible bit values using bitwise operators.
C:
struct bitfields
{
unsigned short f1 : 7;
unsigned short f2 : 9;
};
JAVA:
public class BitFields extends Structure {
public short fshort;
}
Multi-Dimensional arrays are not supported.
⏣ Uni-dimensional arrays are just fine, so just be sure to encompass all of the dimensions size specifications -
a field of type char buffer[3][4][5] in a C struct should be mapped as byte[] buffer = byte[60] in a
matching JAVA Structure sub-class.
Be accurate with your type selection/inclusion - Core dumps are no fun!
Passing allocated memory
Let’s say a native void function expects an allocated byte buffer (char buffer[size]).
⏣ Function declaration would be in the form of void func(char * buffer).
One might guess that the matching JNA setup should look like this:
⏣ Define a native method static native void func(ByteByReference buffer).
⏣ Create a buffer byte [] buffer = new byte[size], put it inside a pointer new ByteByReference(byte[0]) and
pass it on to the method.
Passing allocated memory - Doing it Right
JVM heap allocated arrays are NOT the same as native allocated memory:
⏣ Define a native method static native void func(Pointer buffer).
⏣ Create a Memory(size) buffer instance and pass it on. Memory is a sub-class of Pointer class, so no
problem there.
Structure sub-classes array fields are an exception, and are considered valid.
⏣ The JNA layer takes care of copying from/to native code and memory allocation
C:
struct yarrr
{
byte by[20];
};
JAVA:
public class Yarrr extends Structure {
public byte [] by = new byte[20];
}
memory allocation
Consider the following native code sample:
// Struct definition
typedef struct {
char * f1;
int f2;
} STRUCT;
// Some function
void func(STRUCT * S){...}
// Main code loop
for(int i=0;; i++) {
STRUCT s = { .f1 = "text", .f2 = i };
...
func(s);
}
memory allocation
Matching JNA mapping might look like this:
// Struct defintion
public class Struct extends Structure {
public static Struct of(String f1,int f2){Struct s = new Struct();s.f1=f1;s.f2=f2;return s;}
public String f1;
public int f2;
...
}
// JNA function mapping
static native void func(Struct s);
// Main code loop
for(int i=0;; i++) {
Struct s = Struct.of("text",i);
...
func(s);
}
memory allocation - pressure
In C, a local variable’s memory is allocated in the stack on declaration and gets
deallocated once it goes out of scope:
⏣ Out of scope means end of block - loop iteration, function end, etc.
⏣ Local means every variable inside the bounds of a block aside from memory explicitly allocated.
In the JVM, class instances are created inside the heap and would eventually get GC’d
once they are no longer referenced.
Eventually being the keyword - it’s not always fast-enough…
⏣ This behavior could lead to memory exhaustion, native memory contention, sluggishness, and ugly crashes.
Memory allocation - pressure - Solution
In order to simulate native C stack memory allocation, we could simply reuse structure
instances instead of re-allocating them in each loop iteration.
⏣ Please don’t forget to “clear” the structure before reusing (“cheaper” than additional memory allocation).
// Main code loop
Struct s = new Struct();
for(int i=0;; int++) {
s.clear();
s1.f1 = “text”;
s1.f2 = i;
...
func(s);
}
Weak-References
Weak references refer to object instances that might be GC’d during contention, even
though the instances themselves might still be in-use/referenced.
⏣ Say we have a method void callee(SomeObject obj){...}
⏣ Calling it with callee(new SomeObject()) will create a weak-reference to that SomeObject instance.
Doing the same with JNA mapped structures are no different, of course. The
consequences, however, are far more impactful:
⏣ Structure GC also frees native memory. That memory might still be currently accessed by native code.
⏣ In fact, sometimes structures allocated are not meant to be freed as part of the ongoing flow.
Weak-References - Solution
Make sure everything passed down through JNA proxied methods is strongly referenced.
⏣ Static fields or members of singletons/objects the only go out of scope as part of lifecycle management
⏣ This applies to Structure , Pointer , Callback , *ByReference subclasses/instances.
Memory Pressure - Structure Synchronization
When passing Structure sub-classes through JNA mapped methods, Object fields defined
in the JVM need to be written to native memory and made available to the native code.
⏣ The same goes for fields being read after a JNA method call.
The problem starts when you’re dealing with nested structure definition (consider
structure array fields, re-instantiating on each read).
This could cause heap memory exhaustion and slow down you’re overall application
performance.
⏣ A Full GC might also be triggered, causing weak-reference (and other) issues to arise earlier.
Memory Pressure - Structure Synchronization - Solution
Luckily for us, we can choose what gets synced and what does not:
⏣ We can disable or enable read/write synchronization separately or both altogether.
public class Sync extends Strucutre {public int f1;...}
Sync s = new Sync();
s.setAutoWrite(false); // Disable only pre JNA method write sync
s.setAutoSynch(true); // Enable both read and write sync;
⏣ For maximum efficiency, we can also synchronize specific fields manually.
s.readField("f1"); // Post JNA method call
Only read/write fields that are required to properly fulfill the code’s functionality.
Memory Corruption - Pragma pack
Native code compilers might pad structure fields, so they’ll match the default byte
alignment of the target CPU architecture.
⏣ Given a structure that’s supposed to require 5 bytes:
struct structure {
char f1; // 1 bytes
in32_t f2; // 4 bytes
};
⏣ Memory allocated for the structure might be “rounded” up to 8 bytes:
struct structure {
char f1; // 1 bytes
/* 3 bytes padding */
in32_t f2; // 4 bytes
};
Memory Corruption - Pragma pack
That’s cool, butttttttttttttttttt
⏣ JNA needs to allocate and set memory in the same manner the compiled code behaves.
⏣ Mismatching in this setting might and probably will cause structure fields to be written beyond the bounds of
its allocated memory.
⏣ This would result in vary nesty heap-corruptions, the kind that’ll send you searching the Glibc’s source code.
Memory Corruption - Pragma pack - Solution
JNA Provides us with the means of setting the alignment type.
⏣ You can set it on a per Structure basis :
public class SampleStruct extends Structure {
public SampleStruct(){
setAlignType(ALIGN_NONE);
}
}
⏣ Or globally (on library load):
public class SampleLib {
static {
Native.register(NativeLibrary.getInstance(SAMPLE,
Map.of(Library.OPTION_STRUCTURE_ALIGNMENT,Structure.ALIGN_NONE)));
}
}
Getting proffesionall help
JNA Github repository is actively maintained
⏣ https://github.com/java-native-access/jna
⏣ Browsing through the readme, you can see it’s in active use by several major projects
The google group is also alive & kicking
⏣ https://groups.google.com/forum/#!forum/jna-users
⏣ A good place to search for answers or just rant and let some steam out.
THE BOTTOM LINE
Decisions Decisions
Is JNA a good choice?
AND
Pros
JNA is a mature & stable solution.
⏣ After all, JNA is a just proxy/bridge between Java & Native code.
⏣ If you’re doing everything right, no special treatment/race-condition handling is required.
Fully supported on Linux, OSX and Windows
⏣ That includes the nuisance of dealin with Windows __stdcall convention and special types.
When keeping your eco-system pure JVM is of high importance, JNA is probably your go-to
solution.
⏣ It really narrows down the list of things you can’t easily achieve with a JVM programming language
Cons
JNA requires the developer to be precise and accurate
⏣ C/C++ programming has the same requirement.
⏣ Java, as high level programming language, has gotten us used to getting by with a much lower degree of
accuracy.
JNA requires the developer for the very least to be able to read and understand C/C++
code.
⏣ You need to understand the pointer types populated/passed on and their scope.
⏣ And what about thread-safety ? Documentation provided with native code is sometimes lacking.
⏣ Going JNA without the source code and/or a native reference implementation might be considred suicide.
My 2 cents
Build upon JNA when no other standard pure-JVM solution seem viable for a requirement.
⏣ The lack of existence of, or unmaintained/poor-quality code.
Don’t doubt JNA - doubt your own implementation instead.
⏣ JNA is harder until you get the hang of it - there’s no hiding from that truth.
RTFM, seriously
⏣ https://github.com/java-native-access/jna/blob/master/www/FrequentlyAskedQuestions.md
⏣ http://java-native-access.github.io/jna/4.2.1/overview-summary.html#overview.description
Use Case #1
Needed to convert live raw (wav) audio feed to AAC-encoded segments.
⏣ Segments need to be sequentually concatable.
⏣ The program need to to know epoch start timestamp of each segment (real world clock).
⏣ The JVM can read audio and determine timestamp of read data at any given point, but cannot encode raw
audio to AAC.
⏣ FFmpeg can segment audio-only stream, but cannot imprint epoch timestamps.
Use Case #1
Solution - Created a bridge between libfdk-aac and the JVM using JNA
⏣ Project repository https://github.com/sheinbergon/jna-aac-encoder
⏣ Raw (wav) audio is read from a capture interface in real-time using the Java (old but working) AudioSystem.
⏣ Each x bytes read are encoded to AAC (I’m passing byte buffers back and forth).
⏣ Timetstamp is recorded prior to reading the next chunk of bytes.
Use Case #2
Needed to find a microsecond-fast way to send messages from a C program to a
Java(Kotlin) program, on Windows.
⏣ Socket I/O or Memory mapping was too “low-level” in C.
⏣ Brokerless MQs seemed like a viable solution.
⏣ ZeroMQ/Czmq are very standard solutions, but windows builds are a complete mess.
⏣ JeroMQ might have been considered a good pure JVM alternative, but it wasn’t fast enough.
⏣ Nanomsg is a viable alternative (faster than ZeroMQ - 150-400 us per message), but the Java client requires
MSVC and ANT...Ya’ak
Use Case #2
Solution - Load the Nanomsg DLL from the JVM via JNA
⏣ Nanomsg DLL compiled using CLion/MinGW under Windows within 5 minutes.
⏣ Just took the DLL and made it loadable to the JVM application
⏣ Followed the samples here http://nanomsg.org/gettingstarted/pipeline.html and mapped minimal required
methods for consumer code
⏣ Implemented a consumer server thread in Java with JNA.
⏣ This took around 2.5 hours to wind up with a fully working sample.
Questions
Common, you know you want to
Thank You!

More Related Content

What's hot

Introduction to memcached
Introduction to memcachedIntroduction to memcached
Introduction to memcachedJurriaan Persyn
 
Etsy Activity Feeds Architecture
Etsy Activity Feeds ArchitectureEtsy Activity Feeds Architecture
Etsy Activity Feeds ArchitectureDan McKinley
 
Ozone and HDFS's Evolution
Ozone and HDFS's EvolutionOzone and HDFS's Evolution
Ozone and HDFS's EvolutionDataWorks Summit
 
Inheritance in c++ part1
Inheritance in c++ part1Inheritance in c++ part1
Inheritance in c++ part1Mirza Hussain
 
Introduction to java
Introduction to java Introduction to java
Introduction to java Sandeep Rawat
 
c# usage,applications and advantages
c# usage,applications and advantages c# usage,applications and advantages
c# usage,applications and advantages mohamed drahem
 
Handling inline assembly in Clang and LLVM
Handling inline assembly in Clang and LLVMHandling inline assembly in Clang and LLVM
Handling inline assembly in Clang and LLVMMin-Yih Hsu
 
Memory management in Linux
Memory management in LinuxMemory management in Linux
Memory management in LinuxRaghu Udiyar
 
Strongly Consistent Global Indexes for Apache Phoenix
Strongly Consistent Global Indexes for Apache PhoenixStrongly Consistent Global Indexes for Apache Phoenix
Strongly Consistent Global Indexes for Apache PhoenixYugabyteDB
 
Linux kernel architecture
Linux kernel architectureLinux kernel architecture
Linux kernel architectureSHAJANA BASHEER
 
Reactive Relational Database Connectivity
Reactive Relational Database ConnectivityReactive Relational Database Connectivity
Reactive Relational Database ConnectivityVMware Tanzu
 
Secrets of Performance Tuning Java on Kubernetes
Secrets of Performance Tuning Java on KubernetesSecrets of Performance Tuning Java on Kubernetes
Secrets of Performance Tuning Java on KubernetesBruno Borges
 
Java Spring framework, Dependency Injection, DI, IoC, Inversion of Control
Java Spring framework, Dependency Injection, DI, IoC, Inversion of ControlJava Spring framework, Dependency Injection, DI, IoC, Inversion of Control
Java Spring framework, Dependency Injection, DI, IoC, Inversion of ControlArjun Thakur
 
为啥别读HotSpot VM的源码(2012-03-03)
为啥别读HotSpot VM的源码(2012-03-03)为啥别读HotSpot VM的源码(2012-03-03)
为啥别读HotSpot VM的源码(2012-03-03)Kris Mok
 
Nakov - .NET Framework Overview - English
Nakov - .NET Framework Overview - EnglishNakov - .NET Framework Overview - English
Nakov - .NET Framework Overview - EnglishSvetlin Nakov
 

What's hot (20)

Introduction to memcached
Introduction to memcachedIntroduction to memcached
Introduction to memcached
 
C#ppt
C#pptC#ppt
C#ppt
 
Etsy Activity Feeds Architecture
Etsy Activity Feeds ArchitectureEtsy Activity Feeds Architecture
Etsy Activity Feeds Architecture
 
HBase Storage Internals
HBase Storage InternalsHBase Storage Internals
HBase Storage Internals
 
Ozone and HDFS's Evolution
Ozone and HDFS's EvolutionOzone and HDFS's Evolution
Ozone and HDFS's Evolution
 
Inheritance in c++ part1
Inheritance in c++ part1Inheritance in c++ part1
Inheritance in c++ part1
 
Mainframe
MainframeMainframe
Mainframe
 
Introduction to java
Introduction to java Introduction to java
Introduction to java
 
c# usage,applications and advantages
c# usage,applications and advantages c# usage,applications and advantages
c# usage,applications and advantages
 
Handling inline assembly in Clang and LLVM
Handling inline assembly in Clang and LLVMHandling inline assembly in Clang and LLVM
Handling inline assembly in Clang and LLVM
 
Memory management in Linux
Memory management in LinuxMemory management in Linux
Memory management in Linux
 
Strongly Consistent Global Indexes for Apache Phoenix
Strongly Consistent Global Indexes for Apache PhoenixStrongly Consistent Global Indexes for Apache Phoenix
Strongly Consistent Global Indexes for Apache Phoenix
 
Linux kernel architecture
Linux kernel architectureLinux kernel architecture
Linux kernel architecture
 
Linux Internals - Interview essentials - 1.0
Linux Internals - Interview essentials - 1.0Linux Internals - Interview essentials - 1.0
Linux Internals - Interview essentials - 1.0
 
Reactive Relational Database Connectivity
Reactive Relational Database ConnectivityReactive Relational Database Connectivity
Reactive Relational Database Connectivity
 
Secrets of Performance Tuning Java on Kubernetes
Secrets of Performance Tuning Java on KubernetesSecrets of Performance Tuning Java on Kubernetes
Secrets of Performance Tuning Java on Kubernetes
 
Java Spring framework, Dependency Injection, DI, IoC, Inversion of Control
Java Spring framework, Dependency Injection, DI, IoC, Inversion of ControlJava Spring framework, Dependency Injection, DI, IoC, Inversion of Control
Java Spring framework, Dependency Injection, DI, IoC, Inversion of Control
 
为啥别读HotSpot VM的源码(2012-03-03)
为啥别读HotSpot VM的源码(2012-03-03)为啥别读HotSpot VM的源码(2012-03-03)
为啥别读HotSpot VM的源码(2012-03-03)
 
Linux Internals - Part II
Linux Internals - Part IILinux Internals - Part II
Linux Internals - Part II
 
Nakov - .NET Framework Overview - English
Nakov - .NET Framework Overview - EnglishNakov - .NET Framework Overview - English
Nakov - .NET Framework Overview - English
 

Similar to JNA - Let's C what it's worth

NDK Primer (AnDevCon Boston 2014)
NDK Primer (AnDevCon Boston 2014)NDK Primer (AnDevCon Boston 2014)
NDK Primer (AnDevCon Boston 2014)Ron Munitz
 
NDK Primer (Wearable DevCon 2014)
NDK Primer (Wearable DevCon 2014)NDK Primer (Wearable DevCon 2014)
NDK Primer (Wearable DevCon 2014)Ron Munitz
 
14.jun.2012
14.jun.201214.jun.2012
14.jun.2012Tech_MX
 
Cross Platform App Development with C++
Cross Platform App Development with C++Cross Platform App Development with C++
Cross Platform App Development with C++Joan Puig Sanz
 
Advance Android Application Development
Advance Android Application DevelopmentAdvance Android Application Development
Advance Android Application DevelopmentRamesh Prasad
 
College Project - Java Disassembler - Description
College Project - Java Disassembler - DescriptionCollege Project - Java Disassembler - Description
College Project - Java Disassembler - DescriptionGanesh Samarthyam
 
Using the Android Native Development Kit (NDK)
Using the Android Native Development Kit (NDK)Using the Android Native Development Kit (NDK)
Using the Android Native Development Kit (NDK)DroidConTLV
 
Introduction to the Android NDK
Introduction to the Android NDKIntroduction to the Android NDK
Introduction to the Android NDKBeMyApp
 
Using the Android Native Development Kit (NDK)
Using the Android Native Development Kit (NDK)Using the Android Native Development Kit (NDK)
Using the Android Native Development Kit (NDK)Xavier Hallade
 
Unmanaged Parallelization via P/Invoke
Unmanaged Parallelization via P/InvokeUnmanaged Parallelization via P/Invoke
Unmanaged Parallelization via P/InvokeDmitri Nesteruk
 
Objective-c for Java Developers
Objective-c for Java DevelopersObjective-c for Java Developers
Objective-c for Java DevelopersMuhammad Abdullah
 
What is Java Technology (An introduction with comparision of .net coding)
What is Java Technology (An introduction with comparision of .net coding)What is Java Technology (An introduction with comparision of .net coding)
What is Java Technology (An introduction with comparision of .net coding)Shaharyar khan
 

Similar to JNA - Let's C what it's worth (20)

NDK Primer (AnDevCon Boston 2014)
NDK Primer (AnDevCon Boston 2014)NDK Primer (AnDevCon Boston 2014)
NDK Primer (AnDevCon Boston 2014)
 
NDK Primer (Wearable DevCon 2014)
NDK Primer (Wearable DevCon 2014)NDK Primer (Wearable DevCon 2014)
NDK Primer (Wearable DevCon 2014)
 
14.jun.2012
14.jun.201214.jun.2012
14.jun.2012
 
Cross Platform App Development with C++
Cross Platform App Development with C++Cross Platform App Development with C++
Cross Platform App Development with C++
 
Advance Android Application Development
Advance Android Application DevelopmentAdvance Android Application Development
Advance Android Application Development
 
College Project - Java Disassembler - Description
College Project - Java Disassembler - DescriptionCollege Project - Java Disassembler - Description
College Project - Java Disassembler - Description
 
Using the Android Native Development Kit (NDK)
Using the Android Native Development Kit (NDK)Using the Android Native Development Kit (NDK)
Using the Android Native Development Kit (NDK)
 
basic_java.ppt
basic_java.pptbasic_java.ppt
basic_java.ppt
 
Introduction to the Android NDK
Introduction to the Android NDKIntroduction to the Android NDK
Introduction to the Android NDK
 
Using the Android Native Development Kit (NDK)
Using the Android Native Development Kit (NDK)Using the Android Native Development Kit (NDK)
Using the Android Native Development Kit (NDK)
 
Unmanaged Parallelization via P/Invoke
Unmanaged Parallelization via P/InvokeUnmanaged Parallelization via P/Invoke
Unmanaged Parallelization via P/Invoke
 
OOP-Chap2.docx
OOP-Chap2.docxOOP-Chap2.docx
OOP-Chap2.docx
 
Objective-c for Java Developers
Objective-c for Java DevelopersObjective-c for Java Developers
Objective-c for Java Developers
 
What is Java Technology (An introduction with comparision of .net coding)
What is Java Technology (An introduction with comparision of .net coding)What is Java Technology (An introduction with comparision of .net coding)
What is Java Technology (An introduction with comparision of .net coding)
 
Understanding the Dalvik Virtual Machine
Understanding the Dalvik Virtual MachineUnderstanding the Dalvik Virtual Machine
Understanding the Dalvik Virtual Machine
 
Java basic
Java basicJava basic
Java basic
 
Java introduction
Java introductionJava introduction
Java introduction
 
109842496 jni
109842496 jni109842496 jni
109842496 jni
 
Csharp_mahesh
Csharp_maheshCsharp_mahesh
Csharp_mahesh
 
1.Philosophy of .NET
1.Philosophy of .NET1.Philosophy of .NET
1.Philosophy of .NET
 

Recently uploaded

Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed DataAlluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed DataAlluxio, Inc.
 
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...soniya singh
 
Unit 1.1 Excite Part 1, class 9, cbse...
Unit 1.1 Excite Part 1, class 9, cbse...Unit 1.1 Excite Part 1, class 9, cbse...
Unit 1.1 Excite Part 1, class 9, cbse...aditisharan08
 
why an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdfwhy an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdfjoe51371421
 
Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...OnePlan Solutions
 
The Evolution of Karaoke From Analog to App.pdf
The Evolution of Karaoke From Analog to App.pdfThe Evolution of Karaoke From Analog to App.pdf
The Evolution of Karaoke From Analog to App.pdfPower Karaoke
 
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...Christina Lin
 
HR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.comHR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.comFatema Valibhai
 
What is Binary Language? Computer Number Systems
What is Binary Language?  Computer Number SystemsWhat is Binary Language?  Computer Number Systems
What is Binary Language? Computer Number SystemsJheuzeDellosa
 
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer DataAdobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer DataBradBedford3
 
DNT_Corporate presentation know about us
DNT_Corporate presentation know about usDNT_Corporate presentation know about us
DNT_Corporate presentation know about usDynamic Netsoft
 
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdf
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdfThe Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdf
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdfkalichargn70th171
 
Cloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStackCloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStackVICTOR MAESTRE RAMIREZ
 
Engage Usergroup 2024 - The Good The Bad_The Ugly
Engage Usergroup 2024 - The Good The Bad_The UglyEngage Usergroup 2024 - The Good The Bad_The Ugly
Engage Usergroup 2024 - The Good The Bad_The UglyFrank van der Linden
 
Hand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxHand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxbodapatigopi8531
 
Project Based Learning (A.I).pptx detail explanation
Project Based Learning (A.I).pptx detail explanationProject Based Learning (A.I).pptx detail explanation
Project Based Learning (A.I).pptx detail explanationkaushalgiri8080
 
Call Girls in Naraina Delhi 💯Call Us 🔝8264348440🔝
Call Girls in Naraina Delhi 💯Call Us 🔝8264348440🔝Call Girls in Naraina Delhi 💯Call Us 🔝8264348440🔝
Call Girls in Naraina Delhi 💯Call Us 🔝8264348440🔝soniya singh
 
Building Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop SlideBuilding Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop SlideChristina Lin
 
Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)OPEN KNOWLEDGE GmbH
 
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...kellynguyen01
 

Recently uploaded (20)

Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed DataAlluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
 
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
 
Unit 1.1 Excite Part 1, class 9, cbse...
Unit 1.1 Excite Part 1, class 9, cbse...Unit 1.1 Excite Part 1, class 9, cbse...
Unit 1.1 Excite Part 1, class 9, cbse...
 
why an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdfwhy an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdf
 
Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...
 
The Evolution of Karaoke From Analog to App.pdf
The Evolution of Karaoke From Analog to App.pdfThe Evolution of Karaoke From Analog to App.pdf
The Evolution of Karaoke From Analog to App.pdf
 
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
 
HR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.comHR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.com
 
What is Binary Language? Computer Number Systems
What is Binary Language?  Computer Number SystemsWhat is Binary Language?  Computer Number Systems
What is Binary Language? Computer Number Systems
 
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer DataAdobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
 
DNT_Corporate presentation know about us
DNT_Corporate presentation know about usDNT_Corporate presentation know about us
DNT_Corporate presentation know about us
 
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdf
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdfThe Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdf
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdf
 
Cloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStackCloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStack
 
Engage Usergroup 2024 - The Good The Bad_The Ugly
Engage Usergroup 2024 - The Good The Bad_The UglyEngage Usergroup 2024 - The Good The Bad_The Ugly
Engage Usergroup 2024 - The Good The Bad_The Ugly
 
Hand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxHand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptx
 
Project Based Learning (A.I).pptx detail explanation
Project Based Learning (A.I).pptx detail explanationProject Based Learning (A.I).pptx detail explanation
Project Based Learning (A.I).pptx detail explanation
 
Call Girls in Naraina Delhi 💯Call Us 🔝8264348440🔝
Call Girls in Naraina Delhi 💯Call Us 🔝8264348440🔝Call Girls in Naraina Delhi 💯Call Us 🔝8264348440🔝
Call Girls in Naraina Delhi 💯Call Us 🔝8264348440🔝
 
Building Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop SlideBuilding Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
 
Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)
 
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
 

JNA - Let's C what it's worth

  • 1. JNA - Let’s C what it’s worth Author: Idan Sheinberg
  • 2. whoami Freelance software developer and all things open-source Hobbyist software developer and all things open-source Not much time for other stuff...
  • 3. Let’s Start From The Begining JNA - Java Native Access - A means to access C/C++ code from the JVM. C/C++ (native) code is made accessible to the JNA by compiling it to a shared library. Yep, that means DLLs (Windows), SOs (Linux) or Dylibs(OSX). By using JNA, we are able to access native methods as if they were defined inside standard JVM jars.
  • 4. Why Should I Even Do That? Be a Java programmer. Not (want to) be a C/C++ programmer Need a functionality/API provided only by native code. Need to interface with specific hardware only accessible through native code. Be a masochist/adventurous (maybe the same).
  • 5. Don’t we already have JNI for that? JNI is the standard approach for interfacing with code written in C/C++ from the JVM. With JNI, the programmer must write C/C++ glue code to bridge the access to the actual native code you’re trying to interface with. That’s harder than your average Java related programming task, and also requires proficiency in at least the C. One might argue that a high-level language with a native interface should rid its practician from writing native code.
  • 6. A few more JNI facts Lots of the low level mechanics in the JVM are implemented using JNI. ⏣ FileOutputStream, SocketInputStream, etc... JNI allows for full, bi-directional interaction with JVM heap objects. ⏣ It was designed for the purpose of serving as an extension/foundation to the JVM. ⏣ That’s probably the main cause for its sluggish/clumsy design. JNA, on the other hand, was created to solely ease the access to native code. ⏣ As there’s no(t supposed to be any) C/C++ code to write, there’s no point in dealing with bi-directional access.
  • 7. How does JNA work? JNA uses libffi (Foriegn Function Interface Library) to invoke functions found in compiled C/C++ code from the JVM: ⏣ JNA uses a JNI (no kidding) library named libjnidispatch to glue libffi and handle type mapping & method proxying. ⏣ JNA (via libjnidispatch) also provides access to some useful low-level functions - malloc,memset,free, etc... ⏣ libffi supports many, many CPU architectures, operating systems and compilers, allowing JNA to function seamlessly regardless of the execution environment.
  • 8. Working with JNA A tutorial for the eager beaver.
  • 9. A quick start Given the following sample program: sample-lib.h: void printer(const char * input); sample-lib.c: #include <stdio.h> #include <sample-lib.h> void printer(const char * input) { printf("Input - %sn",input ); }
  • 10. A quick start A matching JNA endpoint class might look like this: SampleLib.java: package org.sheinbergon.jna.sample; import com.sun.jna.Native; public class SampleLib { private final static String SAMPLE = "sample-lib"; static { Native.register(SAMPLE); } public static native void printer(String input); }
  • 11. Working with structures Let’s define a C structure and a method to manipulate it: sample-structure-lib.h: typedef struct sample_structure { unsigned long int random; } SAMPLE_STRUCT; void random(const SAMPLE_STRUCTURE *); sample-structure-lib.c: #include <time.h> #include <stdlib.h> #include <sample-structure-lib.h> void random(const SAMPLE_STRUCT * strct) { srand(time(NULL)); strct->number = rand(); }
  • 12. Working with structures First, let’s define a matching Structure class in Java: SampleStruct.java: package org.sheinbergon.jna.sample; import com.sun.jna.Structure; public class SampleStruct extends Structure { public int number ; @Override protected List<String> getFieldOrder() { return List.of("number"); } }
  • 13. Working with structures Now, for the matching JNA endpoint class: SampleStructureLib.java: package org.sheinbergon.jna.sample; import com.sun.jna.Native; public class SampleStructureLib { private final static String SAMPLE_STRUCTURE = "sample-structure-lib"; static { Native.register(SAMPLE_STRUCTURE); } public static native void random(SampleStruct struct); }
  • 14. Making DLLs available to the JVM. The JVM uses the OS library search path to begin with. ⏣ $LD_LIBRARY_PATH and ldconfig on Linux ⏣ %PATH% and Windows/System Directory on Windows. The local resource classpath should also work. ⏣ Be sure to place library file inside a directory matching the proper CPU architecture - linux-x86-64 for linux 64 bit, win32-x86-64 for windows 64 bit, etc. ⏣ File suffix/prefix is determined per OS - Loading a DLL named java-jna implies searching for a file named libjava-jna.so on Linux and java-jna.dll on Windows. And of course, there’s jna.library.path or java.library.path system properties
  • 15. Type Mapping Working with pointers has never been more FUN!
  • 16. Where’s that manual Standard JNA Type Mapping - https://github.com/java-native-access/jna/blob/master/www/Mappings.md. Unfortunately, the list above is lacking big time. ⏣ C/C++ coding conventions encourage passing pointers/references to maintain an efficient and flexible stack. ⏣ As opposed to JAVA, native function declaration does not differentiate between pointers to allocated memory or garbage. ⏣ Following such rules & guidelines with JNA is a bit trickier, and a lot more confusing. For the very least, it’s going to take some getting used to.
  • 17. Pointer JNA provides us with the Pointer class. As its name implies, it proxies a native pointer. ⏣ Remember, A pointer does not necessarily refer to allocated memory! Common use cases for mapping types to a Pointer: ⏣ Pointers to types you don’t care about. ⏣ void * method/function argument/return type. ⏣ Instantiating a Structure sub-class.
  • 18. Pointer Native code allows you to read any type of data at any offset using a pointer. A JNA Pointer provide the same functionality: ⏣ Let’s say we have int * cp = ... ⏣ For Pointer jp , calling jp.getInt(0L) is the same as *cp (the int value itself). ⏣ jp.getInt(4L) is the same *(cp+1). Pointer offset in native code matches sizeof(type) You can also copy entire arrays from native memory. ⏣ jp.getIntArray(0L,5) copies 20 bytes (5 * int32) from the location pointed by p to the JVM heap. ⏣ Useful for reading structure fields populated inside the native code.
  • 19. ByReference char * is automatically translated to(and from) String. But what about other types, like int * for example ? ⏣ Are we dealing with a reference to pre-allocated or unallocated memory ? are we referencing an array or a single value? For single value references, JNA provides us with smart(ish) types like IntByReference ⏣ From the Java developer’s point-of-view, they are convenient containers that allow us to pass pointers to a JNA mapped method, and read the value set in a clearer way. What about void ** ? ⏣ PointerByReference is your friend.
  • 20. Memory A sub class of Pointer, representing allocated native memory ⏣ That’s memory allocated on the native heap, of course. ⏣ Allocation takes place on instance construction (i.e. new Memory(20L)). Memory is one of the most useful classes when working with JNA: ⏣ Use whenever you need to pre-allocate a buffer to be populated by the innards of native method. ⏣ That’s a pretty common use-case.
  • 22. CAVEATS Things are never that simple...
  • 23. Structures limitations Bit-Fields are not supported. ⏣ Aggregate all relevant bit fields onto the nearest type and parse possible bit values using bitwise operators. C: struct bitfields { unsigned short f1 : 7; unsigned short f2 : 9; }; JAVA: public class BitFields extends Structure { public short fshort; } Multi-Dimensional arrays are not supported. ⏣ Uni-dimensional arrays are just fine, so just be sure to encompass all of the dimensions size specifications - a field of type char buffer[3][4][5] in a C struct should be mapped as byte[] buffer = byte[60] in a matching JAVA Structure sub-class. Be accurate with your type selection/inclusion - Core dumps are no fun!
  • 24. Passing allocated memory Let’s say a native void function expects an allocated byte buffer (char buffer[size]). ⏣ Function declaration would be in the form of void func(char * buffer). One might guess that the matching JNA setup should look like this: ⏣ Define a native method static native void func(ByteByReference buffer). ⏣ Create a buffer byte [] buffer = new byte[size], put it inside a pointer new ByteByReference(byte[0]) and pass it on to the method.
  • 25. Passing allocated memory - Doing it Right JVM heap allocated arrays are NOT the same as native allocated memory: ⏣ Define a native method static native void func(Pointer buffer). ⏣ Create a Memory(size) buffer instance and pass it on. Memory is a sub-class of Pointer class, so no problem there. Structure sub-classes array fields are an exception, and are considered valid. ⏣ The JNA layer takes care of copying from/to native code and memory allocation C: struct yarrr { byte by[20]; }; JAVA: public class Yarrr extends Structure { public byte [] by = new byte[20]; }
  • 26. memory allocation Consider the following native code sample: // Struct definition typedef struct { char * f1; int f2; } STRUCT; // Some function void func(STRUCT * S){...} // Main code loop for(int i=0;; i++) { STRUCT s = { .f1 = "text", .f2 = i }; ... func(s); }
  • 27. memory allocation Matching JNA mapping might look like this: // Struct defintion public class Struct extends Structure { public static Struct of(String f1,int f2){Struct s = new Struct();s.f1=f1;s.f2=f2;return s;} public String f1; public int f2; ... } // JNA function mapping static native void func(Struct s); // Main code loop for(int i=0;; i++) { Struct s = Struct.of("text",i); ... func(s); }
  • 28. memory allocation - pressure In C, a local variable’s memory is allocated in the stack on declaration and gets deallocated once it goes out of scope: ⏣ Out of scope means end of block - loop iteration, function end, etc. ⏣ Local means every variable inside the bounds of a block aside from memory explicitly allocated. In the JVM, class instances are created inside the heap and would eventually get GC’d once they are no longer referenced. Eventually being the keyword - it’s not always fast-enough… ⏣ This behavior could lead to memory exhaustion, native memory contention, sluggishness, and ugly crashes.
  • 29. Memory allocation - pressure - Solution In order to simulate native C stack memory allocation, we could simply reuse structure instances instead of re-allocating them in each loop iteration. ⏣ Please don’t forget to “clear” the structure before reusing (“cheaper” than additional memory allocation). // Main code loop Struct s = new Struct(); for(int i=0;; int++) { s.clear(); s1.f1 = “text”; s1.f2 = i; ... func(s); }
  • 30. Weak-References Weak references refer to object instances that might be GC’d during contention, even though the instances themselves might still be in-use/referenced. ⏣ Say we have a method void callee(SomeObject obj){...} ⏣ Calling it with callee(new SomeObject()) will create a weak-reference to that SomeObject instance. Doing the same with JNA mapped structures are no different, of course. The consequences, however, are far more impactful: ⏣ Structure GC also frees native memory. That memory might still be currently accessed by native code. ⏣ In fact, sometimes structures allocated are not meant to be freed as part of the ongoing flow.
  • 31. Weak-References - Solution Make sure everything passed down through JNA proxied methods is strongly referenced. ⏣ Static fields or members of singletons/objects the only go out of scope as part of lifecycle management ⏣ This applies to Structure , Pointer , Callback , *ByReference subclasses/instances.
  • 32. Memory Pressure - Structure Synchronization When passing Structure sub-classes through JNA mapped methods, Object fields defined in the JVM need to be written to native memory and made available to the native code. ⏣ The same goes for fields being read after a JNA method call. The problem starts when you’re dealing with nested structure definition (consider structure array fields, re-instantiating on each read). This could cause heap memory exhaustion and slow down you’re overall application performance. ⏣ A Full GC might also be triggered, causing weak-reference (and other) issues to arise earlier.
  • 33. Memory Pressure - Structure Synchronization - Solution Luckily for us, we can choose what gets synced and what does not: ⏣ We can disable or enable read/write synchronization separately or both altogether. public class Sync extends Strucutre {public int f1;...} Sync s = new Sync(); s.setAutoWrite(false); // Disable only pre JNA method write sync s.setAutoSynch(true); // Enable both read and write sync; ⏣ For maximum efficiency, we can also synchronize specific fields manually. s.readField("f1"); // Post JNA method call Only read/write fields that are required to properly fulfill the code’s functionality.
  • 34. Memory Corruption - Pragma pack Native code compilers might pad structure fields, so they’ll match the default byte alignment of the target CPU architecture. ⏣ Given a structure that’s supposed to require 5 bytes: struct structure { char f1; // 1 bytes in32_t f2; // 4 bytes }; ⏣ Memory allocated for the structure might be “rounded” up to 8 bytes: struct structure { char f1; // 1 bytes /* 3 bytes padding */ in32_t f2; // 4 bytes };
  • 35. Memory Corruption - Pragma pack That’s cool, butttttttttttttttttt ⏣ JNA needs to allocate and set memory in the same manner the compiled code behaves. ⏣ Mismatching in this setting might and probably will cause structure fields to be written beyond the bounds of its allocated memory. ⏣ This would result in vary nesty heap-corruptions, the kind that’ll send you searching the Glibc’s source code.
  • 36. Memory Corruption - Pragma pack - Solution JNA Provides us with the means of setting the alignment type. ⏣ You can set it on a per Structure basis : public class SampleStruct extends Structure { public SampleStruct(){ setAlignType(ALIGN_NONE); } } ⏣ Or globally (on library load): public class SampleLib { static { Native.register(NativeLibrary.getInstance(SAMPLE, Map.of(Library.OPTION_STRUCTURE_ALIGNMENT,Structure.ALIGN_NONE))); } }
  • 37. Getting proffesionall help JNA Github repository is actively maintained ⏣ https://github.com/java-native-access/jna ⏣ Browsing through the readme, you can see it’s in active use by several major projects The google group is also alive & kicking ⏣ https://groups.google.com/forum/#!forum/jna-users ⏣ A good place to search for answers or just rant and let some steam out.
  • 39. Is JNA a good choice? AND
  • 40. Pros JNA is a mature & stable solution. ⏣ After all, JNA is a just proxy/bridge between Java & Native code. ⏣ If you’re doing everything right, no special treatment/race-condition handling is required. Fully supported on Linux, OSX and Windows ⏣ That includes the nuisance of dealin with Windows __stdcall convention and special types. When keeping your eco-system pure JVM is of high importance, JNA is probably your go-to solution. ⏣ It really narrows down the list of things you can’t easily achieve with a JVM programming language
  • 41. Cons JNA requires the developer to be precise and accurate ⏣ C/C++ programming has the same requirement. ⏣ Java, as high level programming language, has gotten us used to getting by with a much lower degree of accuracy. JNA requires the developer for the very least to be able to read and understand C/C++ code. ⏣ You need to understand the pointer types populated/passed on and their scope. ⏣ And what about thread-safety ? Documentation provided with native code is sometimes lacking. ⏣ Going JNA without the source code and/or a native reference implementation might be considred suicide.
  • 42. My 2 cents Build upon JNA when no other standard pure-JVM solution seem viable for a requirement. ⏣ The lack of existence of, or unmaintained/poor-quality code. Don’t doubt JNA - doubt your own implementation instead. ⏣ JNA is harder until you get the hang of it - there’s no hiding from that truth. RTFM, seriously ⏣ https://github.com/java-native-access/jna/blob/master/www/FrequentlyAskedQuestions.md ⏣ http://java-native-access.github.io/jna/4.2.1/overview-summary.html#overview.description
  • 43. Use Case #1 Needed to convert live raw (wav) audio feed to AAC-encoded segments. ⏣ Segments need to be sequentually concatable. ⏣ The program need to to know epoch start timestamp of each segment (real world clock). ⏣ The JVM can read audio and determine timestamp of read data at any given point, but cannot encode raw audio to AAC. ⏣ FFmpeg can segment audio-only stream, but cannot imprint epoch timestamps.
  • 44. Use Case #1 Solution - Created a bridge between libfdk-aac and the JVM using JNA ⏣ Project repository https://github.com/sheinbergon/jna-aac-encoder ⏣ Raw (wav) audio is read from a capture interface in real-time using the Java (old but working) AudioSystem. ⏣ Each x bytes read are encoded to AAC (I’m passing byte buffers back and forth). ⏣ Timetstamp is recorded prior to reading the next chunk of bytes.
  • 45. Use Case #2 Needed to find a microsecond-fast way to send messages from a C program to a Java(Kotlin) program, on Windows. ⏣ Socket I/O or Memory mapping was too “low-level” in C. ⏣ Brokerless MQs seemed like a viable solution. ⏣ ZeroMQ/Czmq are very standard solutions, but windows builds are a complete mess. ⏣ JeroMQ might have been considered a good pure JVM alternative, but it wasn’t fast enough. ⏣ Nanomsg is a viable alternative (faster than ZeroMQ - 150-400 us per message), but the Java client requires MSVC and ANT...Ya’ak
  • 46. Use Case #2 Solution - Load the Nanomsg DLL from the JVM via JNA ⏣ Nanomsg DLL compiled using CLion/MinGW under Windows within 5 minutes. ⏣ Just took the DLL and made it loadable to the JVM application ⏣ Followed the samples here http://nanomsg.org/gettingstarted/pipeline.html and mapped minimal required methods for consumer code ⏣ Implemented a consumer server thread in Java with JNA. ⏣ This took around 2.5 hours to wind up with a fully working sample.