java.lang.UnsatisfiedLinkError

We are using List and Label for our java desktop application. During shipping ,we packed the necessary DLLS in the jar file and is extracted into the temperory folder of the system. But the System.loadLibrary() is throwing an Error, “java.lang.UnsatisfiedLinkError: no ListLabel19JNI_x64 in java.library.path” even if the property ‘java.library.path’ is set. It would be great if you could help me with this.

Regards,
Bibin Thomas

It seems the problem is that your are extracting into a temporary folder. Do you have also set the library path ‘java.library.path’ to that directory?

Does your application works fine on your LL developer machine?
If so, the problem is either the path (your application cannot find the specified file) OR the dependencies of LL are not complete. Look for that into the folder \Redistributable Files\x64\ and the file redist.txt.

yeah, I have set the property ‘java.library.path’ to the temporary folder.
It works fine on the developer machine. I have also tried loading dlls one after the other using absolute path, but then came the error “Can’t find dependent libraries”.
Is there any order, the dlls should be loaded?

If it works great on the developer machine the problem must be one of the following:

  • environment variable PATH is not set correctly to your temporary folder; additionally to your java.library.path
  • some dependencies of other LL moduls (like cxbr19.dll, cxll19.dll etc.) are missing. Please refer therefore the file redist.txt

I have them same issue, have find a solution?

Hi,

@Oliver_Hambrecht pointed into the right direction.

But one additional issue could also be in changing the path of the used combit Java package. Because of they have to be unchanged. Otherwise the JNI calls cannot find the exported native DLL functions. The reason is the package names are also involved in name resolving of the function names there. And if a function called from Java can not be found in the JNI DLL, then an UnsatisfiedLinkError could occur.

Could you please check the points from Oliver and the new one mentioned here?

Vielleicht sollte ich zu meinem Projekt nähere Informationen geben.
Ich habe ein Java Maven Projekt erstellt und erzeuge daraus eine JAR Datei.

Wenn ich diese JAR auf meinem PC ausführe wo LL schon installiert ist, funktioniert diese einwandfrei.
Sobald ich die JAR auf einem System ausführe wo noch kein LL installiert ist kommt folgender Fehler:
java.lang.UnsatisfiedLinkError ListLabel28JNI_x64.dll Can’t find.

Meine Ordner Struktur sieht wie folgt aus.

Der resources Ordner wurde als Resources Root gemarked.

Die Klassen LlExportPDF, LlPrint, LlSilentPrint werden von meiner Main Klasse aufgerufen abhängig auf welchen Button geklickt wird.

Die pom.xml sieht wie folgt aus:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>combit</groupId>
    <artifactId>ListLabel</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

    <build>
        <resources>
            <resource>
                <directory>src/main/resources</directory> <!-- Pfad zum lib-Ordner -->
                <includes>
                    <include>**/*</include>
                </includes>
            </resource>
        </resources>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <version>3.2.0</version>
                <configuration>
                    <!-- Setze den Namen der Hauptklasse -->
                    <archive>
                        <manifest>
                            <mainClass>combit.Main</mainClass> <!-- Hier den vollqualifizierten Namen deiner Hauptklasse einfügen -->
                        </manifest>
                    </archive>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

In der JAR sieht die Struktur wie folgt aus:

In lib sind auch alle notwendigen dlls. die vom Assisenten erstellt enthalten.

Die Info und Struktur kommt mir nicht ganz unbekannt vor… gut möglich, dass du bereits einen Support-Case dazu bei uns geöffnet hast zu diesem Thema?

Es ist wichtig, dass die Stuktur und der Pfad des combit Packages erhalten bleibt und nicht angepasst werden darf - das setzt JNI(Java Native Interface) einfach fest voraus, um die API-Aufrufe in der eigentlichen nativen DLL dann auch finden zu können.

Spannend wieso es auf der Maschine mit der LL-Installation klappt und ohne LL-Installation dann nicht mehr. Vermutlich werden aber auf der Maschine, bei der es funktioniert auch nicht die DLLs von LL aus dem Verzeichnis des JARs geladen, sondern aus dem Verzeichnis der Windows PATH-Variable unter Windows. Das sollte man aber mit Debwin4.exe sehen/erkennen können, da dort immer die Pfade der geladenen DLLs von LL angegeben werden.

Ja das ist korrekt ich habe, schon ein Support Case eröffnet. Nur bin ich leider nicht zu einem Erfolg gekommen.

Habe ich grundsätzlich von der Struktur und vorgehensweise alles richtig gemacht,
oder übersehe ich hier einen Punkt?

Ja es werden die dlls aus dem Installations-Verzeichniss geladen.

Dann ist die Ursache an dieser Stelle vermutlich diese, dass das Laden der Windows DLLs von List & Label (und die internen Abhängigkeiten) innerhalb des JAR Files über die VM von Java nicht umgesetzt werden kann und es greift hier dann ein Fallback auf die Windows PATH-Variable - daher werden auch nicht die DLLs aus dem eigenen src\main\resources\ im JAR geladen sondern die aus der LL-Installation. Aber das kann man sich nun zu nutze machen:

Die DLLs von List & Label müssen zuerst beim Startup der Anwendung/JARs extrahiert werden - sowohl das JNI wie auch die anderen DLLs von List & Label (siehe DIR src\main\resources\) in ein lokalen Anwendungsverzeichnis, dass dann aber auch noch zusätzlich zuvor in der PATH-Variabel von Windows eingetragen werden muss. Nur so kann der DLL-Lademechanismus von Windows eingehalten werden. Ein ähnliches Vorgehen wurde auch bereits hier auf Stackoverflow dokumentiert:

How to bundle a native library and a JNI library inside a JAR?