In Ubuntu 12.04 habe ich jdk7 von Sun/Oracle installiert. Bei locate jni.h
werden mehrere Standorte gedruckt
/usr/lib/jvm/Java-6-openjdk-AMD64/include/jni.h
/usr/lib/jvm/jdk1.7.0_07/include/jni.h
...
In der von JDK generierten Header-Datei gibt es include <jni.h>
und derzeit beschwert es sich
fatal error: jni.h: No such file or directory.
In meiner Makefile
gibt es keine Angabe von Orten, an denen jni.h
ist. Und ich frage nach Möglichkeit, bestimmte Systemparameter so zu konfigurieren, dass der Pfad von jni.h
(etwa /usr/lib/jvm/jdk1.7.0_07/include/jni.h
) beim Kompilieren bekannt wird.
Sie müssen Ihrem Compiler mitteilen, wo sich das Include-Verzeichnis befindet. Etwas wie das:
gcc -I/usr/lib/jvm/jdk1.7.0_07/include
Aber es hängt von Ihrem Makefile ab.
Es benötigt sowohl jni.h
- als auch jni_md.h
-Dateien. Versuchen Sie dies
gcc -I/usr/lib/jvm/jdk1.7.0_07/include \
-I/usr/lib/jvm/jdk1.7.0_07/include/linux filename.c
Dies umfasst sowohl die umfangreichen JNI-Dateien als auch die für Linux erforderlichen
Das Installieren des OpenJDK Development Kit (JDK) sollte das Problem beheben.
Sudo apt-get install openjdk-X-jdk
Dadurch sollten Sie ohne Probleme kompilieren können.
Verwenden Sie den folgenden Code:
make -I/usr/lib/jvm/jdk*/include
dabei ist jdk * der Verzeichnisname Ihrer jdk-Installation (z. B. jdk1.7.0).
Und es würde keine systemweite Lösung geben, da sich der Verzeichnisname bei verschiedenen Builds von JDK, die heruntergeladen und installiert werden, unterscheidet. Wenn Sie eine automatisierte Lösung wünschen, fügen Sie alle Befehle in einem einzigen Skript zusammen und führen Sie das besagte Skript in Terminal aus.
Durch das Festlegen von Java_INCLUDE_DIR auf die Position, an der sich jni.h befindet, sollte das Problem gelöst sein (die Einstellung von CPPFLAGS hat bei mir nicht funktioniert)
Angenommen, es ist/usr/lib64/Java/include;
export Java_INCLUDE_DIR=/usr/lib64/Java/include
Normalerweise definiere ich meine Java_HOME-Variable wie folgt:
export Java_HOME=/usr/lib/jvm/Java/
Darin befinden sich die notwendigen Include-Dateien. Manchmal füge ich meiner .barshrc das Folgende hinzu, wenn ich viele Dinge kompiliere, die es brauchen.
Keine der veröffentlichten Lösungen funktionierte für mich.
Ich musste vi
in mein Makefile aufnehmen und den Pfad so bearbeiten, dass der Pfad zum include
-Ordner und zum OS-Subsystem (in meinem Fall -I/usr/lib/jvm/Java-8-openjdk-AMD64/include/linux
) korrekt war. Dadurch konnte ich make
und make install
ohne Probleme ausführen.
Für mich war es einfach eine Frage der Sicherheit, die JDK-Installation einzuschließen (ich hatte nur die JRE). Meine R CMD javareconf
Ausgabe sah folgendermaßen aus:
Java interpreter : /usr/lib/jvm/Java-8-openjdk-AMD64/jre/bin/Java
Java version : 1.8.0_191
Java home path : /usr/lib/jvm/Java-8-openjdk-AMD64/jre
Java compiler : not present
Java headers gen.:
Java archive tool:
trying to compile and link a JNI program
detected JNI cpp flags :
detected JNI linker flags : -L$(Java_HOME)/lib/AMD64/server -ljvm
gcc -std=gnu99 -I/usr/share/R/include -DNDEBUG -fpic -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 -g -c conftest.c -o conftest.o
conftest.c:1:17: fatal error: jni.h: No such file or directory
compilation terminated.
/usr/lib/R/etc/Makeconf:159: recipe for target 'conftest.o' failed
make: *** [conftest.o] Error 1
Unable to compile a JNI program
Java_HOME : /usr/lib/jvm/Java-8-openjdk-AMD64/jre
Java library path:
JNI cpp flags :
JNI linker flags :
Updating Java configuration in /usr/lib/R
Done.
Und tatsächlich gab es keine include
Datei in meinem $Java_HOME
. Sehr einfaches Mittel:
Sudo apt-get install openjdk-8-jre openjdk-8-jdk
(Beachten Sie, dass dies speziell für die Installation von openJDK
und nicht von Oracle vorgesehen ist.)
Danach ist alles gut:
Java interpreter : /usr/lib/jvm/Java-8-openjdk-AMD64/jre/bin/Java
Java version : 1.8.0_191
Java home path : /usr/lib/jvm/Java-8-openjdk-AMD64/jre
Java compiler : /usr/lib/jvm/Java-8-openjdk-AMD64/jre/../bin/javac
Java headers gen.: /usr/lib/jvm/Java-8-openjdk-AMD64/jre/../bin/javah
Java archive tool: /usr/lib/jvm/Java-8-openjdk-AMD64/jre/../bin/jar
trying to compile and link a JNI program
detected JNI cpp flags : -I$(Java_HOME)/../include -I$(Java_HOME)/../include/linux
detected JNI linker flags : -L$(Java_HOME)/lib/AMD64/server -ljvm
gcc -std=gnu99 -I/usr/share/R/include -DNDEBUG -I/usr/lib/jvm/Java-8-openjdk-AMD64/jre/../include -I/usr/lib/jvm/Java-8-openjdk-AMD64/jre/../include/linux -fpic -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 -g -c conftest.c -o conftest.o
g++ -shared -L/usr/lib/R/lib -Wl,-Bsymbolic-functions -Wl,-z,relro -o conftest.so conftest.o -L/usr/lib/jvm/Java-8-openjdk-AMD64/jre/lib/AMD64/server -ljvm -L/usr/lib/R/lib -lR
Java_HOME : /usr/lib/jvm/Java-8-openjdk-AMD64/jre
Java library path: $(Java_HOME)/lib/AMD64/server
JNI cpp flags : -I$(Java_HOME)/../include -I$(Java_HOME)/../include/linux
JNI linker flags : -L$(Java_HOME)/lib/AMD64/server -ljvm
Updating Java configuration in /usr/lib/R
Done.
Ich weiß nicht, ob dies in diesem Fall zutrifft, aber manchmal wurde die Datei aus unbekannten Gründen gelöscht. Wenn Sie sie erneut in den entsprechenden Ordner kopieren, sollte das Problem behoben sein.
Die obigen Antworten geben Ihnen eine fest codierte Pfadlösung. Dies ist auf so vielen Ebenen (Änderung der Java-Version, Änderung des Betriebssystems usw.) schlecht.
Eine sauberere Lösung besteht darin, Folgendes hinzuzufügen:
Java_HOME = $(Shell dirname $$(readlink -f $$(which Java))|sed 's^jre/bin^^')
in der Nähe des oberen Randes Ihres Makefiles, dann fügen Sie hinzu:
-I$(Java_HOME)/include
Zu Ihren Include-Flags.
Ich poste dies, weil ich auf dasselbe Problem gestoßen bin und zu viel Zeit damit verbracht habe, nach falschen Antworten zu suchen (ich erstelle eine App auf mehreren Plattformen, sodass die Build-Umgebung transportabel sein muss).