I'm trying to learn JNI but everytime I try to run the java program, it throws an exception stating that it couldn't find the *.so library in the lib path with I declared when launching - this should happen. I was under the impression that it shouldn't but then I realized that I never made a so file and in-fact I was trying load an executable (Ubuntu doesn't make clear file extensions).
Anyways, how can I compile my cpp files into .so files using code blocks. I've been looking all over and all I've found is complicated gcc commands that I don't quite understand.
Any insight on how to create shared object libs from code blocks would be a great help.
You can create the object (.o) files of your classes and then use the -shared tag to combine them into a dynamically linked library.
In my experience, Code blocks does not provide the users with the ability to do so. You will have to make use of gcc.
I solved it under Linux fedorra with a shell script compile_shared.sh
#!/bin/bash
g++ -I ./include/ -c -fPIC src/MyClass.cpp -o so/MyClass.o
g++ -shared -Wl,-soname,lib_MyClass.so -o so/lib_MyClass.so so/MyClass.o
in the root folder and adjusting the build options in Codeblocks, such that the script is executed after the built.
Codeblocks
Project -> Build options ...
Select cpp in tree view on the left
Pre/post build steps
add "xterm -T bash ./compile_shared.sh" in the Post-build steps textfield
This compiles the File ./src/MyClass.cpp to ./so/MyClass.o and in a next step to ./so/lib_MyClass.so.
Related
I was trying to make libimagequant library work in java but I can't make the "dll" and can't make the "jnilib", I don't know why but it just doesn't work, if somebody could help it would be awesome.
I have already tried to make the "Makefile" but it gives me errors on errors, maybe someone already compiled a dll, I still don't understand why they don't pre build all the source.
EDIT NUM 1:
I would like to make the libimagequant library work in my java program,
I downloaded the library https://github.com/ImageOptim/libimagequant
when i tried to run make Makefile java it gave me a message that touch is not recognized, as touch is not important i removed the command from Makefile, then i run it again and now it is giving me this error:
process_begin: CreateProcess(NULL, env bash C:\Users\Me\Desktop\libimag
equant\configure, ...) failed.
make (e=2): The system cannot find the file specified.
make: Nothing to be done for `Makefile'.
javah -o org/pngquant/LiqObject.h org.pngquant.LiqObject
javac org/pngquant/PngQuant.java
javah -o org/pngquant/PngQuant.h org.pngquant.PngQuant
javah -o org/pngquant/Image.h org.pngquant.Image
javah -o org/pngquant/Result.h org.pngquant.Result
make: *** No rule to make target `config.mk', needed by `pam.o'. Stop.
So this is a little bit messy, however I have a single .cpp file that I want to be used in two different ways; as a c class called by a java class using JNI, and as a c program standalone. The reason for this is because this code moves around between machines and sometimes I want to just run and compile the c++ code directly as opposed to running java and having java run it. (The c++ code has a main method that is only ever ran in the standalone version).
So anyways I have the file (test.cpp) and the java source code that goes with it (test.java) in /home/user/dev/javajni/. However, I also want to be able to compile it as a standalone in /home/user/dev/standalone/. In the standalone directory I have a make file that only compiles the c program.
Anyways, when I make a hardlink to the file in javajni inside the standalone directory the makefile doesn't see it, or refuses to see the hardlink.
make: *** No rule to make target `test.cpp', needed by `test'. Stop.
And while in the standalone directory I use:
ln /home/user/dev/javajni/test.cpp test.cpp
But when I copy the entire file over it works fine.
What's the big deal? Isn't the original file in the original location technically just a hardlink to the inode as well? I just want to be able to alter the file in one location without having to copy and paste it back and forth.
If at all useful this is what my makefile looks like:
EX=test
all: $(EX)
.cpp.o:
g++ -c -O3 -Wall $<
clean:
rm -f $(EX) *.o *.a
test:test.cpp; g++ -Wall -o $# $^
(Fyi I did change the name of the file and the directories in this post for simplification)
i am trying to do this tutorial it's for JNI
https://netbeans.org/kb/docs/cnd/beginning-jni-linux.html
i already did everything in there, but i am having this trouble
Exception in thread "main" java.lang.UnsatisfiedLinkError: Can't load library: /home/usr/NetBeansProjects/JNIDemoCdl/dist/libJNIDemoCdl.so
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1846)
at java.lang.Runtime.load0(Runtime.java:795)
at java.lang.System.load(System.java:1061)
at jnidemojava.Main.<clinit>(Main.java:13)
Java Result: 1
i am kind of stuck with JNI for a time now, and i could use some help, thanks
Make sure you have read/write permissions recursively over the directory structure and the lib file itself.
Try
sudo chmod ug+rwX -R /home/usr/NetBeansProjects/
That will add read/write permissions to the files and dirs, and execute permissions on directories and files that already have the execute flag for a user.
Hope this helps.
I never use mac but using windows i have faced same problem when i start working with jni.
With your problem it could be many things or one
the created dll flag is not correct, make sure you have used correct command to create dll.
i use the following command
gcc -Wall -D_JNI_IMPLEMENTATION_ -Wl,--kill-at -I"C:\Program Files\Java\jdk1.7.0\include" -I"C:\Program Files\Java\jdk1.7.0\include\win32" -shared -o Sample1.dll Sample1.cpp
for this i used mingw compiler.
in windows dll file on mac this will so.
i used the command
System.loadlibrary("youLibraryNameWithoutExtensionAndPath")
before this go to your project build path and expand jre and select native library then click brows and select folder where you put dll/so file and ok.
now try to run your code. this will solve issue.
but if the dll/so file have dependent lib then you have to put all dll file in system32 folder (in windows)
If I am writing HelloWorld, is there a way I can run the program from any directory by just typing HelloWorld? Sort of the same way once you set up Ant, you can just run Ant from any directory?
Just for some details, we are creating a CLI based toolkit for a customer, and just curious if we can compile it, install it, and just have them run it using the toolkit name.
You can always create a shell script, call it HelloWorld and make it run java with your JAR.
You'll then need to chmod the script to make it executable, and place it somewhere in your $PATH.
The script would like something like:
#!/bin/bash
cd /path/to/helloworld
java -jar HelloWorld.jar "$#"
or
#!/bin/bash
java -jar /path/to/helloworld/HelloWorld.jar "$#"
depending on your exact requirements.
Common solution for your problem is to create a separate launcher application, which is non-java application that runs your Java program. Launcher can be written in some compilable language such as C/C++ and compiled into native executable. Also it can be written in some interpreted language such as Unix shell, perl, python etc and made executable by adding #!/path/to/interpreter line at the beginning of launcher file and setting executable flag on it. Also there are several utilities that can generate launcher for your program such as launch4j or jsmooth.
On Linux (specifically), you could use the /proc filesystem (see proc(5) man page) and its binfmt_misc (actually the /proc/sys/fs/binfmt_misc/register pseudo-file and other pseudofiles under /proc/sys/fs/binfmt_misc/) to register java as the handler for .class or .jar files. Read the Documentation/binfmt_misc.txt file in the kernel source for gory details.
Then any executable .jar file would be interpreted by java (or jexec)
I'm not sure it is worth the effort. I find that wrapping your Java program in some shell script is much more easy (and more portable, because few Linux systems actually use binfmt_misc, and your customer may need some sysadmin skills to enable it).
I downloaded the JDK sources and I am trying to make a modification in the ServerSocketChannelImpl. The ServerSocketChannelImpl.java uses native code for the accept0 method. The native code for this method is in ServerSocketChannelImpl.c. I need to make a small change there and rebuild the .so library so I can use it with my JVM.
When I build my own general JNI library, i use a gcc command-line as below:
gcc -I/usr/lib/jvm/java-6-oracle/include/ -I/usr/lib/jvm/java-6-oracle/include/linux/ -fPIC -o libHello.so -shared org_tsutils_Hello.c
But for the JVM C source code I am not sure how to proceed. Does anyone have an idea?
if you are implement native method you should run javah on your code and it will generate h files that will fill the c++ code that you have now you add the compilation product including the header to your class path.