<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Paul Legato &#187; JNI</title>
	<atom:link href="http://www.paullegato.com/blog/tag/jni/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.paullegato.com</link>
	<description></description>
	<lastBuildDate>Tue, 06 Dec 2011 00:52:36 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>JNI, Leiningen, and the :native-path argument</title>
		<link>http://www.paullegato.com/blog/jni-leiningen-native-path/</link>
		<comments>http://www.paullegato.com/blog/jni-leiningen-native-path/#comments</comments>
		<pubDate>Fri, 05 Mar 2010 00:12:52 +0000</pubDate>
		<dc:creator>Paul Legato</dc:creator>
				<category><![CDATA[Tech]]></category>
		<category><![CDATA[clojure]]></category>
		<category><![CDATA[Incanter]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[JNI]]></category>
		<category><![CDATA[JVM]]></category>
		<category><![CDATA[leiningen]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[r]]></category>
		<category><![CDATA[statistics]]></category>

		<guid isPermaLink="false">http://www.paullegato.com/?p=119</guid>
		<description><![CDATA[How to load JNI native libraries via Leiningen's undocumented :native-path argument, for installation of Rincanter.]]></description>
			<content:encoded><![CDATA[<p><a target="_blank" href="http://github.com/jolby/rincanter" >Rincanter</a> allows one to access the <a target="_blank" href="http://www.r-project.org/" >R statistical programming language</a> from Clojure. Rincanter also integrates R with <a target="_blank" href="http://data-sorcery.org/" >Incanter</a> for charting and more stats. Rincanter is based on  <a target="_blank" href="http://www.rforge.net/rJava/index.html" >rJava</a>&#8216;s <a target="_blank" href="http://www.rforge.net/JRI/" >JRI R-from-Java bridge</a>. Getting this working required making a JNI library available to Clojure via an as-yet-undocumented Leiningen setting, <code>:native-path</code>.<span id="more-119"></span></p>
<h2>R-Java Bridge Motivation</h2>
<p>I have some statistical functions written in R which would be annoying to re-implement in Java or Clojure, mainly because they depend on R libraries that are already written and for which there are no readily apparent Java/Clojure equivalents (the augmented Dickey-Fuller test, if you&#8217;re interested.) So, naturally, I decided to look into embedding R into Java, somehow.</p>
<h2>Rincanter: R from Clojure</h2>
<p><a target="_blank" href="http://github.com/jolby/rincanter" >Rincanter</a> came up, and it looks perfect: not only does it embed R into the JVM (via <a target="_blank" href="http://www.rforge.net/rJava/index.html" >rJava</a>&#8216;s <a target="_blank" href="http://www.rforge.net/JRI/" >JRI</a> component), it provides a nice Clojure wrapper <em>and</em> it integrates it with <a target="_blank" href="http://data-sorcery.org/" >Incanter</a>, a Clojure-based statistics and charting package that I&#8217;ve been wanting to try.</p>
<h2>rJava and JRI: Low level bridge</h2>
<p>rJava is, incidentally, mainly intended for calling Java code from R, which is the opposite of what I want to do. It absorbed the JRI project, which allows one to call R from Java, into its source tree a while ago, but so far it appears to be a direct graft onto the source tree with little or no integration. Perfect, since I don&#8217;t need to use the Java-from-R stuff anyway. So I downloaded rJava and built only the JRI subdirectory.</p>
<p>Going by Rincanter&#8217;s installation instructions, I need two things from JRIL: a generic JAR for the system-independent Java parts and a platform-specific JNI, a Java Native Interface to the actual R implementation on the system. The build produced two important files (hidden in the <code>src/</code> subdirectory), <code>JRI.jar</code> and <code>libjri.jnilib</code>. (The name of the latter will vary depending on your build platform; it will be a <code>.so</code> file on Linux, a <code>.dll</code> file on Windows, etc.) I stuck them in my Clojure project&#8217;s <code>lib/</code> subdirectory, restarted Leiningen, and went to the REPL to see whether everything worked.</p>
<p>Glancing through the examples that came with JRI, I decided to try a &#8220;<code>(.new org.rosuda.JRI.Rengine)</code>&#8220;. This failed spectacularly, and crashed the JVM with a complaint about being unable to locate the JNI library.</p>
<h2>Loading JNI libraries with Leiningen</h2>
<p><a target="_blank" href="http://blog.pingoured.fr/index.php?post/2009/03/23/Getting-rJava/JRI-to-work%3A" >Further investigation</a> showed that just placing the JNI library on the classpath doesn&#8217;t work. JNI libraries apparently have a separate classpath-like construct stored in the JVM system property <code>java.library.path</code>. Mine was set to <code>".:/Library/Java/Extensions:/System/Library/Java/Extensions:/usr/lib/java"</code> by default.</p>
<p>I don&#8217;t want to install the JRI library system-wide. The default inclusion of <code>"."</code> was curious, but I also don&#8217;t want to start dumping files into my project&#8217;s root directory. What I need is a way to set this system property. Of course, I could be crude and just hammer it in in one of my Clojure source files, but, as it&#8217;s analogous to setting up the classpath, it seems rather like something that Leiningen should be doing as part of its config-file based JVM startup procedure.</p>
<p>Good news: <a target="_blank" href="http://groups.google.com/group/leiningen/browse_thread/thread/3c0f3c28851dec37" >Leiningen got the ability to set java.library.path</a> last December. It&#8217;s still not documented in the README, but the code was merged into the official release. Searching through the codebase, I found that the <code>defproject</code> argument <code>:native-path</code> sets up JNI&#8217;s <code>java.library.path</code>. I made myself a <code>jni/</code> subdirectory, added <code>:native-path "jni"</code> to my <code>project.clj</code>, and it worked.</p>
<p>It did clobber the default <code>java.library.path</code> property completely, replacing it with my &#8220;jni/&#8221; argument rather than appending it. That&#8217;s OK for my case, since I&#8217;m not using any systemwide JNI libraries, but it is something to be aware of in case you are.</p>
<p><em>Update:</em> Rincanter apparently does its own management of <code>java.library.path</code> and JNI library loading. The docs ask for the .jnilib to be installed into Rincanter itself. It&#8217;s still good to know about the Leiningen way. </p>
<img src="http://www.paullegato.com/?ak_action=api_record_view&id=119&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://www.paullegato.com/blog/jni-leiningen-native-path/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

