The JNI (Java Native Interface) is a way to link a Java program, running in the JVM (Java Virtual Machine) with a native program. This can have many uses, one of which is the ability to utilize platform-optimized code in performance critical components of an application. SWT uses this to access platform dependent GUI libraries in a platform independent way. This interface allows a user of SWT to write an application in a standardized, Java-based API, while the resulting product will have the Look and Feel of a native app. Because of this usage, SWT can be conceptually divided into two different sets of code; a standardized, developer-facing Java API, and the native code that makes it work. The Java code is fairly straight forward to work with. Once you have your environment set up for your platform, most bugs can be investigated using the regular eclipse debugging tools. However, working with the native code is a little less straight forward. I found it hard to find guides that contained all the procedures in one location, and instead had to combine information from multiple sources. My goal is to create a step-by-step list of SWT JNI testing procedures for one platform (fedora 20 x86_64). My hope is that readers can then use this as a basis and extrapolate to other platforms as needed.
When I need to modify an element of the JNI code, I follow the following procedures:
- Modify the code using your favourite editor for C code and save the file from there.
- Run Eclipse->Project->Clean in order to re-build the files located in eclipse.platform.swt/bundles/org.eclipse.swt/bin/library (note: if these files are not updated after running this command and you are inside that folder in a terminal, cd out of that directory and try again).
- Run GTK_VERSION=3.0 ./build.sh on the build.sh file created in the last step in order to build with GTK3 support. You will likely have to modify the file permissions to be able to execute it. If you are missing any dependencies, you will need to install the development libraries associated with those dependencies. For example, if you are missing the GTK3 libraries, the fedora package is “gtk3-devel”. You must specify the GTK3 flag in order to do any Wayland work since Wayland support is not possible below GTK3. If you get a missing “jni.h” error you will need to set your JAVA_HOME environment variable to the location of your Java installation. My Java installation is located at /usr/java/jdk1.7.0_51
- Copy the created *.so files to your eclipse.platform.swt.binaries/bundles/org.eclipse.swt.[platform] folder where platform in my case is “linux.x86_64”
- Finally, run the application again from eclipse.
Also, if you are testing with an SWT application in executable .jar form outside of eclipse, the binaries are linked at runtime and the default will likely not be the files you just created. If you set your LD_LIBRARY_PATH environment variable to point to the eclipse.platform.swt.binaries… folder for your platform, you can then test against the new binaries without needing to do additional work in eclipse. Pro tip: This would be a great time to set up a bash/make script to do most of this work for you, especially for setting the environment variables each time. Information regarding SWT requirements for new JNI code can be found in the project’s FAQ page. Most of the time there will already be a similar function to the one you are adding support for, and the process then is mostly a copy/paste adventure.