Best to way execute a file internal to a java project - java

Suppose my project structure is:
/project
/src
/java
Util.java
/cpp
/bin
a.out
I'd like to execute a.out from within Util.java without hard-coding any absolute paths in my java file. What's the best way to go about doing this?
EDIT -- Here's what I ended up doing: I happen to be using autoconf as most of the code is c++. I defined a substitution variable like AC_SUBST([project_root], [$(pwd)]) in configure.ac and substituted it in a Config.java.in file.

Perhaps using a properties file to be loaded on deployment/running time depending on the nature of your app.
More about its use in this thread
How to use Java property files?

You're file path to a.out could be ../bin/a.out. And then execute the file using that path.

Below is some pseudo code that might help you.
// look for the executable in the current working directory
File executable = new File("a.out");
if( executable.exists()){
System.exec() .... etc
} else {
String location = YourMainClass.class.getProtectionDomain().getCodeSource().getLocation();
// write code to form a path name to the a.out based on the location of .jar file
}

Related

Get project directory from java classes

I have a problem with System.getProperty("user.dir") giving different directory when run by IDE and when I manually compile & run it in cmd. My thing is this, I have project structure like this:
project
- exports
- src
- main
- java
- Main
- file1
- file2
One of the args in main method is the name of one of those 2 files, that I then access.
When I configure my run in IDE it works like a charm - the directory I get is C:\Users\**\**\**\project and it is able to read and write to the file.
But when I compile it in cmd javac Main.java and then run it, I get C:\Users\**\**\**\project\src\main\java and because of that, I am unable to access the file without having to modify the path.
My question is, is there like a golden way, that would work for both these cases, without me having to alter the returned path?
EDIT:
For clear understanding, I know what System.getProperty("user.dir") returns, but my question was, if it is possible to get the same result somehow with using Path or if I have to get the path and edit it, so that it will end in project directory?
in IDE I get: C:\Users\petri\Desktop\CZM\bicycle-statistics
in cmd: C:\Users\petri\Desktop\CZM\bicycle-statistics\src\main\java
I want to get the same path in cmd, that I got in IDE.
I tried using Paths.get("").toAbsolutePath(), but it is the same thing.
So, what I did is this:
Path path = Paths.get("").toAbsolutePath();
while (!path.endsWith("project")) {
path = path.getParent();
}
And it works, but I am trying to ask, if there is some more elegant way, because I will have to defend my solution in front of my supervisor.
Normally your IDE will build source files in src/main/java and write the class files out to some other directory, like target/classes.
If your IDE built the project that way, then you can run it from the command line by switching to your project directory (cd C:\Users\**\**\**\project using your example) and then running:
java -classpath target/classes Main
assuming that target/classes is where your IDE put the files. If you really do have the class files in the source directory, then use -classpath src/main/java.
If you always run the program from the project directory, then you can assume within the program that the current directory is the project directory. You don't even have to use user.dir then, just use relative path names for everything, e.g., path/to/whatever.dat will automatically resolve to C:\Users\**\**\**\project\path\to\whatever.dat.
One of the args in main method is the name of one of those 2 files
Then make sure you enter the name correctly.
E.g. if the current working directory is the project folder, then name file1 will refer to the file1 file. If the current working directory is the java folder, then the argument to the program needs to be ..\..\..\file1.
That is because you give relative file names, which means they are relative to the current working directory.
Alternatively, give a fully qualified name, then the argument will be the same, regardless of what the current working directory is:
C:\Users\**\**\**\project\file1

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.

How to get the absolute path of the executed jar?

How do I get the location of the executed jar? I found a lot of solutions but none of them work for me. When I run them in my IDE everything is fine. As soon as I build a jar file and run it with java -jar myapp.jar the output is like /.../myapp.jar!/foo/bar
I will run the code in myapp.jar - not in any library.
Location of jar: /home/me/dev/myapp/myapp.jar
Expected output: /home/me/dev/myapp/
I don't want the working directory as I would get with System.getProperty("user.dir");
Why I want to do this:
I want to store and load a file beside the actual jar. Like
/home/me/bin/myapp/myapp.jar
/home/me/bin/myapp/license.key
I want to avoid storing the file into some generic folder like System.getProperty("user.home");. And I don't want to store the file within the jar file.
java.nio.file.Paths.get(".").toAbsolutePath() will return absolute path to current directory.
I use something along these lines:
[YourClass].class.getProtectionDomain().getCodeSource().getLocation().getPath()
Regards

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)

Path resolution in eclipse package structure

This is a very simple question for many of you reading this, but it's quite new for me.
Here is a screenshot for my eclipse
When i run this program i get java.io.FileNotFoundException: queries.xml (The system cannot find the file specified) i tried ../../../queries.xml but that is also not working. I really don't understand when to use ../ because it means go 1 step back in dir, and in some cases it works, can anyone explain this? Also how can I refer to queries.xml here. Thanks
Note: I might even use this code on a linux box
I assume it is compiling your code into a build or classes folder, and running it from there...
Have you tried the traditional Java way for doing this:
def query = new XmlSlurper().parse( GroovySlurping.class.getResourceAsStream( '/queries.xml' ) )
Assuming the build step is copying the xml into the build folder, I believe that should work
I don't use Eclipse though, so can't be 100% sure...
Try
file = new File("src/org/ars/groovy/queries.xml");
To check the actual working directory of eclipse you can use
File f = new File(".");
System.out.println(f.getAbsolutePath());
You could try using a property file to store the path of the xml files.
This way you can place the xml files in any location, and simply change the property file.
This will not require a change/recompilation of code.
This would mean you will only need to hardcode the path of the property file.
If you prefer not hardcoding the path of the property file, then you could pass it as an argument during startup in your server setup file. (in tomcat web.xml). Every server will have an equivalent setup file where you could specify the path of the property file.
Alternatively you could specify the path of the xml in this same file, if you don't want to use property files.
This link will show you an example of reading from property files.
http://www.zparacha.com/how-to-read-properties-file-in-java/

Categories

Resources