OK, I've gotten it working on my computer, and it turns out to be a
slightly complicated problem.

What is happening is that the vtk java files and your clojure code are
using different classloaders (clojure uses its own classloader).

System/loadLibrary is kind of crippled in that it always loads the
library into the ClassLoader of the _invoking class's_ classLoader. I
was hoping it would use the Thread's context classloader, but it does
not.

There isn't any straightforward way to load a library using a
particular classloader either, so you have 2 options.

1) Make a java class that exposes a "loadLibrary" method. This java
class will be in the same classLoader as VTK and as a result,
loadLibrary calls from there will be visible to VTK.

public class Loader {

   public static void loadLibrary(String lib) {
        // Hack to load a library outside of Clojure's classloader
        System.loadLibrary(lib);
   }

}

2) Expose the package-private "Runtime/loadLibrary0" method and call it.

; This function is in clojure-contrib, reproduced here for convenience
(defn wall-hack-method
  "Calls a private or protected method.
   params is a vector of class which correspond to the arguments to the method
   obj is nil for static methods, the instance object otherwise
   the method name is given as a symbol or a keyword (something Named)"
  [class-name method-name params obj & args]
  (-> class-name (.getDeclaredMethod (name method-name) (into-array
Class params))
    (doto (.setAccessible true))
    (.invoke obj (into-array Object args))))

(defn load-lib [class lib]
    "Loads a native library in the same classLoader as \"class\" was
loaded in. \"lib\" is a string with the OS-appropriate name of the
library. For instance, to load libvtk.so on Linux, lib should be
\"vtk\""
    (wall-hack-method java.lang.Runtime "loadLibrary0" [Class String]
(Runtime/getRuntime) class lib))

; Load vtkCommonJava library in the same classLoader as vtkConeSource
(load-lib vtkConeSource "vtkCommonJava")

--------

I actually think clojure should probably add a method to its RT class
that does option 1 above, that way there's a straightforward way to
load native libraries in the correct classloader.

--Aaron


On Tue, Jun 21, 2011 at 4:10 PM, Antonio Recio <amdx6...@gmail.com> wrote:
> All the vtk libraries that I need are in /usr/local/lib/vtk-5.9/ and are
> executable.
> Java and c++ examples work fine.
>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with your
> first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Reply via email to