Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Java jni including and using native libraries inside jar #1579

Open
ampm78 opened this issue Aug 27, 2018 · 5 comments
Open

Java jni including and using native libraries inside jar #1579

ampm78 opened this issue Aug 27, 2018 · 5 comments
Labels
Distribution Issue Issue around distribution of binary packages Lang: Java

Comments

@ampm78
Copy link

ampm78 commented Aug 27, 2018

The released Java jni currently includes the MacOs native library as a resource inside the jar, but this is not actually used (it will still look for the native library in the "java.library.path"). This forces users to install the native library in their systems if they want to use the vw_jni.

I pushed some code to extract the lib from inside the jar and load it in my clone repo (ampm78@a957fa7) but this will only work at the moment for MacOs as that's the only native lib currently included in the jar.

Ideally the native libraries for at least the major platforms (MacOs, Linux, Windows?) should be built and included in the jar when releasing it, as other java libraries do (for example tensorflow).

@jackgerrits jackgerrits added Lang: Java Distribution Issue Issue around distribution of binary packages labels Nov 30, 2018
@JohnLangford
Copy link
Member

@jmorra @deaktator your thoughts here?

@deaktator
Copy link
Collaborator

@JohnLangford @jmorra @ampm78: I think this depends on the status of the build process. Previous to 8.4.1, we included the binaries for several OS variants in the jar. To the best of my recollection, the primary reason these were removed was related to two primary factors:

  1. the release process for Java was independent of the C lib release process.
  2. At the time, boost program options was dynamically linked in the C build.

These issues led to version conflicts with the boost program opts library and made it extremely hard to use because the library would be tied to the boost lib against which it was built. You’d have to simlink multiple boost libs and change them to make the JNI lib work.

Some of this detail is in the readme file is the java dir in the VW project.

If we can statically link the boost library in the C build and use a CI/CD service to release everything, then we can run the docker script we used previously to build the library for several OSs. I think that Travis has OS support which would allow us to build for major Linux distros and OS X. Not sure about windows support.

The OS detection code was a little “quirky” (if I remember correctly) and it’s often difficult to distinguish between some Linux distros.

@JohnLangford it’s been a while since I looked at the current status of the build process. Do you think we can build and release via Travis? And can we statically link against boost program opts?

@JohnLangford
Copy link
Member

I'm unsure, but several more people are becoming involved so it's possible we can engineer a more comprehensive release process.

@andrusha
Copy link

It would be convenient to only need to include vw as java dep and then it would take care of the rest. This would enable / ease the use of VW on services like Dataflow.

@eisber
Copy link
Collaborator

eisber commented Oct 28, 2019

@deaktator the static linking of the native components works on linux (https://github.com/VowpalWabbit/vowpal_wabbit/blob/master/java/CMakeLists.txt#L57) @jackgerrits has faith that it also works on Windows...

As for the build/release pipelines:

  1. Setup 3x Java (Linux, Mac, Windows) builds outputting statically linked artifacts (use yaml matrix feature to make it convenient).
  2. Setup a release pipeline that takes in the 3x artifacts, copies into target/* so that "mvn package" can pickup all the native dependencies.

The 2 Java APIs (old & spark) handle lib loading differently. Spark loads from jar (it actually extracts to temp folder), the old assumes its on the lib path. That should be unified.
https://github.com/scijava/native-lib-loader/ is a library I originally used, but it didn't support dependency (e.g. boost which was packaged into the jar too). Now since static linking works, we can switch back to the library which has a couple of heuristics to detect the OS.

https://github.com/scijava/native-lib-loader/blob/master/src/main/java/org/scijava/nativelib/NativeLibraryUtil.java#L49 contains the expected directory structure.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Distribution Issue Issue around distribution of binary packages Lang: Java
Projects
None yet
Development

No branches or pull requests

7 participants