Skip to content
This repository has been archived by the owner on May 10, 2019. It is now read-only.

Determining linkage to libjvm is less than perfect, doesn't work on certain Linux distros #23

Open
treyzania opened this issue Nov 21, 2017 · 4 comments

Comments

@treyzania
Copy link
Contributor

This won't work properly my machine as I don't have $JAVA_HOME set and I'm not on macOS.

On my system (Xubuntu 16.04), libjvm.so lives in /usr/lib/jvm/java-8-openjdk-amd64/jre/lib/amd64/server. But there's a symlink to the java-8-openjdk-amd64 directory at /usr/lib/jvm/default-java/jre/lib/amd64/server. Different Linux distributions do things different ways so this might not work 100% the same outside of Debian-land.

My /etc/os-release is:

NAME="Ubuntu"
VERSION="16.04.3 LTS (Xenial Xerus)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 16.04.3 LTS"
VERSION_ID="16.04"
HOME_URL="http://www.ubuntu.com/"
SUPPORT_URL="http://help.ubuntu.com/"
BUG_REPORT_URL="http://bugs.launchpad.net/ubuntu/"
VERSION_CODENAME=xenial
UBUNTU_CODENAME=xenial

The problem is that not all Linux distributions have an OS release file like this, so it's actually really hard to figure out where libjvm.so is supposed to live. But worse-case scenario we can just search through /usr/lib/jvm until we find a directory with libjvm.so in it, as most people don't have enough JVMs installed to make that unreasonably slow.

I might make a pull request soon with a fix in build.rs that'll probably work on Debians, but I don't really have anything to test it with beyond cargo test.

@treyzania
Copy link
Contributor Author

treyzania commented Nov 21, 2017

Aaaand I'm just now realizing that I made an comment on an issue not unlike this a while back, except I was advocating for doing it dynamically at runtime using libloading. In retrospect it is a bit faster/easier to do it at link-time, and it's more unixy. This time I'll actually do something to fix it.

@kud1ing
Copy link
Owner

kud1ing commented Nov 21, 2017

I remember, you've commented in #12.
I am open to it, but i don't see clearly yet how to do cross-platform FFI in Rust at runtime.
Compile time fixes are very much appreciated.

@treyzania
Copy link
Contributor Author

Well I would design some kind of LibJvm struct that contains &Fns from symbols extracted from the library. But again, this is slower and more complicated than doing the "normal" linkages with extern "C". Really the only option here is to just be really clever on build.rs, as that's the closest thing that we have to a configure script with Cargo right now.

@treyzania
Copy link
Contributor Author

treyzania commented Nov 23, 2017

Made some progress on this in #29. Still need to run

export LD_PRELOAD=/usr/lib/jvm/default-java/jre/lib/amd64/server/libjvm.so

which is a huge pain in the ass.

There's a way to get around this by using the rpath ELF variable, but (1) I'm not sure that's available on Windows, and (2) there isn't a way to specify that in build.rs.

We could potentially use #[link_args = ...], but that's not recommended. Worst-case scenario, we use OpenJDK as a submodule and build a static library at build-time.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants