JNI.h header cannot be found - java

I'm trying to create a JNI application between java and c++ and the include #include is telling me that jni.h cannot be found. I've looked at a half dozen threads and web pages and tried fixes that haven't worked. I don't have anything in the path Library/Framework/JavaVM.framework if that helps, and I can't figure out how to get it.
I'm trying to build a JNI project. I know that jni.h is in the path /Library/Java/JavaVirtualMachines/jdk1.7.0_51.jdk/Contents/Home/include but for some reason this makefile isn't working.
EDIT: also, I'm using eclipse if that matters.
# Define a variable for classpath
CLASS_PATH = ../bin
# Define a virtual path for .class in the bin directory
vpath %.class $(CLASS_PATH)
all : hpaprogram.dll
# $# matches the target, $< matches the first dependancy
hpaprogram.dll : HPAProgram.o
gcc -Wl,--add-stdcall-alias -shared -o $# $<
# $# matches the target, $< matches the first dependancy
HPAProgram.o : HPAProgram.c++ HPAProgram.h
gcc -I"/Library/Java/JavaVirtualMachines/jdk1.7.0_51.jdk/Contents/Home/include" -c $< -o $#
# $* matches the target filename without the extension
HPAProgram.h : HPAProgram.class
javah -classpath $(CLASS_PATH) $*
clean :
rm HPAProgram.h HPAProgram.o hpaprogram.dll

I figured it out. My JavaVM.framework was actually in /System/Library/Framework/JavaVM.framework

Related

Compiling basic java project

I want to compile a basic java project, https://sourceforge.net/projects/pdfformfiller2 its installation instructions are quite short:
Make sure that iText library, itext-xtra-5.x.0.jar and itextpdf-5.x.0.jar, are accessible to JAVA,
e.g. these are placed in the "lib" subfolder of the current folder.
Get latest ones from: https://sourceforge.net/projects/itext/files/iText/
Compile PdfFormFiller.java
Then from the command line you give command (to see usage help):
java -jar pdfformfiller.jar
I never compiled jars before, and I'm having hard time trying to compile PdfFormFiller correctly. Here's where I've get:
wget -O pdfformfiller.zip https://sourceforge.net/projects/pdfformfiller2/files/latest/download
# author mentions 5.2.0, which is not available anymore, so we go for the latest 5.x:
wget http://kent.dl.sourceforge.net/project/itext/5.5.10/itext5-5.5.10.zip
unzip pdfformfiller.zip
unzip itext5-5.5.10.zip -d pdfformfiller/lib
cd pdfformfiller
javac -cp "lib/*" PdfFormFiller.java
mkdir META-INF
echo -e 'Manifest-Version: 1.0\nClass-Path: pdfformfiller.jar\nMain-Class: PdfFormFiller' > META-INF/MANIFEST.MF
jar -cvfm pdfformfiller.jar META-INF/MANIFEST.MF lib PdfFormFiller.class
Which succeeds without an error, but still doesn't run:
$ java -jar pdfformfiller.jar
Error: Could not find or load main class PdfFormFiller
I guess I'm missing something trivial?
Edit
Complete automation:
iText5=5.5.10
wget -O pdfformfiller.zip https://sourceforge.net/projects/pdfformfiller2/files/latest/download
wget http://kent.dl.sourceforge.net/project/itext/${iText5}/itext5-${iText5}.zip
unzip pdfformfiller.zip
unzip itext5-${iText5}.zip -d pdfformfiller/lib
cd pdfformfiller
mkdir classes
javac -cp "lib/*" -d ./classes/ PdfFormFiller.java
mkdir META-INF
echo 'Manifest-Version: 1.0' > META-INF/MANIFEST.MF
echo "Class-Path: ./lib/itextpdf-${iText5}.jar ./lib/itext-xtra-${iText5}.jar ./lib/itext-pdfa-${iText5}.jar" >> META-INF/MANIFEST.MF
echo 'Main-Class: PdfFormFiller.PdfFormFiller' >> META-INF/MANIFEST.MF
jar -cvfm pdfformfiller.jar ./META-INF/MANIFEST.MF ./lib -C ./classes/ PdfFormFiller
Edit 2
It seems to be the only way to fill pdf form from CLI reliably:
# list fields in a file:
$ java -jar pdfformfiller.jar input.pdf -l
myfield
# prepare field data:
$ echo 'myfield αβγ' > fields
# specify font, fill the fields, flatten the form:
$ java -jar pdfformfiller.jar input.pdf -f fields -font Times_New_Roman.ttf -flatten output.pdf
Works like a charm!
Here are the steps I followed to get it working.
First of all, just for the sake of clarity, let's create a dedicated folder for your compiled classes. It's not mandatory, but just an example of good development practice. I'm omitting the steps of creating folders, changing dirs etc. because it's quite obvious. All commands are run from the project's root directory
javac -cp "lib/*" -d ./classes/ PdfFormFiller.java
Fixing the two main things that were missed:
a) the reference for required lib folder and
b) package name:
echo -e 'Manifest-Version: 1.0\nClass-Path: ./lib/itextpdf-5.5.4.jar ./lib/itext-xtra-5.5.4.jar ./lib/itext-pdfa-5.5.4.jar\nMain-Class: PdfFormFiller.PdfFormFiller' > META-INF/MANIFEST.MF
Assembling jar (please note that additional option: -C is being used here):
jar -cvfm pdfformfiller.jar ./META-INF/MANIFEST.MF ./lib -C ./classes/ PdfFormFiller
This is the final output from executing the resulting jar file:
$ java -jar pdfformfiller.jar
USAGE: pdfformfiller document.pdf [ -l ] [ -v ] [ -f fields_filename ] [ -font font_file ] [ -flatten] [ output.pdf ]
document.pdf - name of source pdf file (required).
-l - only list available fields in document.pdf.
-v - verbose. Use to debug the fields_filename file.
-f fields_filename - name of file with the list of fields values to apply to document.pdf.
if ommited, stdin is used.
-font font_file - font to use. Needed UTF-8 support, e.g. cyrillic and non-latin alphabets.
-flatten - Flatten pdf forms (convert them to text disabling editing in PDF Reader).
output.pdf - name of output file. If omitted, the output if sent to stdout.
fields_filename file can be in UTF-8 as is of the following format:
On each line, one entry consists of 'field name' followed by value of that field without any quotes.
Any number of whitespaces allowed before 'field name', and one space separates 'field name' and its value.
In value, newline characters should be encoded as "\n",
'U+2029 utf-8 E280A9 : PARAGRAPH SEPARATOR PS' should be encoded as "\p",
and '\' characters should be escaped as "\\".
For checkboxes, values are 'Yes'/'Off'.
Based on the Belgian iText library v. 5.2.0, http://www.itextpdf.com/

JNI make file is not working. Multiple definitions

So I am trying to make a jni library but the make file gives a strange error that I don't really understand.
/tmp/ccPWlMuy.o: In function `Java_GameLogic_setMap':
GameLogic.c:(.text+0x0): multiple definition of `Java_GameLogic_setMap'
/tmp/ccajmgva.o:GameLogic.c:(.text+0x0): first defined here
/tmp/ccPWlMuy.o: In function `Java_GameLogic_hello':
GameLogic.c:(.text+0x1c): multiple definition of `Java_GameLogic_hello'
/tmp/ccajmgva.o:GameLogic.c:(.text+0x1c): first defined here
collect2: ld returned 1 exit status
make: *** [GameLogic.o] Error 1
and the make file is:
# Define a variable for classpath
CLASS_PATH = .
# Define a virtual path for .class in the bin directory
vpath %.class $(CLASS_PATH)
all : libGameLogic.so
# $# matches the target, $< matches the first dependancy
libGameLogic.so : GameLogic.o
gcc -W1 -shared -o $# $<
# $# matches the target, $< matches the first dependancy
GameLogic.o : GameLogic.c GameLogic.h
gcc -fPIC -I /usr/lib/jvm/java-1.6.0-openjdk-1.6.0.38.x86_64/include -I /usr/lib/jvm/java-1.6.0-openjdk-1.6.0.38.x86_64/include/linux -shared GameLogic.c -o libGameLogic.so Map.c GameLogic.c
GameLogic.h: GameLogic.class PlayGame.class Bot.class
javah -classpath $(CLASS_PATH) GameLogic
GameLogic.class: GameLogic.java
javac *.java
PlayGame.class: PlayGame.java
javac *.java
Bot.class: Bot.java
javac *.java
clean :
rm GameLogic.o libGameLogic.so
To run the make file I type in make into the terminal and this is the error that it creates. For this I need to have it so that JNI makes a c call which then calls a method in another c file.
So Java <-> JNI <-> GameLogic <-> Map
In that order.
Any advice is much appreciated many thanks.
gcc -fPIC -I /usr/lib/jvm/java-1.6.0-openjdk-1.6.0.38.x86_64/include -I /usr/lib/jvm/java-1.6.0-openjdk-1.6.0.38.x86_64/include/linux -shared -o libGameLogic.so Map.c GameLogic.c
Map.h:7: warning: array ‘name’ assumed to have one element
Map.h:10: warning: array ‘map’ assumed to have one element
gcc -W1 -shared -o libGameLogic.so GameLogic.o
gcc: GameLogic.o: No such file or directory
gcc: no input files
make: *** [libGameLogic.so] Error 1
-bash-4.1$
You are compiling and linking GameLogic.c twice in this line:
# $# matches the target, $< matches the first dependancy
GameLogic.o : GameLogic.c GameLogic.h
gcc -fPIC -I /usr/lib/jvm/java-1.6.0-openjdk-1.6.0.38.x86_64/include
-I /usr/lib/jvm/java-1.6.0-openjdk-1.6.0.38.x86_64/include/linux
-shared GameLogic.c -o libGameLogic.so Map.c GameLogic.c

GCC option not found while constructing .dll

I'm trying to create a .dll while following this tutorial (http://www3.ntu.edu.sg/home/ehchua/programming/java/JavaNativeInterface.html) to use JNI in my eclipse project. There's an issue with my makefile however that may be unrelated to all the JNI stuff.
I'm getting "unknown option: --add-stdcall-alias" when I build (make all). I'm using the Mac GCC Compiler. Here's my console log and make file:
EDIT: So i removed the option that is giving me the error and my build worked. However, I feel unsafe just removing a line of code that I am clueless about. Any one want to tell me the implications of removing this code?
console output:
18:05:33 ** Build of configuration Default for project HPA* Testing *
make all
javah -classpath ../bin HPAProgram
gcc -Wl,--add-stdcall-alias -shared -o hpaprogram.dll HPAProgram.o
ld: unknown option: --add-stdcall-alias
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: ** [hpaprogram.dll] Error 1
18:05:34 Build Finished (took 823ms)
makefile:
# Define a variable for classpath
CLASS_PATH = ../bin
# Define a virtual path for .class in the bin directory
vpath %.class $(CLASS_PATH)
all : hpaprogram.dll
# $# matches the target, $< matches the first dependancy
hpaprogram.dll : HPAProgram.o
gcc -Wl,--add-stdcall-alias -shared -o $# $<
# $# matches the target, $< matches the first dependancy
HPAProgram.o : HPAProgram.c++ HPAProgram.h
gcc -I /System/Library/Frameworks/JavaVM.framework/Versions/A/Headers/ -c $< -o $#
# $* matches the target filename without the extension
HPAProgram.h : HPAProgram.class
javah -classpath $(CLASS_PATH) $*
clean :
rm HPAProgram.h HPAProgram.o hpaprogram.dll
I practiced by following the same tutorial, it turned out that it's OK to get rid of "-Wl,--add-stdcall-alias".
BTW, in Mac, you have to use ".dylib" instead of ".so", otherwise you will get error saying "java.lang.UnsatisfiedLinkError: no hello in java.library.path".

Solution for error ClassDefNotFound in Java

I have five class files Servant.class, Server.class, Client.class, TransferRequest.class and TransferResponse.class. My Makefile is at the below. I have this error for any of my class file:
Error occurred during initialization of VM
java/lang/NoClassDefFoundError: java/lang/Object
Makefile:11: recipe for target 'TransferRequest.class' failed
How can I cope with this error? I really tried all solutions which was written here such changing path or sth. This makefile is also 5th or 6 th one. The other well known makefiles gave same error too. I am on Windows machine I use cygwin.
Makefile:
JAVAC=javac
sources = $(wildcard *.java)
classes = $(sources:.java=.class)
all: $(classes)
clean :
rm -f *.class
%.class : %.java
$(JAVAC) $<
Add a classpath (with the -cp) option to your javac.
JAVAC=javac -cp "$CLASSPATH"
Or you could change
$(JAVAC) $<
to add the classpath
$(JAVAC) -cp "$CLASSPATH" $<
This is a problem with javac. Either something is missing from your make file or your java installation is broken.
Find out if you can compile a file by hand with javac to narrow it down.

How can I make makefile for java with external jar file?

I have a java project, and need to write makefile to let it run on Linux. My project includes external jar files and resource package(.txt resourses).I am really a newbie for Linux, and just learn how to write makefile.
I refer to some materials and write a makefile like this:
# Set the file name of your jar package:
JAR_PKG = ADBproject1.jar
# Set your entry point of your java app:
ENTRY_POINT = adb/Bing_WebResults/Run.java
# Need resource directory
RES_DIR = yes
SOURCE_FILES = \
adb/jsonModels/Metadata.java \
adb/jsonModels/Result.java \
adb/jsonModels/Data.java \
adb/jsonModels/DataContainer.java \
adb/models/Weight_ID.java \
adb/models/Pair.java \
adb/models/Document.java \
adb/models/Collections.java \
adb/Bing_WebResults/Bing_Search.java\
adb/Bing_WebResults/Run.java \
JAVAC = javac
JFLAGS = -encoding UTF-8
vpath %.class bin
vpath %.java src
# show help message by default
Default:
#echo "make new: new project, create src, bin, res dirs."
#echo "make build: build project."
#echo "make clean: clear classes generated."
#echo "make rebuild: rebuild project."
#echo "make run: run your app."
#echo "make jar: package your project into a executable jar."
build: $(SOURCE_FILES:.java=.class)
# pattern rule
%.class: %.java
$(JAVAC) -cp bin -d bin $(JFLAGS) $<
rebuild: clean build
.PHONY: new clean run jar
new:
ifeq ($(RES_DIR),yes)
mkdir -pv src bin res
else
mkdir -pv src bin
endif
clean:
rm -frv bin/*
run:
java -cp bin $(ENTRY_POINT)
jar:
ifeq ($(RES_DIR),yes)
jar cvfe $(JAR_PKG) $(ENTRY_POINT) -C bin . res
else
jar cvfe $(JAR_PKG) $(ENTRY_POINT) -C bin .
endif
But I don't know how to add those two external .jar files (gson.jar, commons.jar) into makefile. And I'm not quite sure, whether the file paths I wrote are correct.
javac has a -cp and -classpath argument:
-classpath <path> Specify where to find user class files and
annotation processors
-cp <path> Specify where to find user class files and
annotation processors
They seem to be equivalent as far as the documentation is concerned.
I solve the problem by adding all *.jar files to a new folder "lib".
Then
javac -sourcepath src/ -classpath lib/*.jar
will solve the external jar file problem.

Categories