InfoQ

News

JNA brings native code to JRuby

Posted by Werner Schuster on Sep 05, 2007 11:00 PM

Community
Java,
Ruby
Topics
JRuby,
Programming
Tags
JRuby
One of JRuby's problems might soon get a solution: POSIX support integration and native extension support. POSIX stands for Portable Operating System Interface, and is a group of standards. Among other things, it provides APIs for filesystem access or networking. This allows for tighter OS integration, or at least as tight as the POSIX integration of the OS.

Until now, supporting POSIX calls was quite difficult with JRuby. Using equivalent Java APIs is one way to go, but even if  a Java equivalent of the functionality exists, it might not have the right semantics. And if the Java platform lacks the functionality, there remain only workarounds like launching command line programs to do the tasks.

Charles Nutter of the JRuby team reports the native code and POSIX on his blog:
I know, I know. It's got native code in it, and that's bad. It's using JNI, and that's bad. But damn, for the life of me I couldn't see enough negatives to using Java Native Access that would outweigh the incredible positives. For example, the new POSIX interface I just committed:

import com.sun.jna.Library;
public interface POSIX extends Library {
   public int chmod(String filename, int mode);
   public int chown(String filename, int owner, int group);
}
The (not so) secret ingredient here is the Java Native Access (JNA) library, not to be confused with Java's JNI. While JNI provides access to native C code, it requires extra effort and glue code, such as JNI header definitions that need to be compiled, to access it.

For the given example, this code using JNA is all that's needed to load and access the library:
import com.sun.jna.Native
POSIX posix = (POSIX)Native.loadLibrary("c", POSIX.class);
This loads the standard C library, and gives access to chmod (for changing file access permissions) and chown (changing the owner of a file) functions. Of course, this approach is not limited to these two functions. Adding further functions to the POSIX interface from the code sample would allow access to ever more functions of C stdlib. After all, Native.loadLibrary simply tries to map the names from the Java interface methods to C functions in the library and make them accessible.

JNA still uses JNI under the covers to access libffi which does all the magic. Using JNI brings along problems, for instance it's possible to run afoul of security managers that might not allow it or get into  trouble with JEE containers.
Obviously, whenever native libraries are shipped, they need to fit the platform. The currently available JNA release ships with libraries compiled for Win32, Linux 32 and 64 bit x86 versions, Solaris SPARC and x86, FreeBSD, and Darwin (MacOS X) for PPC and x86, which covers quite a lot of the available spectrum.

Easy access to native libraries from JRuby is useful, but JNA opens another possibility: support for Ruby native extensions. These are shared libraries that are loaded in a Ruby process and can access the internals of the Ruby interpreter. Native extensions are widely used. For instance, the popular rcov tool, used to determine the test coverage of a piece of code, makes use of the Ruby API to see which code is actually executed in a test run.

Support for this is not as easy as the examples above, as it requires a full implementation of the Ruby C Language API that extensions use to interact with the Ruby runtime. This is a two way affair: native code can call this API, but the Ruby runtime also invokes callbacks for certain events.  For more details on native extensions, see the Extending Ruby chapter of the online version of Programming Ruby.

Is the lack of POSIX functionality in JRuby a problem for you? What native extensions do you miss in JRuby?

2 comments

Reply

JNI required by JNA? by Chris Morris Posted Sep 6, 2007 3:13 PM
Re: JNI required by JNA? by Werner Schuster Posted Sep 6, 2007 5:34 PM
  1. Back to top

    JNI required by JNA?

    Sep 6, 2007 3:13 PM by Chris Morris

    Your article says, "JNA still uses JNI under the covers", but the jna home page says, "no JNI or native code is required". Are these statements compatible - does the JNA homepage mean only that JNI is not required in my code?

  2. Back to top

    Re: JNI required by JNA?

    Sep 6, 2007 5:34 PM by Werner Schuster

    JNA uses JNI to access libffi. I can't speak for the JNA guys, but I guess the "no JNI or native code required" means that, if you use JNA, you don't have to use JNI, instead you only use the JNA API calls and they do all the nasty JNI stuff in the background. One big problem with JNI is that if you want to access native code, you need to write a C library that needs to include JNI headers and compile and ship it with your product. This C library's functions area all you can call - nothing else. It's not possible to just load any old DLL or shared lib with plain JNI - JNA, on the other hand, can just take a DLL or shared lib, figure out what it provides and make these calls available. Also: look into the jna.jar (that you can download at the JNA site) - it ships with native libs for various platforms.

Exclusive Content

Intentional Software - Democratizing Software Creation

Business users doing programming? Simonyi and Kolk presents how Intentional Software offers a radical new software approach that separates business knowledge from software engineering knowledge.

Getting Started with Grails

Jason Rudolph discusses Java/Grails integration, Grails plugins, creating a Grails sample application, Grails app structure, data querying and persistence, validation, controllers and tag libraries.

Creating Product Owner Success

The Scrum Product Owner role is powerful, valuable and challenging to implement. It brings healthier relationships between customers and developers, and competitive advantage - if you do it right.

Book Excerpt and Interview: Effective Java, Second Edition

Effective Java, Second Edition by Joshua Bloch is an updated version of the classic first edition, which won a 2001 Jolt Award. InfoQ asked Bloch questions about the areas that the new edition covers.

Tapestry for Nonbelievers

A new article by I. Drobiazko and R. Zubairov introduces v. 5 of the Apache Tapestry component-oriented web framework. The tutorial shows how to create a component and covers IoC in Tapestry and Ajax.

Pete Lacey on REST and Web Services

In this interview, Burton Group consultant Pete Lacey talks to Stefan Tilkov about his disillusionment with SOAP, his opinion on REST, and addresses some of the perceived shortcomings REST vs. WS-*.

Business Natural Languages Development in Ruby

Jay Fields presents his concept of Business Natural Languages - a type of Domain Specific Languages geared towards being readable by domain experts.

Distributed Version Control Systems: A Not-So-Quick Guide Through

Adoption and interest for Distributed Version Control Systems is constantly rising. We will introduce the concept of DVCS and have a look at 3 actors in the area: git, Mercurial and Bazaar.