How to set up JAssimp? - java

Assimp is a library used for importing 3D models into your application. It is written for C++, but there is a port for java called jassimp. For the past 5 or 6 hours I've been trying to set up jassimp in Eclipse and cannot get it to work. I downloaded the win-binaries version of assimp here, which also includes ported versions of it like jassimp. I will now posts the steps I have taken to get jassimp to function in hopes that someone will be able to identify an error.
I've mainly followed the "tutorial" shown here, which basically consists of the two parts under "HOW TO BUILD."
Keep in mind, I didn't and still don't really know what any of those commands mean. Anyways, I had to install MinGW since I'm not using Linux and because I could not find the equivalent in DOS commands. After changing the paths to point to the same places his did, my command looked like this:
gcc jassimp.cpp -I "C:/Program Files/java/jdk1.8.0/include" -I "C:/Program Files/java/jdk1.8.0/include/win32" -lassimp -shared -fPIC -o libjassimp.so
I ran it, but there was a problem I encountered::
jassimp.cpp:3:28: fatal error: assimp/cimport.h: No such file or directory
#include <assimp/cimport.h>
"Okay," I thought. "Well, those -I commands probably include files or something, so maybe I should look for the header file that's missing and include it via -I!" Thus, I looked through the jassimp folder for a "cimport.h" file, and what do you know, I found it in a folder called include. I then proceeded to change my command to
gcc jassimp.cpp -I "C:/Program Files/java/jdk1.8.0/include" -I "C:/Program Files/java/jdk1.8.0/include/win32" (new->)-I "C:/assimp-3.1.1-win-binaries/include/"(<-new) -lassimp -shared -fPIC -o libjassimp.so
Upon running it, I was very surprised to see that I got another error:
C:/mingw/bin/../lib/gcc/mingw32/4.8.1/../../../../mingw32/bin/ld.exe: cannot find -lassimp
"Hmmm..." I thought. After some googling, I found this answer. So, I went ahead and did what he did, and strangely enough, I saw that it was looking in some random folders for files called libassimp.dll, assimp.dll.a, libassimp.a, etc... "Hey, you shouldn't be looking in those folders!" I screamed.
"So how do I get it to look in the right location?" I wondered. Luckily, I found this answer. "Hmmm... he put -L and then the location of his library and then called -l< library >..." As I was thinking about how I was going to modify my command, I realized I was missing a little detail: what's the library I'm even trying to point to? Well, in the --verbose command, it looked like a file with a general name of assimp.lib or assimp.dll. And so, I searched the jassimp folder in hopes of finding a similar file. I found one named assimp.dll in a folder called bin64. I then changed my command once again:
gcc jassimp.cpp -I "C:/Program Files/java/jdk1.8.0/include" -I "C:/Program Files/java/jdk1.8.0/include/win32" -I "C:/assimp-3.1.1-win-binaries/include/" (new->)-L "C:/assimp-3.1.1-win-binaries/bin64"(<-new) -lassimp -shared -fPIC -o libjassimp.so
Running it gave me this error:
C:/assimp-3.1.1-win-binaries/bin64/assimp.dll: file not recognized: File format not recognized
So, I decided to build assimp as if I was using it for c++ in order to hopefully get a functional .dll file (I was really desperate...). I followed this (http:// assimp.sourceforge.net/lib_html/cmake_build.html) tutorial for building it, which uses CMake. Eventually, I built the project using CMake, which apparently just sets it up for use in Visual Studio, opened it in Visual Studio 2013, and built a release version of it from there. This gave me a .dll file which I then changed my command to point to:
gcc jassimp.cpp -I "C:/Program Files/java/jdk1.8.0/include" -I "C:/Program Files/java/jdk1.8.0/include/win32" -I "C:assimp-3.1.1-win-binaries/include/" (new->)-L "C:/assimp build/code/Release/"(<-new) -lassimp -shared -fPIC -o libjassimp.so
Well, at least it gave me a different error:
C:\Users\Nick\AppData\Local\Temp\ccgtrCg8.o:jassimp.cpp:(.eh_frame$_ZN7JNIEnv_9NewObjectEP7_jclassP10_jmethodIDz+0x13): undefined reference to `__gxx_personality_v0'
C:\Users\Nick\AppData\Local\Temp\ccgtrCg8.o:jassimp.cpp:(.eh_frame+0x14b): undefined reference to `__gxx_personality_v0'
c:/mingw/bin/../lib/gcc/mingw32/4.8.1/../../../../mingw32/bin/ld.exe: C:\Users\Nick\AppData\Local\Temp\ccgtrCg8.o: bad reloc address 0x14b in section `.eh_frame'
Googled it and just changed gcc to g++ and lo and behold, I got a file called libjassimp.so. Part 1 done. Or so I thought.
Time for part 2, which was relatively easier, so I'll just say I successfully ended up with a jassimp.jar file.
Time to put it all into my Eclipse project, which just consisted of me adding the jar file to the build path and attaching the libjassimp.so to the jar's native location. Upon trying to use one of the classes from jassimp, I came upon this little guy:
Exception in thread "main" java.lang.UnsatisfiedLinkError: no jassimp in java.library.path
I don't feel like explaining my thought process for this next part, so long story short, I changed the output file name in my command as such:
from
-o libjassimp.so
to
-o jassimp.dll
Genius, right? Running it with the new native file, I am now stuck with this:
Exception in thread "main" java.lang.UnsatisfiedLinkError: C:\Users\MyName\workspace\jassimp\lib\native\jassimp.dll: Can't load IA 32-bit .dll on a AMD 64-bit platform
Google says using -m64 will compile a .dll to be 64-bit, so I tried
g++ jassimp.cpp ... -m64 -o jassimp.dll
And, not very surprisingly, I got this error while trying to compile it from the command line:
jassimp.cpp:1:0: sorry, unimplemented: 64-bit mode not compiled in
If I messed up anywhere, I would have to guess it was when I changed the name output file from .so to .dll, but I don't know what else to do. I also could've messed up anywhere else.
Anyways, I'm stuck, and I honestly don't know what else I can do here. There doesn't seem to be many posts on this topic, but it seems that some other people have gotten it to work and I am just stupefied by it, since I don't know any other process other than mine that they could have taken. There is one solution I've read, which is using a 32-bit jvm/jdk/jre/whatever, but I read that a 64-bit computer is more efficient than 32-bit so I don't want to do that.

Got it working. Turns out I was using a 32-bit version of MinGW which was why I was compiling a 32-bit .dll. I also did not need to build assimp with CMake or Visual Studio: I could have simply used the assimp.lib and assimp.dll files located in the win-binaries assimp folder. The final command is here:
g++ jassimp.cpp -I "C:/Program Files/java/jdk1.8.0/include" -I "C:/Program Files/java/jdk1.8.0/include/win32" -I "C:/Users/Nick/Desktop/java libraries/assimp-3.1.1-win-binaries/include/" -L "C:/Users/Nick/Desktop/java libraries/assimp-3.1.1-win-binaries/bin64" -L "C:/Users/Nick/Desktop/java libraries/assimp-3.1.1-win-binaries/lib64" -lassimp -shared -fPIC -o -m64 jassimp.dll
The -m64 is unnecessary, but I put it there just to make sure that the dll compiles as 64 bit. Also, when I used the new jassimp.dll in Eclipse, I got an unsatisfied link error:
Exception in thread "main" java.lang.UnsatisfiedLinkError: C:\Users\MyName\workspace\myproject\lib\jassimp-native\jassimp.dll: Can't find dependent libraries
I fixed this by putting the assimp.dll file from assimp-3.1.1-win-binaries/bin64 into my system32 folder.
Hopefully this helps someone.
And if you have any questions, feel free to ask.

Related

iTextpdf Java compatibility

I need to encrypt a pdf document and decided to use itext Version 5.4.0 for this, and everything went well for my local test on my machine(with JAVA 1.8.0), but now I need to move the work to an oracle database 11gR2, and when I load the jar files (iText and bouncycastle) I keep getting the same error: ORA-29534:referenced object could not be resolved. I'm using the loadjava command for this:
loadjava -u SYSTEM/SYS_PWD#SID -o -r -v -f -noverify -synonym -g public itextpdf-5.1.0.jar
I've tried using SYS as well, but still getting the same error code.
I don't know if this has something to do with the JVM, the database uses JAVA 1.5.0.
I've searched about iText java requirements but couldn't found anything
useful, I'll be grateful with any help I can get.
I was able to upload, compile and use the libraries in the .jar files using the same command but with other parameter, and it compiled; the command I used is :
loadjava -u SYS/[pwd]#[SID] -r -v -f -genmissing -s -grant public [file].jar
Hope this can help someone in need out there!

Where is the program or package gcjh?

I'm having trouble similar to Unable to build pdftk from source on fedora machine, but I'm having it on Ubuntu 13.04.
I've install gcc-gcj, which provides gcj-4.8.
I opened Makefile.Debian, and modified it as follows. So it finds the proper version of some of the GCC build tools:
export VERSUFF ?=-4.6
Next, I tried to make:
$ VERSUFF="-4.8"; make -f Makefile.Debian
make -f Makefile -iC /home/jwalton/pdftk-2.02-dist/pdftk/../java all
...
make[1]: Entering directory `/home/jwalton/pdftk-2.02-dist/java'
gcjh-4.8 -force --classpath="/usr/share/java/libgcj-4.8.jar:/home/jwalton/pdftk-2.02-dist/java:."
pdftk/com/lowagie/text/Anchor
/bin/sh: 1: gcjh-4.8: not found
...
gcjh-4.8 -force --classpath="/usr/share/java/libgcj-4.8.jar:/home/jwalton/pdftk-2.02-dist/java:."
pdftk/org/bouncycastle/crypto/engines/AESFastEngine
/bin/sh: 1: gcjh-4.8: not found
Though I have installed gcc-gcj, it appears I don't have gcjh:
$ find /usr/bin -name gcjh
$ find /usr/local/bin -name gcjh
$
There is no gcc-java or gcc-gcjh packages:
$ apt-cache pkgnames | grep -i gcc-java
$ apt-cache pkgnames | grep -i gcc-gcjh
$ apt-cache pkgnames | grep -i gcjh
$
What is gcjh, and where can I find it for Ubuntu 13?
For anyone in recent years trying to compile pdftk or otherwise looking for gcj
The pdftk package relied on gcj, which is the GCC compiler for Java. GCJ was officially removed from GCC in September 2016, and by extension, discontinued by the package repositories themselves for the various distros. As a result of this, many notable systems have officially dropped the no-longer-buildable pdftk package itself from their repositories, including Fedora, Ubuntu and Cygwin.
I gave up attempting to build pdftk for my own Cygwin system because of the gcj dependency and because I couldn't trust a tool from developers who insist on using dependencies that have been deprecated for 4 years now. An email exchange here from 2014 - two years before GCJ was finally dropped by GCC - cites the developer of pdftk as saying:
Yes, I've heard that they're dropping support for libgcj. We have been
working on a new pdftk that doesn't depend on libgcj, but it is
currently pre-beta.
However, it seem nothing came from this "pre-beta", since the last time pdftk had an update at all was in 2013.
I personally had two options available to me: to install the Windows binary of the pdftk, which would result in an installation separate to the rest of my Cygwin environment, or to use a different but similar tool such as qpdf. Given what I now knew of the last time that pdftk had been updated, I opted to use qpdf and so far haven't been disappointed. The one criticism I have of qpdf is that the website and documentation looks a lot less prettier compared to pdftks, but the tool itself appears to have all of the same functionality as pdftk.
qpdf is also available and actively maintained on most other major Unix-like systems, including Ubuntu and Fedora.
For anyone who's still desperate to compile pdftk for a Linux distribution, for either workflow or legacy reasons, the above-linked Github thread has some instructions that seem like they still work for a few people.
Use http://packages.ubuntu.com/ to search, and I get http://packages.ubuntu.com/search?searchon=contents&keywords=gcjh&mode=exactfilename&suite=saucy&arch=any suggesting that the answer is gcj-jdk.

JNI: Problems compiling 64-bit native libraries

I compiled a native DLL file on Windows (64-bit) with GCC flags -c and -o Name.dll.
When I did System.load("fullpahhere"), I get this error:
java.lang.UnsatisfiedLinkError: RenderControl.dll: %1 is not a valid Win32 application
If I recompile adding a blank main() method to the C source and removing the -c flag, it then fails with an UnsatisfiedLinkError that says it can't load a 32 bit DLL on a 64 bit machine.
Why is Java calling a DLL with no main method invalid? Doesn't that ruin the whole point of DLL files and the JNI?
Update
I fixed the main() issue. This GCC invocation setup works:
gcc -Wall -D_JNI_IMPLEMENTATION_ -Wl,--kill-at -I "C:\Program Files\Java\jdk1.6.0_32\include" -I "C:\Program Files\Java\jdk1.6.0_32\include\win32" -shared *.c -o lib.dll
I still need to figure out the JVM Architecture problem, however.
Where can I find a MinGW installation that is capable of compilnig 64 bit code? It seems my standard MinGW install only does 32 bit.
If I can get my hands on that, how do I decide which library to load in Java? Is there a System property that shows the JVM arch (NOT the OS arch)?
If you use the MinGW32 compiler, you cannot produce 64-bit code. This is something that is most likely intentional. Similar issues with other people I quickly looked up seem to suggest that you're trying to use a 32-bit native binary with 64-bit java.
Try compiling with mingw-w64 and see if that allays the problem.
There's also the possibility that your library simply isn't in the library path and that it's not being found even though you're giving System.load the full path, in which case you should make sure that your DLL is in the correct location for native libraries.
Check out http://tdm-gcc.tdragon.net/, to download TDM-GCC which gives an easy installation on Windows for MinGW-w64 referenced above. You can use the following code to generate a 64-bit dll after installint TDM-GCC.
"C:\MinGW64\bin\gcc.exe" -m64 -c -I"C:\Program Files\Java\jdk1.6.0_26\include" -I"C:\Program Files\Java\jdk1.6.0_26\include\win32" HelloWorld.c
It is the "-m64" which makes it 64 bit. This is run from the same directory as the HelloWorld.c C Code Source File. This generates the HelloWorld.o C Code Object File in the same directory as run..

UnsatisfiedLinkError when using JNI?

I want to call a C program from Java program using JNI in linux ubuntu.
I am new to this and I have tried the sample program given in http://www.ibm.com/developerworks/java/tutorials/j-jni/section2.html
. I have already created the .java, .h , .c and .so files. But when i tried to run the program I am getting the following error.
Exception in thread "main" java.lang.UnsatisfiedLinkError: no Sample1 in java.library.path
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1738)
at java.lang.Runtime.loadLibrary0(Runtime.java:823)
at java.lang.System.loadLibrary(System.java:1028)
at Sample1.main(Sample1.java:13)
This exception is indicating that the .so is not available to the JVM.
Adding the directory where the .so exists to the LD_LIBRARY_PATH will resolve this. If the .so depends on other .so libraries the directories where these .so exist will also need added to LD_LIBRARY_PATH.
I've just tried to get the same sample to work on my CentOS and got the same error as you. As already answered, JVM failed to find the so file needed. I succeeded to get it to work by following the steps below using gcc:
$ javac Sample1.java
$ javah Sample1
$ # Include paths must also be specified using -I option in the following gcc command line!
$ gcc -shared -I...snip... Sample1.c -o libSample1.so
$ # Library path for libSample1.so must also be specified!
$ java -Djava.library.path=...path/to/libSample1.so... Sample1
If you omit the "lib" prefix of the shared library, JVM fails to find it for some reason.
I don't know why. I am not familiar with the naming convention of shared libraries in Linux.
I hope this post could help.

64 Bit Java Path in Cygwin

Ok, so this is actually quite a long story, but i'll try and keep it pretty short. So I'm trying to get the WebOS SDK working on Windows using Cygwin. Well, it wasn't working. It kept complaining that i was using a 32 bit version of java instead of 64 bit. the explenation for that problem is pretty easy to figure out. my PATH variable was set wrong and was pointing to my 32 bit installation of Java. Simple solution YOU'D THINK. apparantly not. for some reason, despite my best efforts, i cannot get the 64 bit version of java written into the PATH variable. The problem:
Cygwin doesn't like spaces in the Path variable, even though the path variable is littered with spaces, it won't accept it when i add my own space. After a lot of googling, i've found multiple accurances of this problem, and multiple solutions. but none of them seem to work. i always get exactly the same error:
bash: /usr/local/bin:/usr/bin:/cygdrive/c/Program: No such file or directory
The error is pretty self explanetary, basically its not reading anything past the first space, and i have no such directory as C:/Program so it spits out an error, my question is how do i get it to except a space, because changing the name of the directory is not an option, too many things depend on it. heres what i've tried so far:
$PATH=$PATH:C:\PROGRA~1\Java\jre6
$PATH=$PATH:"'pwd'" (while in java directory)
$PATH=$PATH:/cygdrive/c/Program Files/Java/jre6/bin (hay, i had to try)
$PATH=$PATH:/cygdrive/c/"Program Files"/Java/jre6/bin
$PATH=$PATH:/cygdrive/c/Program\ Files/Java/jre6/bin (escape character was rumored to work
$PATH=$PATH:'/cygdrive/c/Program Files/Java/jre6/bin'
$PATH=$PATH:"`/cygdrive/c/Program Files/Java/jre6/bin`"
and i think that was it, if anyone knows how to actually do it properly (or improperly but working for all i care) it would be greatly appreciated
Thanks
--
Chris
You also have the option of using the cygpath tool to help. Cygpath can be used to convert from a Window's path to a Unix path, but that doesn't directly handle spaces, so you need to do a two step process, first eliminate the spaces by converting to a DOS (short) path name, then convert to a Unix style path:
PATH=$(cygpath -u $(cygpath -m -s "C:\Program Files\Java\jre6\bin")):${PATH}
PATH=$(cygpath -u $(cygpath -m -s "C:\Program Files (x86)\HP webOS\PDK\bin")):${PATH}
PATH=$(cygpath -u $(cygpath -m -s "C:\Program Files (x86)\HP webOS\SDK\bin")):${PATH}
PATH=$(cygpath -u $(cygpath -m -s "C:\Program Files (x86)\HP webOS\SDK\bin\novacom")):${PATH}
The end result will be something like (short names may differ slightly):
/cygdrive/c/PROGRA~3/HPWEBO~1/SDK/bin/novacom:/cygdrive/c/PROGRA~3/HPWEBO~1/SDK/bin:/cygdrive/c/PROGRA~3/HPWEBO~1/PDK/bin:/cygdrive/c/PROGRA~1/Java/jre6/bin:....other path elements....
One thing to keep in mind when using this, cygpath generates an error if the provided path actually does not exist because it can not create the short path for a non-existent path.
What is nice about this approach is that if you set Windows environment variables (like for example JAVA_HOME) then you can use that environment variable in the convert operation inside the .bash_profile, since all Windows environment variables are visible when the profile is being loaded. So if you had in the Windows environment
JAVA_HOME=C:\Program Files\Java\jre
then the cygpath command can be
$(cygpath -u $(cygpath -m -s "${JAVA_HOME}\bin"))
which means you only ever need to update via the Windows settings if the java install changes.
In .bash_profile:
PATH=/cygdrive/c/Program\ Files/Java/jre6/bin/:${PATH}
PATH=${PATH}:/cygdrive/c/Program\ Files\ \(x86\)/HP\ webOS/PDK/bin
PATH=${PATH}:/cygdrive/c/Program\ Files\ \(x86\)/HP\ webOS/SDK/bin
PATH=${PATH}:/cygdrive/c/Program\ Files\ \(x86\)/HP\ webOS/SDK/bin/novacom
Adds the paths to your .bash_profile and both java and the webOS SDK tools should be available.

Categories

Resources