Executable Java JAR can't find file path - java

I am facing problem while running executable .jar file via java -jar my.jar. I've created a project which contains a .sh file under src/main/resources/ path. In the code i am referring it to execute as:
Process pb = new ProcessBuilder("src/main/resources/stacktrace.sh",pid, traceFilePath,timeInMin).start();
It works just fine when I run my application from Intellij but when I export it to executable jar file and try to run it complains:
Exception in thread "main" java.io.IOException: Cannot run program "src/main/resources/stacktrace.sh": error=2, No such file or directory
at java.lang.ProcessBuilder.start(ProcessBuilder.java:1048)

The path you used in your ProcessBuilder is relative to the current working directory. When you run your code from your source project the path exists, but when running the jar the current working directory is different as you are not running it from within your source project. Therefore when your code attempts to find "src/main/resources/stacktrace.sh" it fails to find it.
For example, maybe your source project is located in:
/myCodeProject
So when you run your project your path resolves to:
/myCodeProject/src/main/resources/stacktrace.sh
When you run your jar perhaps you're running from somewhere like:
/opt/app/myApp
Therefore your path resolves to:
/opt/app/myApp/src/main/resources/stacktrace.sh
and it is this path which does not exist.
EDIT:
As requested I am adding some ideas regarding how to correct the problem. However, your requirements are not clear as to where you want the file to live. Should it be outside the jar? Inside the jar? If it's outside will it be located in a specific constant path or relative to the jar?
There's the obvious fix: put the file in the expected path so that it will be found.
The other obvious fix: change the relative path so that it points to where the file is actually located.
Build your jar such that the file is included inside the jar and use one of these methods to access it. Note that you may not be able to directly run the file, but you could read its content and generate an external temporary file and run that.

Related

Running an external program from an executable Jar

I have created a simple SWING gui for a cmd program someone else developed. To run this program I execute this line:
Process convertProcess = Runtime.getRuntime().exec("jlyt\\prog\\com_win\\jlyt.bat " + selectedFiles.getName());
The jlyt folder is in the same folder as my src folder (I am using IntelliJ).
When running via IDE everything works great, but not when I run the jar I created. I have tried running it from the directory it was saved to by IntelliJ as well as from the directory of the jlyt folder.
I did not add the external program (inside the jlyt folder) to my jar since it is very heavy. I want my jar to be distributed along side the original program and not to contain everything.
Any idea how I should build my jar?
Thanks.
I see why you put /jlyt in /src, it serves as a convenience within the IDE. /jlyt will get copied as a resource into /bin/classes, or whatever the IDE target is, and that allows everything to work from the IDE.
When you JAR your application, /jlyt is typically added to the JAR; however, it is not accessible to Windows. I assume you are placing a copy of /jlyt in the same folder as the JAR when you attempt to run.
As a first step, in a terminal, set the current directory to the folder containing the JAR and /jlyt. Since you are specifying a relative path in your exec(), that should be sufficient for everything to run.
You can also try creating a shortcut to the JAR, since it is executable, and set the working directory to the folder containing the JAR.
You have to use a relative path based on the place where jlyt.bat is according to your jar file.
e.g. use "./" or "../" to navigate the directory tree up.
The location of the JAR file is only relevant for starting the JAR. The working directory must be the directory that contains the jlyt folder, since you are using 'jlyt\...' as path to the executable.
Example, lets suppose following directory structure:
somewhere
project
gui
appl.jar
jlyt
prog
...
working directory must be 'project' and the JAR will then be referenced as 'gui\appl.jar
C:\somewhere> cd project
C:\somewhere\project> java -jar gui\appl.jar
Also be sure to wait for the convert process to terminate (e.g. convertProcess.waitFor()) before exiting your application/java - I believe that any running external process is killed when the Java Virtual Machine is closed!
Hint in documentation of Process:
As of 1.5, ProcessBuilder.start() is the preferred way to create a Process.

How to make jar files that draw from a source folder

I've been wanting to make executable jar files with java lately. When executing my code with Eclipse it works perfectly. But when I use Eclipse to export the same code as a runnable jar, Most of my jars work except the ones that draw from separate source folders.
The jar will be made but when launched it will try and open and then just say to check to console for possible errors. I try and run the jar through the console with the command "java -jar test.jar". and It says it cannot access the jar. Any Ideas? Btw Im on a macbook pro osX. Thank you!!
picture of where my files are within eclipse
If you have a file you want to store in a jar and access from there, you don't really have a Java File any more. Look at Class.getResourceAsStream() and Class.getResource() - the first can give you an InputStream to the (used-to-be) file, the second returns a URL and can be used for things like images. Note that the file being accessed can be accessed relative to the package/folder location of the class or relative to a classpath root (by putting "/" at the front of the resource name ("/resource/funny.jpg")).
When you execute the jar from a command line, be aware that you have a thing called the "default directory"; it is a folder in which your commands execute by default. If your jar is not in the default directory, you have to specify a valid folder path to your jar to execute it.

Running and Importing files folder along with runnable jar in eclipse

I have a project in eclipse where all my source code is under mbl/src. I am exporting this code as a runnable jar. I have got another folder under mbl/files which contains some of the properties files.I want to export these files also but eclipse doesnt give any such option. I have put the mbl/files under add class folder in build path options but still I am facing similar issues. I have also put the files folder directly under src folder but still it is not able to access it.I am using following options in commandline.
java -jar myprogram.jar arg1
It gives this error:
Unable to find files/text1.properties
text1.properties is under mbl/files/text1.properties
and is referred in the following manner from main class:
FileInputStream fs=new FileInputStream("files\\text1.properties");
Resources in bedded within Jars, need to be read via the Class.getResource(...) method.
This method returns an URL object, from which you can obtain an InputStream

FileNotFoundException while running as Jar - Java

I have written my java codes using eclipse and iam reading a file and processing the codes. The key.txt is present in the same folder as src .
BufferedReader br= new BufferedReader(new FileReader("KEY.txt"));
Now after i compile the jar and place both the jar and file in the same folder and execute iam getting FilenotFoundException. The program works if i run inside Eclipse reading the file perfectly.
The jar file and the key.txt always have to be in the same folder.
Please let me know how can I solve this issue of FilenotFoundException.
The code you have opens a file in the current working directory, which is the directory where you started the Java process from.
This is completely unrelated to where the jar file is located.
How do you execute the jar file?
If the key file is right next to the jar file, this should work:
java -jar theJar.jar
But this will not (because the path to the key is now "test/KEY.txt" ):
java -jar test/theJar.jar
When you run a program in Eclipse, the current working directory is (usually) the project root folder.
An alternative to consider (if the file does not need to be edited by the user) is to put the key file into the jar file. Then it will not get lost, and you can load it via the classloader.
Another good option is to have the user provide the path to the file, via command line parameter or system property.
Or make a batch file / shell script that makes sure that you are always running from the proper directory.
I think you should put these files with class file of the running class, because the current directory is the directory in which the class file is stored, not the source java file.

Load files External To The Distribution Jar

I have written a Java program which I package and run from a JAR file. I need to have some user-changeable configuration files which are simply text lines of:
key = value
format. To load these files I used the class described here. When I run my program through Netbeans IDE all works fine as I have included the directory where I store the configuration files in the Project properties.
The problem comes when I build my application into a JAR file. As I want the configuration files to be user-editable I keep them OUTSIDE of the JAR but in the same directory but now when I run my application from the command line it cannot find the configuration files. If I manually add the files to JAR file at the ROOT folder then all is well.
So how can I tell Java to look outside of the JAR for my loadable files? The -classpath option has no effect.
That's because the way you are loading them requires that they be inside the .jar when running from a jar, or inside the project directory if not; it's relying on the classloader to tell it where to find the file.
If you want to open a file outside the .jar, you need to just open it as a File and read it in.
One of the ways we've approached this is to take the external filename as an option on the command line (e.g. java -jar myJar.jar -f filename). This allows you to explicitly state where the file is located. You can then decide whether or not to also look in a default location, or inside the .jar if the file isn't specified on the command line.
I resolved it by referring to this question. I Added the current directory to the MANIFEST file of the jar and it works.
Why is the -classpath option ignored in this case I wonder? Security?
I had the same problem and saw your post, but the answer in the end, was simple.
I have an application deployed via Java Webstart and am building it in Netbeans 7.3.
I have a properties file config.xml that will be updated during run time with user preferences, for instance, "remember my password".
Hence it needs to be external to the jar file.
Netbeans creates a 'dist' folder under the project folder. This folder contains the project jar file and jnlp file. I copied over the config.xml to the dist folder and the properties file was loaded using standard
FileInputStream in = new FileInputStream("config.xml");
testData.loadFromXML(in);
in.close();

Categories

Resources