# JNI - UnsatisfiedLinkError



## tdc (26. Aug 2012)

Hi,
ich versuche gerade, ein einfaches HelloWorld-Programm mit JNI zu erstellen. Das Problem dabei ist, dass ich zurzeit beim Aufruf der nativen Mehtode folgende Fehlermeldung bekomme:

```
Exception in thread "main" java.lang.UnsatisfiedLinkError: jni.callnative()V
	at jni.callnative(Native Method)
	at jni.main(jni.java:5)
```

Mene Java-Klasse sieht so aus:

```
class jni {
  private native void callnative();

  public static void main(String[] args) {
    new jni().callnative();
  }

  static {
    System.loadLibrary("hello");
  }
}
```

und meine Hello.c-Klasse:

```
#include <jni.h>
#include <stdio.h>

JNIEXPORT void JNICALL Java_jni_callnative(JNIEnv *env,
                                                  jobject obj)
{
   printf("HelloWorld\n");
   return;
}
```

und schließlich noch die Befehle zum kompilieren:
(ich wollte es erstmal über die Konsole versuchen, da es mir zurzeit noch zu umständlich erscheint, es z.B. in Eclipse einzurichten)

```
javac jni.java
javah -jni jni
gcc -fPIC -shared  -I/usr/local/java/include -I/usr/local/java/include/genunix -Wl,--add-stdcall-alias hello.c -lc -o libnativelib.so
export LD_LIBRARY_PATH="/home/pfad/JNITest"
java jni
```

Wodurch wird nun die Fehlermeldung verursacht?


----------



## Marco13 (26. Aug 2012)

Schau mal in http://www.java-forum.org/allgemein...ava-lang-unsatisfiedlinkerror.html#post793645 , dieses "kill-at" scheint wichtig zu sein...


----------



## tdc (27. Aug 2012)

Wenn ich das Kompilier-Script von

```
gcc -fPIC -shared -I/usr/local/java/include -I/usr/local/java/include/genunix hello.c -lc -o libnativelib.so
```
zu

```
gcc -Wl,-kill-at -fPIC -shared -I/usr/local/java/include -I/usr/local/java/include/genunix hello.c -lc -o libnativelib.so
```
ändere, erhalte ich die Fehlermeldung:

```
/usr/bin/ld: unrecognized option '-kill-at'
/usr/bin/ld: use the --help option for usage information
collect2: ld gab 1 als Ende-Status zurück
```
und danach auch wieder die UnsatisfiedLinkError-Exception. Mein gcc-Compiler scheint -kill-at wohl nicht zu kennen. Habe ich vielleicht eine falsche Version?


----------



## nillehammer (27. Aug 2012)

Sieht danach aus, als wäre Deine lib nicht im Library-Path von Java. Dazu folgende Hinweise von Stack Overflow. Sogar mit einer lib, die auch _hello_ heißt: java - How should I load native libraries for JNI to avoid an UnsatisfiedLinkError? - Stack Overflow


----------



## tdc (27. Aug 2012)

Daran sollte es nicht liegen, denn wenn ich

```
export LD_LIBRARY_PATH="/home/pfad/JNITest"
```
weglasse, wodurch der Pfad richtig gesetzt werden sollte, erhalte ich:

```
Exception in thread "main" java.lang.UnsatisfiedLinkError: no hello in java.library.path
	at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1860)
	at java.lang.Runtime.loadLibrary0(Runtime.java:845)
	at java.lang.System.loadLibrary(System.java:1084)
	at jni.<clinit>(jni.java:9)
```
Das ist zwar auch eine UnsatisfiedLinkError-Exception, aber doch eine andere. 

Edit: Wenn ich es soweit richtig verstanden habe, liegt es bei mir angeblich daran, dass der C-Compiler irgendwelche zusätlichen Annotations produziert, die man mit -kill-at vermeiden kann. Bei mir existiert dieser Parameter aber in gcc scheinbar nicht.


----------



## freak_007 (27. Aug 2012)

Hey,
Die Kommandos sind nicht nötig. Laut diesem Tutorial reich alleine 
	
	
	
	





```
gcc -shared -I/usr/local/java/include  -I/usr/local/java/include/genunix hello.c -o libhello.so
```
 um die lib zu kompilieren.
Gruß,
Freak
[EDIT]Falls du ein OpenJDK verwendest reicht 
	
	
	
	





```
gcc -shared -I/usr/lib/jvm/<jdk auswählen>/include -I/usr/lib/jvm/<jdk auswählen>/include/linux hello.c -o libhello.so
```
[/EDIT]


----------



## Marco13 (27. Aug 2012)

Nebenbei, @nillehammer: Bei der ersten Fehlermeldung
Exception in thread "main" java.lang.UnsatisfiedLinkError: jni.callnative()V
hat der die lib offenbar schon gefunden. Er findet nur die Methode "jni.callnative" nicht. Wenn er die komplette Lib nicht finden würde, wäre es
Exception in thread "main" java.lang.UnsatisfiedLinkError: no hello in java.library.path


----------



## freak_007 (27. Aug 2012)

Marco13 hat gesagt.:


> Nebenbei, @nillehammer: Bei der ersten Fehlermeldung
> Exception in thread "main" java.lang.UnsatisfiedLinkError: jni.callnative()V
> hat der die lib offenbar schon gefunden. Er findet nur die Methode "jni.callnative" nicht. Wenn er die komplette Lib nicht finden würde, wäre es
> Exception in thread "main" java.lang.UnsatisfiedLinkError: no hello in java.library.path



Die Lösung ist die von javah erstellte Header einzubinden. Das hast du wohl vergessen.


----------



## Akeshihiro (27. Aug 2012)

Nur so als Anmerkung, weil das Problem hatte ich auch mal. Der Parameter 
	
	
	
	





```
-Wl,-kill-at
```
 ist nur bedingt "unwichtig". Im Normalfall ist er unwichtig, ja. Es gibt aber eine Ausnahme und diese nennt sich MinGW. Da muss der Parameter angegeben werden, sonst is nich. Warum weiß ich auch nicht, ist aber so.


----------



## tdc (27. Aug 2012)

Danke für die Hilfe!
Woran genau es lag kann ich auch nicht sagen, ein Fehler war jedenfalls die Benennung: lib**name**.so - dann funktioniert es.


----------

