Provide DLL path to System.loadLibrary on export - java

I want to export my Java application which uses JNI interface, and loads a DLL via System.loadLibrary("dllName").
The DLL file is present inside Java Project folder as well as in C drive, one of places where JVM will search for DLL at runtime.
Problem: When I export this project out as a Jar and give it to client, client should be able to run the tool without hassles of entering a Dll file. I can't think of accomplishing this via alternative way; to provide absolute path by using System.load("path:\\") because I don't know where the user would download the Jar file to.

The following snippet will load the DLL regardless of the working directory if it's loacted in the same directory as the JAR file:
CodeSource codeSource = MainClass.class.getProtectionDomain().getCodeSource();
File jarFile = new File(codeSource.getLocation().toURI().getPath());
File parentDir = jarFile.getParentFile();
File dllFile = new File(parentDir, "my.dll");
System.load(dllFile.getPath());

You need to put the DLL in the same path that the application is running, in a system path or add its path the PATH variable before starting the app.

Have a look at Runtime.load.
Loads the specified filename as a dynamic library. The filename
argument must be a complete path name. From java_g it will
automagically insert "_g" before the ".so" (for example
Runtime.getRuntime().load("/home/avh/lib/libX11.so");).
First, if there is a security manager, its checkLink method is called
with the filename as its argument. This may result in a security
exception.
This is similar to the method loadLibrary(String), but it accepts a
general file name as an argument rather than just a library name,
allowing any file of native code to be loaded.
The method System.load(String) is the conventional and convenient
means of invoking this method.

Related

How to find the path of a file local eclipse project

I have created a .txt file in my Eclipse Java project, and I want to find out the path to it so I can use it for a Scanner. I do not want to find out the path on my local drive, as I will be planning to share the program to someone else, and they will have a different folder structure, rather a path that can be used on anybodies machine.
Here is the code:
this.file = new File("<insert path here>");
you can use :
= new File("Build Path"); (your .java file exist in your build path)
The build path is used for building your application. It contains all of your source files and all Java libraries that are required to compile the application.
In eclipse, the default behavior is for the Java system property user.dir to be set to the project directory. This is what dictates where the "root" of File operations is. So if you created a file test.txt in the root project directory, you should be able to access it with new File("test.txt").
However, as Andrew Thompson mentioned in his comment, the more correct method would be using embedded resources.
Try one of These:
1.
System.getProperty("user.dir");
2.
File currentDirFile = new File(".");
String helper = currentDirFile.getAbsolutePath();
String currentDir = helper.substring(0, helper.length() - currentDirFile.getCanonicalPath().length());//this line may need a try-catch
I have not tested it just found while googling

Using relative path in a maven project

I have a maven project with these standard directory structures:
src/main/java
src/main/java/pdf/Pdf.java
src/test/resources
src/test/resources/files/x.pdf
In my Pdf.java,
File file = new File("../../../test/resources/files/x.pdf");
Why does it report "No such file or dirctory"? The relative path should work. Right?
Relative paths work relative to the current working directory. Maven does not set it, so it is inherited from whatever value it had in the Java process your code is executing in.
The only reliable way is to figure it out in your own code. Depending on how you do things, there are several ways to do so. See How to get the real path of Java application at runtime? for suggestions. You are most likely looking at this.getClass().getProtectionDomain().getCodeSource().getLocation() and then you know where the class file is and can navigate relative to that.
Why does it report "No such file or dirctory"? The relative path should work. Right?
wrong.
Your classes are compiled to $PROJECT_ROOT/target/classes
and your resources are copied to the same folder keeping their relative paths below src/main/resources.
The file will be located relative to the classpath of which the root is $PROJECT_ROOT/target/classes. Therefore you have to write in your Pdf.java:
File file = new File("/files/x.pdf");
Your relative path will be evaluated from the projects current working directory which is $PROJECT_ROOT (AFAIR).
But it does not matter because you want that to work in your final application and not only in your build environment. Therefore you should access the file with getClass().getResource("/path/to/file/within/classpath") which searches the file in the class path of which the root is $PROJECT_ROOT/target/classes.
No the way you are referencing the files is according to your file system. Java knows about the classpath not the file system if you want to reference something like that you have to use the fully qualified name of the file.
Also I do not know if File constructor works with the classpath since it's an abstraction to manage the file system it will depend where the application is run from. Say it is run from the target directory at the same level as source in that case you have to go one directory up and then on src then test the resources the files and finally in x.pdf.
Since you are using a resources folder I think you want the file to be on the classpath and then you can load a resource with:
InputStream in = this.getClass().getClassLoader()
.getResourceAsStream("<path in classpath>");
Then you can create a FileInputStream or something to wrap around the file. Otherwise use the fully qualiefied name and put it somewere like /home/{user}/files/x.pdf.

Sharing a Java Object Stream

I've got a project to do with 2 other classmates.
We used Dropbox to share the project so we can write from our houses (Isn't a very good choice, but it worked and was easier than using GitHub)
My question is now about sharing the object stream.
I want to put the file of the stream in same dropbox shared directory of the code.
BUT, when i initialize the file
File f = new File(PATH);
i must use the path of my computer (C:\User**Alessandro**\Dropbox)
As you can see it is linked to Alessandro, and so to my computer.
This clearly won't work on another PC.
How can tell the compiler to just look in the same directory of the source code/.class files?
You can use Class#getResource(java.lang.String) to obtain a URL corresponding to the location of the file relative to the classpath of the Java program:
URL url = getClass().getResource("/path/to/the/file");
File file = new File(url.getPath());
Note here that / is the root of your classpath, which is the top of the directory containing your class files. So your resource should be placed inside the classpath somewhere in order for it to work on your friend's computer.
Don't use absolute paths. Use relative paths like ./myfile.txt. Start the program with the project directory as the current dir. (This is the default in Eclipse.) But then you have to ensure that this both works for development and for production use.
As an alternative you can create a properties file and define the path there. Your code then only refers to a property name and each developer can adjust the configuration file. See Properties documentation.

Dynamically finding the destination of the project

I can use:
getClass().getClassLoader().getResource("").getPath());
To dynamically get the path of the Class files in my project.
But I need to get the path dynamically for the home directory of the project. I can't do this statically, like this:
File file = new File("C:\Users\etc...");
Because the destination of the project can change from one computer to the next. I need to call a file in the project's home directory. How do I do that dynamically. It would be similar to how I did it in the beginning of this question, but it can not be just for Classes.
Any idea?
There's no such thing as a "java project" in Java. If you know where your class files are in relationship to whatever directory you're trying to locate, you can use the path you obtained in your first example:
Url classUrl = ...
File resourcePath = new File(classUrl.toUri());
File rootDir = resourcePath.getParentFile().getParentFile().getParentFile();
or
File rootDir = new File(resourcePath.getPath() +
"/../../../".replace("/", File.separatorChar));
Of course, this will only work as long as the files are actually on the file system; if they're in a jar, you'd need to locate the jar file instead.
But this is usually not something you want to do. It's a better practice to configure a sandbox for your application by passing them to your application as command-line arguments or environment variables. In some cases, it's also useful to use the pre-defined System properties such as user.home, user.dir, and java.io.tmpdir.

Calling a path in java method

I have a small problem calling a path(that has the python file, that I need to run) in the following code:
Process p = Runtime.getRuntime().exec(callAndArgs,env,
new java.io.File("C:\\Users\\Balkishore\\Documents\\NetBeansProjects\\Testinstrument_Rest\\build\\web"));//excuting python file
As it can be seen from the above code, the python file is called using the path specified in java.io.file function. But it is very specific, as it can be run only in my computer. How can i make it generic, so that it is possible to run this piece of code in any computer?
Any help would be very much appreciated.
Put your python script to the location relative to your working directory and use relative path. Alternatively use configuration file or property to read the path from.
If this file is already exist in the app then you need to do
ServletContext.getRealPath("/");
which will give you the path to web root now from here you need to move relatively to reach to your file
If this is an external file
put it in ${user.home}/appname/
String filePath = System.getProperty("user.home")+File.separator+"APP_NAME"
and instruct your users to put the file in this path, or read the path from some configuration file (.properties, .conf)

Categories

Resources