1

I'm making a small app to test the integration of a native library (linux and windows) into java code with jna.

To do this I just call a single method into the library and check the result using simple junit tests.

The problem is that when the first test exits the library, it quits abruptly.

Here is the (simplified) code I use:

interface NativeLibraryInterface extends Library {
    static final String LIB_NAME_WINDOWS = "mylibW";
    static final String LIB_NAME_LINUX = "mylibL";

    NativeLibraryInterface INSTANCE = Native.load(Platform.isWindows() ? LIB_NAME_WINDOWS : LIB_NAME_LINUX, NativeLibraryInterface.class);

    int func1(int argc, String[] argv) throws LastErrorException;
}


public interface INativeLibraryApi {
    int myFunc1(String... args) throws LastErrorException;
}


public class NativeLibraryApi implements INativeLibraryApi {

    @Override
    public int myFunc1(String... args) throws LastErrorException {
        try {
            return NativeLibraryInterface.INSTANCE.func1(args.length, args);
        } catch (LastErrorException e) {
            System.out.println(e.getLocalizedMessage());
            return -1;
        } finally {
            System.out.println("EXIT");
        }
    }

}


final class NativeLibraryTest {
    static INativeLibraryApi nativeApi;

    @BeforeAll
    static void setup() {
        nativeApi = new NativeLibraryApi();
    }

    @Test
    void test1() throws Exception {
        int result = nativeApi.myFunc1("myArgA", "myArgB");
        assertEquals(0, result);
    }

    @Test
    void test2() throws Exception {
        int result = nativeApi.myFunc1("myArgC", "myArgD", "myArgE");
        assertEquals(0, result);
    }

}

When I run each test individually or run junit on the whole test class, func1 displays the expected data in the console, thus I know it has been executed properly. But it always quits just after exiting the call to the library.

"EXIT" is not displayed so I presume the execution stops in or after the call to NativeLibraryInterface.INSTANCE.func1(args.length, args);

What did I do wrong here ? Thanks for your help.

EDIT1:

I did a test where I replaced my native lib by a system lib (libc.so) and called the method double cosh(double) (I used this as an example: https://www.baeldung.com/java-jna-dynamic-libraries) and it worked flawlessly with junit, even calling the function a few times in the same test worked. So there is definitely a problem within my library but I don't see what it is.

EDIT2:

I guess I should add the C++ code for the library (simplified as well):

compile options: -g -ansi -pedantic -Wall -Wextra -m64 -O0

link options: -shared

myLibrary.hpp:

class MyLibrary {
public:
   MyLibrary ();
   ~MyLibrary ();

   int myFunc1 (
      int argc,
      char* argv[]
      );
};

extern "C" int func1 (int argc, char* argv[]);

myLibrary.cpp:

#include "myLibrary.hpp"

MyLibrary::MyLibrary ()
{
}


MyLibrary::~MyLibrary ()
{
}


int MyLibrary::myFunc1 (int argc, char* argv[])
{
    std::cout << "welcome" << std::endl;
    exit (EXIT_SUCCESS);
}


extern "C" int func1(int argc, char* argv[])
{
   MyLibrary library;

   return library.myFunc1(argc, argv);
}

1 Answer 1

0

I found the problem and the solution: don't use exit anywhere in the code of the library -> use return (but make sure you don't change the previous behavior, for example by returning a value that wouldn't lead to exiting the library during chained function calls).

Explanation: some functions used exit because originally the code of this lib was part of an executable. I just removed the main and added the extern "C" declarations to transform it to a library.

EDIT: this is not a valid solution when exit is called in void functions. I asked a specific question here: Transforming a C++ executable to a library: how to prevent ending the process when returning from a call (eg: return instead of exit)

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.