How to distribute native libraries with jar? - java

This is the directory structure I want to create when I finally deploy my software. It is a Java chat client with a webcam feature and for the webcam I am using LTI-CIVIL.
I was told that I can not use DLLs right from the JAR and I will have to extract them somewhere. All cool. However, what I cannot get my head around is how can I make it work ?
LTI comes with a large number of files in the zip that they provide on their site. If you are using Eclipse, you need to set the path to appropriate folder for the native library. However, this limits me to Eclipse and prevents me from distributing the JAR to my friends. Apparently, I will now have to point to that folder, and maybe load the files, programatiaclly
I am a beginner so if someone can download LTI-CIVIL, have a look at the directory structure and let me know how to achieve what I am trying to do then that would be highly appreciated.
AFAIK, for my 32 bit Windows, I need to point to native/win32-x86 folder.
What I am trying to do is to load the appropriate files in memory so that I can provide webcam facility. I want to avoid installers and simply give a zip file with a directory structure mentioned above so that people can extract, run the jar file from the folder and start chatting.
Clarification: I am trying to send a library with jar file and not in jar. I know extracting and using dlls from jar is tough

I'm assuming that it is not your own code which loads the native libraries (System.load), and they are loaded by a third-party jar (lti-civil).
In this case you have to set the enviroment variable LD_LIBRARY_PATH appropiately before lti-civil attempts to load the native libraries.
Either:
With a launcher script (e.g .bat), set the variable before running java, or set the system property, something like:
java -jar your.jar -Djava.library.path=/path/to/native/folder
At runtime. In the entry point of your program.
This is a bit "hackish", but it works.
Check this link for example:
http://nicklothian.com/blog/2008/11/19/modify-javalibrarypath-at-runtime/
Since you do not know the exact path beforehand, in both cases you will have to also find the correct path where the native libraries are located.
If the path to the libraries is relative to the path of the jar/launcher, then find the current path of the executable:
in a .bat launcher:
Get Directory Path of an executing Batch file
in java:
How to get the path of a running JAR file?
And then that, you can assume the libraries are located in path relative to this (../native), just calculate the path (and maybe expand it to an absolute path).
After you have calculated the absolute path, set the enviroment/system property as described in the first part of the answer.

Related

Where should i place my files in order to be able to access them when i run the jar?

I store some objects in files and everything works fine in Netbeans console. But when i run the JAR through the command line (java -jar myapp.jar) i get this:
Where should i place the files in order to be able run the app through the command line?
The answer will depend on if you want to write to the files or not...
You could...
Ensure that the files are placed relative to the Jar file and use a relative path. The problem with this is if the execution context is not the same directory as where the jar and files are stored, you won't be able to find them again...
This will also be dependent on your build process to make sure that any required files are placed copied to the build location of the Jar
You could...
Place the files within a well know location, for example, on Windows you could use {user.home}/AppData/Local/{application name} or on Mac you could use {user.home}/Library/Application Support/{application name} and place the files here, then you could use an absolute path to the files
This likely becomes an installation issue, as you need to ensure that any required files are copied to the required location when the application is installed.
If the files are auto generated at runtime, then you just need to make sure the directories exists and make them if they don't
You could...
Store the files within the Jar context (AKA embedded resources), the means by which you do this will depend on your IDE and build process, for example, in Netbeans, you can copy files into the src directory of your project and they will automatically be included in the resulting Jar file. I believe that Eclipse can work the same way. However, if you're using Maven, you will need to place the files into the resources directory instead.
You would then access these resources using Class#getResource or Class#getResourceAsStream depending on your needs.
This will make the resources read-only however.

MATLAB: importing java libraries

I have the following lines in my MATLAB code:
javaaddpath('C:\Users\localadmin\SkyDrive\IdeaProjects\DrawModels\out\artifacts\DrawModels_jar\DrawModels.jar')
javaaddpath('C:\Users\localadmin\SkyDrive\IdeaProjects\DrawModels\out\artifacts\DrawModels_jar\itextpdf-5.4.1.jar')
I then go on to instantiate some JAVA objects defined in the files.
I would like to copy the JAR files to where the .m file sits, and then write the following instead (i.e. I want to use a relative path rather than an absolute one).
javaaddpath('DrawModels.jar')
javaaddpath('itextpdf-5.4.1.jar')
However, the MATLAB path doesn't seem to apply to javaaddpath and so the JAR files do not get loaded.
Any ideas as to how I may achieve a relative path addressing of JAR files?
The background for this is I want the MATLAB code to run both on Windows and Linux, i.e. whereever it is unpacked. The user may unpack it in any folder he chooses, so I don't want a hard-coded path in the source.
Any help appreciated.
You can use mfilename to find the path of the running M file, which you can concatenate with the JAR file name like,
javaaddpath(fullfile(fileparts(mfilename('fullpath')),'DrawModels.jar'))
That must go in the M file with which you would like to add the Java class to MATLAB.

Preparing JNA for use in Eclipse

Background:
I'm doing machine learning research, and want to use the FANN library to construct neural networks. The source code is written in C, but I need it wrapped so that I can use it with a lot of Java classes we've created.
Question:
The website provides a link to an already well received wrapper software called fannj. Its dependencies is the FANN library source code and JNA. I've never done wrapping before so JNA is brand new to me. The github homepage for the code mentions "you must set the jna.library.path system property to the path of the FANN Library". I'm currently in the process of trying to do this in Eclipse on Mac OS X. A friend of mine mentioned to me earlier that it means I have to pass the location of the FANN library as argument to the virtual machine, but he only showed me how to do this via the shell. I never actually ran this command from the shell, because I wasn't sure how it would conflict with whatever configurations I do in Eclipse later.
How do I set the jna.library.path in Eclipse? The JNA directory is huge, and I don't know where the actual executable is. My friend suggested I modify its run configuration through use of the argument tab, but like I said I don't actually know where the executable is. All I have is the large uncompressed jar file. How can I go about getting it set up in Eclipse?
You don't set in an IDE, just insert in some piece of code that is called BEFORE JNA is called, something like this:
System.setProperty("jna.library.path", "path you need");
Where System is java.lang.System. As for what path you need it must be the path that contains compiled dynamically linked FAAN library (a *dll).
Or just forget that alltogether and dump FAAN (*dlls, *so..) into Windows/system32 (or other appropriate folder on system you use) and these dll's will be on default search path.
Two allow Eclipse to use JNA, all you need to do is to put two jar files in Eclipse's Java Build Path, jna.jar and platform.jar. That's it.
To do this for an individual project, right click on the project in the Package Explorer, click Properties (at the bottom), click Java Build Path on the left, then the Add External Jar files. Browse to the directory with your JNA files and add those two files.

JNI-wrapped library seeks out wrong working directory -- how to circumvent?

I am using JNI to wrap a few native functions in a closed-source PDF library. It has an dependent fonts directory which must be in a subfolder of the calling application's directory. In my experience, it is standard to seek based on the current working directory. Thus, the problem.
When loading the JNI code into a Java application, the current working directory is correct. However, the calling application's directory is java.exe's bin directory. I have verified that putting the dependent fonts folder in C:\Program Files (x86)\Java\jre6\bin folder works as expected.
The library seems to be using a C++ GetCommandLine() call, or something similar to determine where the fonts directory should be. Obviously, this is an unacceptable solution.
I'd like to avoid calling an external EXE. But the only workarounds that I've come up with are:
Compile an EXE, place in Java project directory, and use Java's Runtime.exec() to execute. (this does work)
Make JNI code launch a separate process which does the same as above (gains nothing but more complexity)
Any ideas on how I can circumvent this problem? When Java applications are compiled as a runnable JAR, is the resultant command line still the JRE's C:\Program Files\...java.exe?
A Java executable maker can create an executable *.exe from your Java application without any native coding or compiling. You can put that executable, the jar files, the fonts and other application dependencies into a single install directory.
Exe4j is one of the executable makers that will support this, for Windows. It does not require any assumptions about the current working directory. This is important in the frequent case where you have no control over what the working directory is when the application is launched.

java, System.loadlibrary("someDLLFile") gets unstatisfied link error

I have written some JNI hooks into a C++ library and created some DLL files for my java server project. Lets say the DLL and jar files are in the same folder under "C:/server"
I am accessing these DLL files using:
System.loadLibrary("someDLLFile");
in the class that needs the C++ code.
The problem I am running into is when I run this server on my own machine, everything works fine regardless of where I place the "server" folder. But when I give it to a colleague to test, they continually get:
java.lang.UnsatisfiedLinkError no someDLLFile in java.library.path
I want to have the DLL files live in the same folder as the jar files and would prefer not having someone configure their PATH variable.
Why does System.loadLibrary() work on my own machine regardless of the folder's location, but not on another computer?
It works because the DLL (or a DLL it depends on, i.e. msvcr90.dll or something) are in the PATH on your machine, but not on the other one.
Either set PATH env-var or the java.library.path property to contain the dir with your file, or store your dll where java finds it by default (Many options here, depending on deployment strategy and platform).
One option is to specify the directory in the command line when you start the VM:
java -classpath C:\server -Djava.library.path=C:\server somePackage.Main
Another option is to use System.load instead of System.loadLibrary.
URL url = Test.class.getResource("someDLLFile.dll");
String f = new File(url.getFile()).getAbsolutePath();
System.load(f);
The downside is that your program is now dealing with platform-dependent directory names, file extensions etc.
I'm not sure if this is helpful or not, but I have included the following in some projects:
http://forums.sun.com/thread.jspa?threadID=707176
To load native libraries.
And then I just load the bin directory
String binPath = new File(".").getAbsolutePath()
+ System.getProperty("file.separator") + "bin";
addDir( binPath );
It works pretty well.
But Again, I'm not sure if this is the case or not.
Try downloading depends.exe to see if the dll depends on other dlls on the system or not. If it does, then check the other machine, whether such dlls are present or not in Path.

Categories

Resources