-
Notifications
You must be signed in to change notification settings - Fork 16
Installation instructions are missing a step #9
Comments
Good point. I just committed a fix in ee68022 |
I'm afraid this isn't working for me. Same error :( ** deleted a bit that was a brain failure on my part ** Oh, and you need a closing |
I tried
as well (ripped from clj-v8). That didn't work either. Checked the jar, and the files are definitely there. |
Fix the typo, thanks! I have no idea about the other problem sorry. It works for us in production on 64bit 12:04 :( |
I have a similar problem when deploying an uberjar. It looks to me like clj-v8 reads the binaries from the file system. (https://github.com/circleci/clj-v8/blob/master/clj-v8/src/v8/core.clj#L20-L23) Shouldn't these be read off of the class path? |
@pbiggar Does it also work for you in an uberjar? It seems like it is looking for the binaries in The comment on https://github.com/circleci/clj-v8/blob/master/clj-v8/src/v8/core.clj#L17-L19 seems to imply that it is a problem with version numbers that require the absolute path lookup. Can that be mended in some other way, like using only digits and dots for versions? |
It might not have anything to do with linux either, because just running an uberjar on the command line in OSX reveals similar problems:
Does clj-v8 support having the binaries in jars? Does jna? |
We're not using an uberjar in production, so I wouldn't be surprised if that's the problem.
Maybe, but we need to have a version which doesn't conflict with another possible version number, since libv8 will likely exist on the system. But I agree with your diagnosis of where the problem likely lies. |
It seems like this StackOverflow question has the solution, basically use Is this something you are interested in supporting? |
Yes please! |
Ok, I'll give it a go. |
This is what I have so far: (require '[clojure.java.io :as io])
(import '[java.io File FileOutputStream])
(defn load-library-from-class-path
[name extension]
(let [tmp (File/createTempFile name extension)
lib (io/resource (str "native/macosx/x86_64/" name extension))
in (.openStream lib)
out (FileOutputStream. tmp)]
(io/copy in out)
(.close out)
(.close in)
(System/load (.getAbsolutePath tmp))))
(load-library-from-class-path "libv8" ".dylib.clj-v8")
(load-library-from-class-path "libv8wrapper" ".dylib") Loading
when trying to load I'll continue beating at it, but if you have any ideas or tips, I'm all ears. :) |
I just realized this belongs in the clj-v8 repo. If you would like to move there, I'd be happy to open an issue. |
What is the function of libv8wrapper btw? Would it be a possible strategy to just use libv8 directly? Seems like that would simplify the loading quite a bit. |
The Java ZeroMQ wrapper has this working, by the way. It doesn't have the issue with one native lib depending on another, tho. https://github.com/zeromq/jzmq/blob/master/src/org/zeromq/EmbeddedLibraryTools.java |
Ok, moving along at a halting pace. :) If I avoid |
Sorry about the rubberducking. :) Would you mind giving this a go? (require '[clojure.java.io :as io])
(import '[java.io File FileOutputStream])
(defn- find-binary-path
[]
(let [os-name (System/getProperty "os.name")
os-arch (System/getProperty "os.arch")
id (case os-name
"Mac OS X" "macosx"
"Linux" "linux"
(throw (Exception. (str "Unsupported OS: " os-name))))
arch (case os-arch
"x86" "x86"
"x86_64" "x86_64"
"amd64" "x86_64" ;; need to compile own binaries for this?
(throw (Exception. (str "Unsupported archetype: " os-arch))))]
(str id "/" arch)))
(defn load-library-from-class-path
[name extension]
(let [tmp (File. (File. (System/getProperty "java.io.tmpdir")) (str name extension))
lib (io/resource (str "native/" (find-binary-path) "/" name extension))
in (.openStream lib)
out (FileOutputStream. tmp)]
(io/copy in out)
(.close out)
(.close in)
(System/load (.getAbsolutePath tmp))))
(try
(System/loadLibrary "v8wrapper")
(catch UnsatisfiedLinkError e
(load-library-from-class-path "libv8" ".dylib.clj-v8")
(load-library-from-class-path "libv8wrapper" ".dylib")))
(def LIBRARY (com.sun.jna.NativeLibrary/getInstance "v8wrapper")) |
I'd be happy to do it myself, but running
So I'm not sure how you're running your tests. |
Ironically, this is another of the issues I've reported: circleci/clj-v8#6 |
The code above only works on Mac atm, since I included |
Here's the code that finds .so instead of .dylib on linux. (defn- find-file-path-fragments
[]
(let [os-name (System/getProperty "os.name")
os-arch (System/getProperty "os.arch")]
(case [os-name os-arch]
["Mac OS X" "x86_64"] ["macosx/x86_64/" ".dylib"]
["Linux" "x86_64"] ["linux/x86_64/" ".so"]
["Linux" "amd64"] ["linux/x86_64/" ".so"]
["Linux" "x86"] ["linux/x86/" ".so"]
(throw (Exception. (str "Unsupported OS/archetype: " os-name " " os-arch))))))
(defn load-library-from-class-path
[name path-postfix]
(let [[binary-path binary-extension] (find-file-path-fragments)
file-name (str name binary-extension path-postfix)
tmp (File. (File. (System/getProperty "java.io.tmpdir")) file-name)
lib (io/resource (str "native/" binary-path file-name))
in (.openStream lib)
out (FileOutputStream. tmp)]
(io/copy in out)
(.close out)
(.close in)
(System/load (.getAbsolutePath tmp))))
(try
(System/loadLibrary "v8wrapper")
(catch UnsatisfiedLinkError e
(load-library-from-class-path "libv8" ".clj-v8")
(load-library-from-class-path "libv8wrapper" "")))
(def LIBRARY (com.sun.jna.NativeLibrary/getInstance "v8wrapper")) Right now it works spendidly on my Mac, using the native files from the Jar. On my Ubuntu it loads both libraries from the class path without error, but then JNA fails to load v8wrapper anyway. I'm kinda stuck at this point. Maybe a way forward is to replace JNA with a hand-made JNI interface. If you have any ideas, please do advice. :) |
Okay, so here's the deal:
So, to get this to work on both OSX and Linux, just add: (System/setProperty "jna.library.path" (System/getProperty "java.io.tmpdir")) right before (def LIBRARY (com.sun.jna.NativeLibrary/getInstance "v8wrapper")) It doesn't feel good, but that's what it takes. I guess this is a peculiarity of JNA, meaning you could probably avoid this sort of trickery by switching to plain JNI - but that is pretty painful as well. I'll see if I can get the clj-v8 tests to run using this. Otherwise I hope you can pick up the ball from here, @pbiggar - unless you feel this sort of mess is not worth having clj-v8 support living in an uberjar. |
I'm really not sure what to do here. AFAICT, this fixes some uberjar problems, but adds some other problems? Is my understanding correct? In general in these cases, I'll prefer to leave the patch unmerged and wait for a complete solution. I know that's a pain in the arse to solve your use case though :( |
The comments above chronicle my blundering steps towards the solution, but the pull request works in all cases that I know of. There might be regressions that I don't know about, since I am unable to run the tests (with or without the patch), and since there are no instructions on how to get the tests running. However, with this fix it now works both as a regular dependency, and bundled in an uberjar. |
Let me add that I've tested the pull request code on both OSX and Linux (Ubuntu), both with clj-v8 as a regular dependency and bundled in an uberjar. So as far as I can tell, it works. :) I'm just not able to run the tests. |
On ubuntu 12.04, just referencing the plugin and lib as in the readme gives you the following:
The text was updated successfully, but these errors were encountered: