I'm new to the Jni environment and I want to cross compile the shared library builds using the docker so the Jar can be packed easily from any platform and can include the required shared libraries.
I had more attempts to do via CMake and Meson build system but never succeed in them, so I shifted to docker, luckily I found a repo (dockcross) which provide prebuilt images for cross compiling C/C++ toolchains.
Since the toolchains are for the windows I would have no problems when compiling with that toolchain, platform-dependent code (like long which is 32 bit in windows) should be compiled and linked through the cross-compiler and platform dependent libraries will build fine.
So, I only need the Jni headers to build. The problem is I couldn't install the Windows JDK in Linux environment, so I am not able to get the header files (jdk/include/win32).
How shall I proceed getting the header files for the build?
Found OpenJDK headers in the github repository.
Although that's not properly arranged as one in the JDK installation, its worth hardcoding those paths or use a simple bash/python script :)
Hopefully its helpful. Since its nowhere written or guided to be used. Many blog posts just download extract the whole jdk for all three OS, and then put them on their repo, which probably isn't be best idea because those headers are licensed as GPL2 and any OSS having non-GPL2 licenses (like MIT) may suffer to not do such things.
But alright, we found it so we can remotely use them as a dependency on any OSS projects!
Right now I'm trying to get Java3D to work with JDK 1.8.0 in Eclipse on OS X. I've tried following this tutorial (among many others) and am finding varying levels of no success. I believe part of the problem is that there are currently 3 separate locations with the Java3D .jars are ending up on the build path:
/Library/Java/Extensions/ as a part of the JRE system library
/System/Library/Java/Extensions/ as a part of the JRE system library
My personal libraries folder as external included .jar files
Earlier in project development, I hadn't updated the files in the Library folders (they were whatever came with the Mac), and in that case there were no Eclipse errors, but the project could not be run (UnsatisfiedLinkError: no j3dcore-ogl in java.library.path)
Now that I've updated both of the JRE system library .jar files, the code has errors: Access restriction: The type '...' is not API (restriction on required library '/Library/Java/Extensions/j3dcore.jar')
What's the proper way to clean up all these locations so that the project only references one set of these .jars, and where should these .jar's be?
There is only one way to clean up: uninstall all those obsolete versions of Java3D provided by Apple ("whatever came with the Mac") and follow my instructions.
The extension mechanism has been removed from Java 1.9, relying on it is a very bad idea. Only use a carefully chosen "personal libraries folder" whose scope affects only your application and not the rest of the operating system.
If you need some help on Java3D, rather use its official forum.
I'm writing some code that uses the Subversion (SVN) Java bindings (JavaHL) directly (where JavaHL comprises native libraries and a thin Java wrapper). On Linux (Ubuntu 12.04) this is no problem: package libsvn-java installs the native libraries and \usr\share\java\svn-javahl.jar, so i just reference the latter and away I go.
On Windows, I know of no such clean packaging of the pair (JAR + native libraries) together. I was aware that SlikSVN contains a JavaHL implementation, but installing that seems only to install the native libraries (which it does put on the PATH). Is there anything that gives a clean package of the two? (If SlikSVN does package the JAR, it's in no place I expect, and a search of the whole drive finds nothing...)
As a workaround, I built the JAR file manually (details below which may be useful for people). But it seems that the 'match' of Java wrapper and native libraries is very precise: when I built a JAR from later SVN source code (instead of that matching my exact SlikSVN SVN version) as a test, I got fatal errors in the native code (EXCEPTION_ACCESS_VIOLATION). Perhaps I was unlucky but, if it is pretty sensitive, I'll need to provide a JAR library for every potential version of SlikSVN (and thus SVN) that users might install (or restrict their SlikSVN choices, or have some prone-to-error auto-build process which would need them to install a JDK). All bad options :-(
Manual Workaround (Bad!)
I had SlikSVN 1.8.10: svn --version reports version 1.8.10-SlikSvn-1.8.10-X64.
So I got the Java wrapper source from the tagged SVN release. (You can also get it from the
main site's source downloads.)
svn export http://svn.apache.org/repos/asf/subversion/tags/1.8.10/subversion/bindings/javahl/src
Compiling this (there are no dependencies) into a JAR, and using that, worked fine with the SlikSVN native libraries.
P.S. I know that I could use SVNKit to avoid having to do this, but I'm doing this precisely so as not to rely on SVNKit for licensing reasons (plus the JavaHL API is fine and reasonably high-level anyway, and there are other reasons to prefer using the 'official' native JavaHL implementation).
The WANdisco binaries should have JavaHL in them.
http://www.wandisco.com/subversion/download
Been a while since I used them myself (don't typically use Windows). But WANdisco has tools that depend on JavaHL so I can't imagine the Windows binaries are missing JavaHL.
[Question author edit to complete detail]
You need to install the (Windows) Subversion client (not SmartSVN), and make sure you check the box to add it to the Windows PATH. This stores the 'paired' JAR in the install directory (along with the native libraries). However, WANDisco only provide a 32-bit install (see this forum post) so this won't work on 64-bit Windows. In addition, the JAR only includes the Apache versions of the API, which were added for Subversion 1.7. If you're using the legacy org.tigris.subversion.javahl package API for compatibility with pre-1.7 SVN clients, you still need to build the JAR manually.
I'm working on a Java project that uses the JNI. The JNI calls a custom library that I've written myself, let's say mylib.dll, and that depends on a 3rd party library, libsndfile-1.dll.
When I run my program it crashes with
java.lang.UnsatisfiedLinkError: C:\...path...\mylib.dll: Can't find dependent libraries.
I've searched this site (and others) and I've tried a number of fixes:
I ran dependency walker. DW gave a couple of warnings -- that two libraries required by libsndfile, MPR.DLL and SHLWAPI.DLL, had "unresolved imports" -- but the DW FAQ said that these warnings could be safely ignored.
I fixed the method names in mylib.dll, as suggested here. The method names had somehow gotten mangled by the compiler, but I added linker flags and the dll method names now match those in my jni header file exactly.
I put all of these DLLs in the same directory -- the same directory as the .jar that calls them -- to ensure that they're on the right PATH.
No dice.
Does anyone have any idea what's going on?
I'm doing my development in Visual Studio 2010 on a MacBook pro (via Parallels). I'm doing my testing in Windows XP on a toshiba laptop.
I'm pretty sure the classpath and the shared library search path have little to do with each other. According to The JNI Book (which admittedly is old), on Windows if you do not use the java.library.path system property, the DLL needs to be in the current working directory or in a directory listed in the Windows PATH environment variable.
Update:
Looks like Oracle has removed the PDF from its website. I've updated the link above to point to an instance of the PDF living at University of Texas - Arlington.
Also, you can also read Oracle's HTML version of the JNI Specification. That lives in the Java 8 section of the Java website and so hopefully will be around for a while.
Update 2:
At least in Java 8 (I haven't checked earlier versions) you can do:
java -XshowSettings:properties -version
to find the shared library search path. Look for the value of the java.library.path property in that output.
I want to inform this interesting case, after tried all the above method, the error is still there. The weird thing is it works on a Windows 7 computer, but on Windows XP it is not. Then I use dependency walker and found on the Windows XP there is no VC++ Runtime as my dll requirement. After installing VC++ Runtime package here it works like a charm. The thing that disturbed me is it keeps telling Can't find dependent libraries, while intuitively the JNI dependent dll is there, however it finally turns out the JNI dependent dll requires another dependent dl. I hope this helps.
You need to load your JNI library.
System.loadLibrary loads the DLL from the JVM path (JDK bin path).
If you want to load an explicit file with a path, use System.load()
See also: Difference between System.load() and System.loadLibrary in Java
If you load a 32 bit version of your dll with a 64 bit JRE you could have this issue. This was my case.
Please verify your library path is right or not. Of course, you can use following code to check your library path path:
System.out.println(System.getProperty("java.library.path"));
You can appoint the java.library.path when launching a Java application:
java -Djava.library.path=path ...
Did have identical problem with on XP machine when installing javacv and opencv in combination with Eclipse. It turned out that I was missing the following files:
msvcp100.dll
msvcr100.dll
Once these were installed, the project compiled and ran OK.
When calling System.loadLibrary(), the JVM will look on the java.library.path for your native library. However, if that native library declares any dependencies on other native libraries, then the operating system will be tasked with finding those native library dependencies.
Since the operating system has no concept of the java.library.path, it will not see any directories you place on the java.library.path. Instead, it will only search the directories on PATH environment variable of the operating system. This is totally fine if the native library dependency is an operating system native library because it will be found on the PATH. However, if the native library dependency is a native library that you or someone else created, then it will not be found on the PATH unless you place it there. This behavior is strange, unexpected, and not well documented, but it is documented in the OpenJDK issue tracker here. You can also find another StackOverflow answer reinforcing this explanation, here.
So, you have a couple of options. You could either load each native library in the correct dependency order using System.loadLibrary(), or you could modify the PATH to include the directories where your native libraries are stored.
Short answer: for "can't find dependent library" error, check your $PATH (corresponds to bullet point #3 below)
Long answer:
Pure java world: jvm uses "Classpath" to find class files
JNI world (java/native boundary): jvm uses "java.library.path" (which defaults to $PATH) to find dlls
pure native world: native code uses $PATH to load other dlls
I found a great article by some friends at keepsafe that went through the same thing I did. It worked for me, so hopefully it helps you out as well! Have a read if you're interested (The Perils of Loading Native Libraries on Android) or just use
compile 'com.getkeepsafe.relinker:relinker:1.2.3'
and replace
System.loadLibrary("myLibrary");
with
ReLinker.loadLibrary(context, "mylibrary");
installing Microsoft Visual C++ 2010 SP1 Redistributable Fixed it
I used to have exactly the same problem, and finally it was solved.
I put all the dependent DLLs into the same folder where mylib.dll was stored and make sure the JAVA Compiler could find it (if there is no mylib.dll in the compilation path, there would be an error reporting this during compiling). The important thing you need to notice is you must make sure all the dependent libs are of the same version with mylib.dll, for example if your mylib.dll is release version then you should also put the release version of all its dependent libs there.
Hope this could help others who have encountered the same problem.
I had the same issue, and I tried everything what is posted here to fix it but none worked for me.
In my case I'm using Cygwin to compile the dll. It seems that JVM tries to find the JRE DLLs in the virtual Cygwin path.
I added the the Cygwin's virtual directory path to JRE's DLLs and it works now.
I did something like:
SET PATH="/cygdrive/c/Program Files/Java/jdk1.8.0_45";%PATH%
In my situation, I was trying to run a java web service in Tomcat 7 via a connector in Eclipse. The app ran well when I deployed the war file to an instance of Tomcat 7 on my laptop. The app requires a jdbc type 2 driver for "IBM DB2 9.5". For some odd reason the connector in Eclispe could not see or use the paths in the IBM DB2 environment variables, to reach the dll files installed on my laptop as the jcc client. The error message either stated that it failed to find the db2jcct2 dll file or it failed to find the dependent libraries for that dll file. Ultimately, I deleted the connector and rebuilt it. Then it worked properly. I'm adding this solution here as documentation, because I failed to find this specific solution anywhere else.
Creating static library worked for me, compiling using g++ -static. It bundles the dependent libraries along with the build.
place the required dlls in folder and set the folder path in PATH environment variable.
make sure updated environment PATH variable is reflected.
I was facing same issue with ffmpeg library after merging two Android projects as one project.
Actually issue was arriving due to two different versions of ffmpeg library but they were loaded with same names in memory. One library was placed in JNiLibs while other was inside another library used as module. I was not able to modify the code of module as it was readonly so I renamed the one used in my own code to ffmpegCamera and loaded it in memory with same name.
System.loadLibrary("ffmpegCamera");
This resolved the issue and now both versions of libraries are loading well as separate name and process id in memory.
I faced the same problem after migrating my CI into a new machine.
I was still facing it even after applying all the above solutions.
The problem was in my new machine, there was Microsoft Visual C++ 2010 SP1 Redistributable x86 installed in it. But my new machine was having 64-bit CPU and operating system. So the fix was that i just updated and installed the 64 bit version from here .
Go to http://tess4j.sourceforge.net/usage.html and click on Visual C++ Redistributable for VS2012
Download it and run VSU_4\vcredist_x64.exe or VSU_4\vcredist_x84.exe depending upon your system configuration
Put your dll files inside the lib folder, along with your other libraries (eg \lib\win32-x86\your dll files).
This question already has answers here:
How can I convert my Java program to an .exe file?
(16 answers)
Closed 3 years ago.
I'm wondering how to package a Java application into a native binary for Windows, Linux and Mac OS X.
I know Minecraft does this, but I can't figure out how. This is what'd I'd like to do:
From NetBeans (preferably) or Eclipse, build the three binaries automatically.
Include native libraries for OpenGL et. all.
Obfuscate my code if possible.
If there's some way to mimic the Minecraft auto-updater feature, that'd be totally awesome.
So, are there any tools available to do this for you, or do I need to write a large bulk of XML to accomplish this?
To make a native binary for Windows, you would use a tool like Launch4J. On OSX you could use JarBundler. Minecraft simply distributes the jar file for Linux. I'm not aware of a native binary packager for Linux.
You could also compile your Java code via GCJ but that's probably not what you want, as there are limitations and compatibility concerns there. The native bundlers like Launch4j and JarBundler simply wrap your jar file and use a real JRE to execute it.
As for integrating with NetBeans or Eclipse, you'll probably have to write your own ant build file, especially since the solution varies from one platform to the next.
If you are using Java 9, you can also use Java 9 Modularization & jlink to ship a zero-dependency native app.
There is also maven-jlink-plugin that could help here.
Take a look at GCJBuilder plugin for eclipse. Not sure if it supports cross compilation as the command GCJ compiler does.
If the app. has a GUI and can be distributed from a web site, look into Java Web Start. JWS is supplied by Oracle, and provides auto-update amongst many other features.
Note that JWS uses Jar files, so no conversion is necessary.
I've used JSMooth for this in the past: http://jsmooth.sourceforge.net/
As mentioned before, this wrapper just looks for a real JRE to run it - it does not come with a bundled JRE.