0

I have access to test.h and test.so files:

test.h

int insert_data(void *location_data, uint64_t device_id, uint64_t event_id,
                uint64_t motion_seq, uint64_t utc_time, uint32_t sensor_seq,
                uint32_t device_seq, uint32_t tick_mark, uint16_t ble,
                int movement, int path_id);

I am now writing JNA code to call the above method.

interface TestCLibrary extends Library {
    TestCLibrary INSTANCE = (TestCLibrary) Native.loadLibrary(“test”, TestCLibrary);

    int insert_data(Pointer test_data, long device_id, long event_id,
                    long motion_seq, long utc_time, int sensor_seq,
                    int device_seq, int tick_mark, short ble,
                    int movement, int path_id);
 }

public class JNATest {
    public static void main(String[] args) throws IOException{ 
        Native.setProtected(true); 
        int path_id = 1, movement = 1, tick_mark = 1, device_seq = 1;
        long utc_time = System.currentTimeMillis();
        int sensor_seq = 100;
        short ble = 25;
        long motion_seq = 22222299;
        long device_id = 111122333;
        long event_id = 44445555;  
    
        Pointer test_data = Pointer.NULL; 

        TestCLibrary.INSTANCE.insert_data(test_data, device_id, event_id, motion_seq, utc_time, sensor_seq, device_seq, tick_mark, ble, movement, path_id);
   }
}

While running the JNATest facing following exception at this code location:

TestCLibrary.INSTANCE.insert_data

Exception in thread "main" java.lang.Error: Invalid memory access at com.sun.jna.Native.invokeInt(Native Method) at com.sun.jna.Function.invoke(Function.java:419) at com.sun.jna.Function.invoke(Function.java:354) at com.sun.jna.Library$Handler.invoke(Library.java:244) at com.test.apps.$Proxy0.insert_data(Unknown Source) ....

How to avoid such error ? and how can I initialize a Pointer in JNA with default value ?

Community
  • 1
  • 1
kaniska Mandal
  • 189
  • 1
  • 12

2 Answers2

0

The error is happening because, I assume, the function writes the data into the memory pointed at by the pointer passed to it. You need to allocate memory to which the function can write. It cannot write to a NULL pointer.

What you should do depends on what the data is, how it is structured, and how you're using it.

If the data is just an array of integers or bytes, treat it as such (change array size accordingly):

int insert_data(int[] data, // ... etc.
// ...

int[] data = new int[4096];
insert_data(data, /* ... */

However, if you know that the data produced by the function is a struct or class, create a Java class for it. JNA will automagically "marshal" the data written by the native function into meaningful Java class instances:

Since the function accepts a pointer, you'll want to use Structure.ByReference:

int insert_data(Structure.ByReference data, // ...
cbr
  • 12,563
  • 3
  • 38
  • 63
0

The JVM Crash problem was solved after I performed following steps:

1) Native.setProtected(true);

2) Free up memory using Native library Native.free(Pointer.nativeValue(my_pointer_by_ref.getValue()));

3) running the program with following CLI options - -XX:-UseLoopPredicate -DLD_PRELOAD=/usr/lib/jvm/java-8-oracle/jre/lib/amd64/libjsig.so

kaniska Mandal
  • 189
  • 1
  • 12
  • You've only stopped the error from crashing the JVM, but you haven't fixed the error itself from occurring. Unless you've changed your code. – cbr Aug 08 '17 at 04:25
  • Actually now I am constructing the Pointer By Reference correctly and sending proper data to the actual C code (different from the test code that I mentioned here) . Its working fine in standalone mode when I run as => Djna.library.path=/opt/myJNA/ -DLD_PRELOAD=/usr/lib/jvm/java-8-oracle/jre/lib/amd64/libjsig.so -XX:-UseLoopPredicate -DLIBLOCATION_PATH=/opt/myJNA/ java -jar myJNA.jar – kaniska Mandal Aug 08 '17 at 20:11
  • Now I have a different problem , the same myJNA code fails when executed inside a storm bolt of a storm topology , and also fails when executed inside a Java Rest Controller ... with following error ... # A fatal error has been detected by the Java Runtime Environment: # # SIGSEGV ... # Problematic frame: # J 3028 C1 sun.net.www.ParseUtil.encodePath(Ljava/lang/String;Z)Ljava/lang/String; – kaniska Mandal Aug 08 '17 at 20:13