90

In Ubuntu 12.04, I have jdk7 from sun/oracle installed. When locate jni.h, it prints multiple locations

/usr/lib/jvm/java-6-openjdk-amd64/include/jni.h
/usr/lib/jvm/jdk1.7.0_07/include/jni.h
...

In the header file generated by JDK, there is include <jni.h>, and currently it complains

fatal error: jni.h: No such file or directory.

In my Makefile, there is no specification of locations where jni.h is. And I am asking if possible to configure certain system parameter to make path of jni.h (say, /usr/lib/jvm/jdk1.7.0_07/include/jni.h) to be known when being compiled.

Richard
  • 14,642
  • 18
  • 56
  • 77
  • 4
    Add `-I/usr/lib/jvm/jdk1.7.0_07/include` to compiler flags. – hmjd Jan 25 '13 at 20:22
  • 1
    is there any system-wise configuration for path of jni.h, so that no need to specify compile option everytime it gets compiled. – Richard Jan 25 '13 at 20:24
  • 1
    Possible setting `JVM_HOME` environment variable and referring to it from the makefile (I _think_): `-I$JVM_HOME/include` – hmjd Jan 25 '13 at 20:26
  • The next stage after this question: http://stackoverflow.com/questions/6804253/jni-h-no-such-file-or-directory – Raedwald Dec 24 '14 at 15:38

11 Answers11

52

You have to tell your compiler where is the include directory. Something like this:

gcc -I/usr/lib/jvm/jdk1.7.0_07/include

But it depends on your makefile.

jdb
  • 4,419
  • 21
  • 21
  • Locate jni.h returns me nothing. I have java 1.7 installed on Ubuntu 13.04 machine. – w2lame Nov 14 '13 at 12:33
  • To generalize jdb's solution: first set an environment $JAVA_HOME to point to your desired jdk folder. Then make sure to include the path $JAVA_HOME/include in your include paths for the gcc call. – chinnychinchin Nov 19 '18 at 22:48
33

It needs both jni.h and jni_md.h files, Try this

gcc -I/usr/lib/jvm/jdk1.7.0_07/include \
  -I/usr/lib/jvm/jdk1.7.0_07/include/linux filename.c

This will include both the broad JNI files and the ones necessary for linux

pevik
  • 4,523
  • 3
  • 33
  • 44
yogesh singh
  • 605
  • 6
  • 9
  • Hey! I'm on mac and `gcc -I/Library/Java/JavaVirtualMachines/jdk1.8.0_73.jdk/Contents/Home/include/` gives me following error: `clang: error: no input files` – nimeshkiranverma Apr 20 '16 at 07:28
17

Installing the OpenJDK Development Kit (JDK) should fix your problem.

sudo apt-get install openjdk-X-jdk

This should make you able to compile without problems.

hgaronfolo
  • 331
  • 1
  • 3
  • 9
12

I usually define my JAVA_HOME variable like so:

export JAVA_HOME=/usr/lib/jvm/java/

Therein are the necessary include files. I sometimes add the below to my .barshrc when I compile a lot of things that need it.

Leo Ufimtsev
  • 6,240
  • 5
  • 40
  • 48
9

Use the following code:

make -I/usr/lib/jvm/jdk*/include

where jdk* is the directory name of your jdk installation (e.g. jdk1.7.0).

And there wouldn't be a system-wide solution since the directory name would be different with different builds of JDK downloaded and installed. If you desire an automated solution, please include all commands in a single script and run the said script in Terminal.

user2925073
  • 91
  • 1
  • 2
6

For me it was a simple matter of being sure to include the JDK installation (I'd only had the JRE). My R CMD javareconf output was looking like:

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.

And indeed there was no include file in my $JAVA_HOME. Very simple remedy:

sudo apt-get install openjdk-8-jre openjdk-8-jdk

(note that this is specifically intended to install the openJDK and not the one from Oracle)

Afterwards all is well:

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.
MichaelChirico
  • 33,841
  • 14
  • 113
  • 198
  • after I did the steps you recommended I also added following lines to my Cmakelists.txt file: `include_directories(/usr/lib/jvm/java-8-openjdk-amd64/include /usr/lib/jvm/java-8-openjdk-amd64/include/linux) link_directories(/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/amd64/server)` then deleted the Cmake cache and built the project again, then everything went well – Seyed Hossein Mirheydari Jun 15 '23 at 09:58
5

Setting JAVA_INCLUDE_DIR to where jni.h is located should solve your problem (setting CPPFLAGS did not work for me)

Assuming it is /usr/lib64/java/include;

export JAVA_INCLUDE_DIR=/usr/lib64/java/include
karanis
  • 51
  • 1
  • 3
  • I use build.xml for some older project and this didn't work for me, I had to provide and to make it working – kensai Jan 22 '18 at 13:16
3

Above answers give you a hardcoded path solution. This is bad on so many levels (java version change, OS change, etc).

Cleaner solution is to add:

JAVA_HOME = $(shell dirname $$(readlink -f $$(which java))|sed 's^jre/bin^^')

near the top of your makefile, then add:

-I$(JAVA_HOME)/include

To your include flags.

I am posting this because I ran into the same problem and spent too much time googling for wrong answers (I am building an app on multiple platforms so the build environment needs to be transportable).

GrueMaster
  • 101
  • 3
1

None of the posted solutions worked for me.

I had to vi into my Makefile and edit the path so that the path to the include folder and the OS subsystem (in my case, -I/usr/lib/jvm/java-8-openjdk-amd64/include/linux) was correct. This allowed me to run make and make install without issues.

riddle_me_this
  • 8,575
  • 10
  • 55
  • 80
0

In case you are on Ubuntu:

#X means 6,7,8...
apt install openjdk-X-jdk
gemfield
  • 3,228
  • 7
  • 27
  • 28
-2

I don't know if this applies in this case, but sometimes the file got deleted for unknown reasons, copying it again into the respective folder should resolve the problem.