"java.library.path", extrahieren, Platz, abhandeln,

Hallo

Ich hab hier n paar Native-Libs (dlls und so’s) die ich über
JNI lade:
System.loadLibrary("./mylib.so");

Wie das grundsätzlich funktioniert weiss ich - ich suche nur eine standardmäßige Herangehensweise - falls es die gibt. Oder 'n Best Practice.

Es geht ums verteilen : d.h. aus dem jar-file(denn hier liegen sie drin rum) extrahieren.

Ich kann das einmal über das Buildtool machen – in meinem Fall maven.
Oder programmatisch im JAVA-Code.

Eclipse hat früher die „xx-swt-xx.so“ einfach nach dem Start hierher kopiert: „<user_home>/.eclipse/xx-swt-xx.so“

Und bei den folgenden starts einfach geschaut obs schon drin liegt und wenn ja geladen.

Diesen Ansatz finde ich ehrlich gesagt nicht schlecht.

Aber:
Wie würdet Ihr das machen oder gibts dazu vielleicht ne STandart-Herangehensweise.

Danke und Grüße

Als Nutzer von links mit dlls geht meine Empfehlung ganz klar in Richtung: extrahieren sie so wie es Eclipse tut oder so ähnlich.

Wir haben libs im Einsatz die zu diesem Ansatz zum Glück gewechselt haben. Denn somit haben wir nicht mehr das Problem, wie wir zuverlässig die dlls überall an die richtigen Stellen bekommen.

Hmja, mit der Frage haben sich viele (mich eingeschlossen) lange rumgeärgert. Leider gibt es keine „eingebaute“ Möglichkeit, native Libs direkt aus JARs (d.h. als resource, aus einem InputStream) zu laden. Das hängt sicher damit zusammen, dass praktisch jede native Lib irgendwelche weiteren dependencies hat, und die Frage, die die dependencies einer nativen Lib aufgelöst werden nochmal eine weitere Schicht an Komplexität auf die Frage setzt, wo überhaut nach „der ersten“ nativen Lib gesucht wird.

(In diesem Zusammenhang, nebenbei: Ich glaube, System.loadLibrary("something.so") wird i.a. schon nicht funktionieren: loadLibrary erwartet nur den Namen, und kümmert sich intern darum, da lib davor und .so dahinter zu schreiben, und dann an verschiedenen Stellen nachzusehen - bei Windows im PATH, bei Linux im LD_LIBRARY_PATH, und was nicht alles…)

Spätestens, wenn die Lib in der Maven Central landen soll, muss man die Lib praktisch in eine JAR packen und zur Laufzeit extrahieren (und die Datei dann mit System.load (ohne ...Library) laden - nachdem man sich selbst um den ganzen Namens-Sche!ß gekümmert hat).

Es gibt eine Lib, die sich um das ganze kümmern kann: https://github.com/scijava/native-lib-loader Die habe ich selbst noch nicht verwendet, aber sie scheint im wesentlichen das zu machen, was ich für JOCL und JCuda dann selbst gebastelt habe. Letzteres liegt in https://github.com/gpu/JOCL/blob/master/src/main/java/org/jocl/LibUtils.java (und ich hatte schon überlegt, das mal als eigene Lib rauszuziehen…). Auch dort wird die Lib aus der JAR rausgeholt, ins „temp“-Verzeichnis geschrieben (falls sie da noch nicht liegt), und dann die Datei geladen.

(BTW: Die JCuda FAQ haben sich praktisch nur auf den UnsatisfiedLinkError bezogen, den man immer bekommt, wenn da was schiefgeht. Aber seit ich die natives in JARs packe, ist dieser Fehler praktisch weg…)

Danke – ziehe aus beiden Antworten das beste raus :wink: