2

My problem is as follows.

I need to create a library in Java. So far so good. Like any decent Java Libraries, it must be usable on any JVM.

But the difficulty here is that this library will contain a lot of native code.

I have some knowledge in JNI. I've tried creating a few native methods in Java in an Android application with Android Studio and with the Android NDK.

That's great I can do a lot of HelloWorld examples. But how can I export this as a library ?

My project needs external C++ Libraries. I would like to wrap these libraries and use them in a JNI wrapper wrapped inside a Java Library.

See the following schema : Java JNI API Schema

To make things even simpler, take a simple HelloWorld JNI API for example. Create a Java Desktop App (or anything else). Import the Helloworld JNI API (as jar), call String HelloWorldJNI_API.sayHello(String yourName) and print the result.

What is required here :

  1. The JNI API will obviously declare the sayHello() method as a native method ;
  2. The argument (String yourName) is sent to JNI ;
  3. The JNI code calls an internal awesome C++ so library that crunches the data and returns a "hello" + "yourName" (awesome, right ?)
  4. The JNI code returns the result as a jstring
  5. Finally, the Java API returns the result as a String and voila !

This simple example should show you what I am trying to do.

David Eisenstat
  • 64,237
  • 7
  • 60
  • 120
Mackovich
  • 3,319
  • 6
  • 35
  • 73
  • What part do you need help with? Google shows many examples; Oracles Java tutorial includes a fine step by step. – Ernest Friedman-Hill Aug 28 '15 at 12:35
  • I did find a few good tutorials (mostly for Android Studio and Netbeans) but they are platform-specifics, which makes sense but is limiting me. I need to be compatible with as many platforms as possible. Like a POJO '^^ – Mackovich Aug 28 '15 at 12:41
  • The Java part of a JNI Library is the same on every platform, but the native code part has to be compiled separately for every platform you support. If you look at how the "loadLibrary()" method works, you'll see that you only supply the root of the library name, and Java figures out what the file name should be on each individual platform. – Ernest Friedman-Hill Aug 28 '15 at 12:47
  • [JNA](http://github.com/twall/jna) abstracts the native bits so that you can focus on writing _only_ Java code. On most platforms, the jar file JNA profiles (`jna.jar`) knows how to unpack and load native libraries from the jar file itself. – technomage Aug 28 '15 at 16:12

1 Answers1

3

Well, your Library will contain both the .jar file with the java wrapper code as well as the native files (.so if you're on linux based, or .dll if you're on windows).

Here's where the fun begins :

Because native is compiled in processor assembly language you will have to compile the .so for all your supported target (eg for all android with native support since like forever): armv5, armv7, armv7s , arm64

Now, you will have to provide an archive with all the above.

This is the case where you want a stand alone library, without providing the code to the developer.

If you can provide the code,then you don't need to worry about different architectures.

MichaelCMS
  • 4,703
  • 2
  • 23
  • 29
  • Thank you ! I knew it would have been something like that. But where to find the tools and guides to accomplish this much ? I need a stand-alone library. The code will most certainly be obfuscated (meaning external developpers should not be able to have access). So how should I create this API ? Can I use Netbeans IDE and create a C/C++ Library ? How to export it as a so for all these plateforms ? – Mackovich Aug 28 '15 at 12:45
  • Suggestion for working allot with JNI : use a IDE for C++ to create the native part, then use a IDE for Java / Android to test the wrapper. Don't make the mistake of using Eclipse /Net Beans / InteliJ for native... you would be better off with notepad++ and copiler. 2nd thing you need to take into account : When working on desktop, debug using a C++ wrapper equivalent to the java wrapper to test on desktop . This will give you breakpoints and save you the incredible headaches of trying to debug native code when having a java entry point :). – MichaelCMS Aug 28 '15 at 12:50
  • wait, I can debug C++ code in notepad++ ? Why should I not use Netbeans for native ? I can debug native code as well. And finally, following your instructions, I would end up copying and pasting code between, say, notepad++ and Android Studio ? – Mackovich Aug 28 '15 at 12:56
  • From my experience I used Eclipse, and the problem is that the entry point is in java, so the debuggers must switch (there's a java debugger and a native debugger), and in Eclipse this was working very badly (more like it wasn't working). Notepad++ doesn't come with debuggers, I said that I preferred using Notepad++ rather then using Eclipse with C++ (auto-complete didn't work well, notepad++ is more lightweight,etc). You won't end up pasting code. You will have a C++ entry point when you are debugging on desktop and a Java entry point when you're testing on the real thing. – MichaelCMS Aug 28 '15 at 13:04
  • I dislike Eclipse. I just tried Netbeans C++ debugger (that uses gdb of course) and it works fine. Autocompletion to. Anyway, where should I write this C++ wrapper (the entry point) ? How come the debugger will be attached to the code ? Thanks for the help ! – Mackovich Aug 28 '15 at 13:06
  • Well, the C++ entry point was a suggestion in the scenario where you were using different IDEs for C++ and Java. If you want to go with Netbeans all the way, and It supports JNI correctly, then you don't need to worry about this anymore :). I personally didn't try netbeans. – MichaelCMS Aug 28 '15 at 13:14
  • Alright thank you. I might try Android Studio 1.3 which has a C++ debugging feature as stated here : http://stackoverflow.com/a/30514788/3535408 – Mackovich Aug 28 '15 at 13:23