jep
jep copied to clipboard
Java expects `libjep.dylib` rather than `jep.so` on OS X
What I did:
scala> System.loadLibrary("jep")
java.lang.UnsatisfiedLinkError: no jep in java.library.path
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1867)
at java.lang.Runtime.loadLibrary0(Runtime.java:870)
at java.lang.System.loadLibrary(System.java:1122)
... 32 elided
Why? Because:
scala> System.mapLibraryName("jep")
res16: String = libjep.dylib
What solved the issue for me:
ln -s /Library/Python/2.7/site-packages/jep/jep.so /Library/Python/2.7/site-packages/jep/libjep.dylib
- OS Platform, Distribution, and Version: OS X Sierra
- Python Distribution and Version: Pre-installed python 2.7
- Java Distribution and Version: Oracle Java "java version "1.8.0_152" Java(TM) SE Runtime Environment (build 1.8.0_152-b16) Java HotSpot(TM) 64-Bit Server VM (build 25.152-b16, mixed mode)"
We already do a link of jep.so to libjep.jnilib. Did you not get that link? It's part of the install
command with setup.py.
https://github.com/ninia/jep/blob/master/commands/link_util.py#L35
I did. The loading didn't work until I made a link to libjep.dylib.
Although System.mapLibraryName will return libjep.dylib
, ClassLoaderHelper.mapAlternativeName should be returning libjep.jnilib
which is why it works when we test on OS X.
Your environment seems very close to the travis-ci configuration that we use to test OS X, it is weird that you are getting different results. Can you run the jep tests(./setup.py test
) to see if it works in the default environment that it uses.
Another theory is that you may be using a custom class loader that implements the findLibrary method and only works with the default name. Can you see what ClassLoader is being used for the System.loadLibrary call. It is normally the ClassLoader of the calling class but I don't know what that would be at the scala interpreter.
Although the simple fix is to just add a link from libjep.dylib
, I don't think we should really need two links and I'm concerned if we change it we would break someone else who needs libjep.jnilib
. Unfortunately I can't find any definitive source claiming one way or the other is significantly better so I'm just trying to get more information on why this might be only impacting you right now.
This page from Apple says, "JNI libraries are named with the library name used in the System.loadLibrary() method of your Java code, prefixed by lib and suffixed with .jnilib. For example, System.loadLibrary("hello") loads the library named libhello.jnilib. Java HotSpot also recognizes .dylib as a valid JNI library format as of OS X v10.5."
I found a few random pages that claimed that JDK 7 needs .dylib:
- https://bugs.openjdk.java.net/browse/JDK-8127215
- https://github.com/mikiobraun/jblas/issues/19
I know .jnilib works on my machine at home that's on El Capitan with Oracle Java 8.
We need to revisit this now that we've dropped support for versions of Java before 1.7 and Oracle is providing the JRE instead of Apple. That said, a number of Jep users are probably switching to OpenJDK. We may want to wait until we drop support for 1.7 too. I don't have a reasonable way to test these different environments.
Jep 4.0 will drop support for JDK 7, so if we are going to change the link from .jnilib to .dylib, it should go in Jep 4.
Jep 4.0 has now been released, but I haven't made any changes for this. I'm not sure if this is still an issue or not.
