Issue
I'm trying to create a JNI project in Eclipse using CDT. I'm following this tutorial.
So first I created my project as a Java project and created a HelloJNI
class in the default package, which contains some really basic code.
I then added a C nature to my project, selecting 'Makefile Project' in 'Project type' and 'Linux GCC' in 'Toolchains'.
Then I created a new directory called 'jni' to store all the C code. I then created a new file in eclipse called 'makefile' (note the lowercase name) and added this to it.
# Define a variable for classpath
CLASS_PATH = ../bin
# Define a virtual path for .class in the bin directory
vpath %.class $(CLASS_PATH)
# $* matches the target filename without the extension
HelloJNI.h : HelloJNI.class
javac -h -classpath $(CLASS_PATH) $*
I then created a build target called 'HelloJNI.h' in the jni folder, which automatically used the makefile. I then attempted to build the target, but I got this error:
javac -h -classpath ../bin HelloJNI
javac: invalid flag: ../bin
Usage: javac <options> <source files>
use -help for a list of possible options
make: *** [makefile:9: HelloJNI.h] Error 2
I am puzzled by the error message. Does javac recognize ../bin
as a flag? Is there some weird bug happening in Eclipse? If I try to do this in the terminal, I get the same error. I tried searching for answers, but found none.
This is my directory strcture:
-bin
HelloJNI.class
-jni
makefile
-src
HelloJNI.java
Edit: Changing the javac call to
javac -h -classpath $CLASS_PATH $*
gave me the following error:
error: Class names, 'LASS_PATH,HelloJNI', are only accepted if annotation processing is explicitly requested
Solution
Starting point
Looking at the tutorial you're following, your question lines up with "2. Getting Started", specifically "Step 2" – compiling Java and generating a C/C++ header file.
To revisit, here's what you tried:
javac -h -classpath ../bin HelloJNI
A few points..
- The
-h
option tojavac
specifies a directory. This directory is where the generated header file should go. It requires a directory name immediately after, like this:-h directory
. In the attempt above, it's using the-h
option, but doesn't specify a directory. That's an issue. - This includes
-classpath ../bin
which isn't necessary for this example. It's not a problem, but it isn't necessary to include and can be removed. - "HelloJNI" is not an appropriate input for the compiler - you need to specify a ".java" filename
The fix
In the tutorial, they show this example:
javac -h . HelloJNI.java
This works because:
They're using
-h
with "." as the directory (where "." means "current directory").They're compiling the .java file – "HelloJNI.java"
Also, they're not using
-classpath
. That option is used to designate where to find class files for compilation (as input to compilation itself), but that isn't relevant for this tutorial example – there aren't any necessary input classes forjavac
to work. So, just remove-classpath ../bin
altogether.
In the end, things should work for you if you run the command as they posted in the tutorial:
javac -h . HelloJNI.java
Also: JDK version differences
You didn't specify which JDK version you're using, but if you're using an older (pre-8) version of the JDK, there are
different steps to follow (namely, using javah
in addition to javac
).
Answered By - Kaan
Answer Checked By - David Marino (JavaFixing Volunteer)