Newsgroup: it.comp.java
Titolo: JNI... non funziona! Dove sbaglio?

Volevo fare una prova di integrazione tra codice C e java, ma non riesco 
proprio a risolvere.
Ho fatto così:
1) Ho scritto il file helloNative.java che segue:
///////////////////////////////////////////////////////
class helloNative
  {
   static
    {
 
System.setProperty("java.library.path",System.getProperty("java.library.path")+":/home/marco/Scrivania/C/prova");
     System.loadLibrary ( "helloNative" ) ;
    }
   private native void print();
   public static void main (String[]args)
    {new helloNative().print();}
  }
///////////////////////////////////////////////////////
2) ho creato il file helloNative.c che segue
///////////////////////////////////////////////////////
#include <jni.h>
#include <stdio.h>
#include "helloNative.h"
JNIEXPORT void JNICALL
Java_helloNative_print(JNIEnv * env,jobject obj)
  {
   printf("Hello, Native!\n");
   return;
  }
///////////////////////////////////////////////////////
3) ho digitato /usr/java/jdk1.6.0/bin/javac helloNative.java, creando il 
file helloNative.class
4) ho digitato /usr/java/jdk1.6.0/bin/javah helloNative, creando il file 
  helloNative.h
5) ho digitato gcc -I /usr/java/jdk1.6.0/include -I 
/usr/java/jdk1.6.0/include/linux -c helloNative.c -o helloNative.so per 
compilare il programma in C, creando l'eseguibile helloNative.so 
[sistema operativo Linux Fedora 8, con tutti gli aggiornamenti)
6) ho digitato /usr/java/jdk1.6.0/bin/java helloNative per eseguire il 
programma java. Ma il risultato è sempre lo stesso:
Exception in thread "main" java.lang.UnsatisfiedLinkError: no 
helloNative in java.library.path
         at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1682)
         at java.lang.Runtime.loadLibrary0(Runtime.java:823)
         at java.lang.System.loadLibrary(System.java:1030)
         at helloNative.<clinit>(helloNative.java:8)
Ho provato in tutti i modi, ma non riesco ad evitare l'errore di cui 
sopra. Dove ho sbagliato?


rinomina il .so in "libhelloNative.so"

 rinomina il .so in "libhelloNative.so"
Non cambia nulla. Nč lasciando il sorgente java cosě com'č, nč 
modificando System.loadLibrary("helloNative"); in 
System.loadLibrary("libhelloNative");

 System.loadLibrary("libhelloNative");
se in java metti:
System.loadLibrary("helloNative");
il file .so *deve* essere:
libhelloNative.so
lib all'inizio e .so alla fine.
in windows invece sara':
helloNative.dll
mantenendo sempre lo stesso codice java.

 lib all'inizio e .so alla fine.
Ti ringrazio per la risposta, ma non cambia nulla. Ho provato a lasciare 
System.loadLibrary("helloNative"); nel file java e a rinominare in 
libhelloNative.so la libreria, ma l'eccezione in esecuzione persiste.
Ho provato anche con 
System.load("/home/marco/Scrivania/C/prova/libhelloNative.so"); al posto 
di System.loadlibrary, e l'errore che otengo ora è
Exception in thread "main" java.lang.UnsatisfiedLinkError: 
/home/marco/Scrivania/C/prova/libhelloNative.so: 
/home/marco/Scrivania/C/prova/libhelloNative.so: only ET_DYN and ET_EXEC 
can be loaded
         at java.lang.ClassLoader$NativeLibrary.load(Native Method)
         at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1751)
         at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1647)
         at java.lang.Runtime.load0(Runtime.java:770)
         at java.lang.System.load(System.java:1005)
         at helloNative.<clinit>(helloNative.java:9)
Mi viene il dubbio che non siano errate le impostazioni del comando gcc 
(è il mio primo tentativo al riguardo, avevo sempre lavorato con java 
finora).
Aggiornamento: ho modificato il comando gcc in
gcc -I /usr/java/jdk1.6.0/include -I /usr/java/jdk1.6.0/include/linux 
-shared libhelloNative.c -o libhelloNative.so
(Ho tolto -c, e ho aggiunto -shared)
Ora funziona con 
System.load("/home/marco/Scrivania/C/prova/libhelloNative.so"), ma non 
con System.loadLibrary("helloNative")

 con System.loadLibrary("helloNative")
prova a settare la java.library.path cioe':
/usr/java/jdk1.6.0/bin/java -Djava.library.path=. helloNative
se la libreria sta nella stessa directory da cui lanci il comando

 ... /home/marco/Scrivania/C/prova"); 
Scusa la domanda Off Topic.
Quale distribuzione / Desktop Enviroment usi?
-- 
Andrea Francia
http://www.andreafrancia.it/

 se la libreria sta nella stessa directory da cui lanci il comando
sotto linux va fatto ma lui gia' lo fa da codice.... forse non funziona.
in effetti io passo sempre -Deccc. a linea di comando.

Hybris ha scritto:

Però è strano... con -Djava.library.path=. funziona, mentre il 
System.setProperty sembra che non produca effetti...

 System.setProperty sembra che non produca effetti...
Non sono sicuro, magari dico una baggianata.
La java.library.path è una variabile che viene letta in partenza come
il classpath,  se la cambi in corso non ha alcun effetto.
Comunque io  lo settata sempre tramite l'argomento -D

Rock ha scritto:

Probabilmente è come dici tu..
Ora ho un altro problema, anche se diventa un po' OT...
Vorrei compilare una dll per Windows, ma non riesco a farlo. Ho provato 
a installare vari compilatori (Borland, gcc), ma ottengo sempre degli 
errori in compilazione (per esempio, errori nel jni.h di java!!!).
Vorrei consigli su una strada funzionante. Con Borland che comandi, e 
con che opzioni, dovrei digitare? Oppure, con gcc, quali pacchetti 
dovrei avere, esattamente? E come faccio a fare generare una dll, 
impedendo al compilatore di arrabbiarsi per la mancanza del main? O 
cos'altro mi consigliate - rigorosamente free???
Sotto Linux ora funziona regolarmente, ma vorrei che andasse anche sotto 
Windows.