Running JNI based code inside XCode
Sometimes you want to run JNI based code inside XCode – e.g. in case when your C/Objective-C/C++ code is based on some Java library.
It’s both simple and little bit confusing to get JNI running in XCode – you have to make sure to set few things before proceeding.
1. Getting source code
In this article I will use one of mine recipes from JNI Cookbook. Note that source code can be found here: GitHub.
> mkdir -p ~/workspace > cd ~/workspace > git clone https://github.com/mkowsiak/jnicookbook
2. Creating new project inside XCode
Start XCode and create new project macOS -> Command Line Tool. Once there, make sure to remove main.m file and replace it with $HOME/workspace/jnicookbook/recipeNo065/c/recipeNo065_main.m. You should have something like this.
![](http://www.owsiak.org/wp-content/uploads/2019/12/XCode_step_1.png)
3. Adding custom user variable
Make sure to switch to Project -> Build Settings so you can add new, user-defined, variable. I will use JAVA_HOME. It should point to location where your Java is installed. You can get this location by calling java_home
> /usr/libexec/java_home -v 11.0.4 /Library/Java/JavaVirtualMachines/jdk-11.0.4.jdk/Contents/Home
![](http://www.owsiak.org/wp-content/uploads/2019/12/XCode_step_2.png)
4. Setting up Search Paths
You need to set following search paths: Header Search Path, Library Search Path, and Runpath Search Path. Inside Header Search Path section make sure to add: $(JAVA_HOME)/include/darwin and $(JAVA_HOME)/include. Like this
![](http://www.owsiak.org/wp-content/uploads/2019/12/XCode_step_3.png)
Inside Library Search Path make sure to set location of libjvm.dylib ($(JAVA_HOME)/lib/server). You can set it following way
![](http://www.owsiak.org/wp-content/uploads/2019/12/XCode_step_4.png)
Last thing to set here is Runpath Search Path. Make sure to add $(JAVA_HOME)/lib/server there as well
![](http://www.owsiak.org/wp-content/uploads/2019/12/XCode_step_5.png)
5. Make sure your code is linked with libjvm.dylib
Last thing we have to do (in order to compile the code) is to pass -ljvm to the linker
![](http://www.owsiak.org/wp-content/uploads/2019/12/XCode_step_6.png)
6. Running the code
Note that JVM uses SIGSEGV to throw exceptions. Make sure to set breakpoint early in your code and ignore SIGSEGV
(lldb) process handle --pass true --stop false --notify true SIGSEGV
![](http://www.owsiak.org/wp-content/uploads/2019/12/XCode_step_7.png)
7. Continue debugging session
After process handle --pass true --stop false --notify true SIGSEGV is executed inside lldb you can continue with the debugger session.
![](http://www.owsiak.org/wp-content/uploads/2019/12/XCode_step_8.png)