Getting the location of a folder next to my .jar file - java

In a program I am making, I need to access images in a folder placed alongside it. The program works fine when I run it with Eclipse, but when I export it to a .jar file, it does not get the location of the folder properly.
File roomF = new File("Assets/Rooms/1/0.png");
In the IDE, roomF refers to the correct location:
C:\Users\[Username]\Desktop\Eclipse Java\[Project name]\Assets\Rooms\1\0.png
However, in the .jar file, it refers to this:
C:\Users\[Username]\Assets\Rooms\1\0.png.
How can I fix this?

You should not have resources outside of your JAR or dependencies that need a local path in order to work. Create a resource folder in your project and load the file from there.

There are two solutions to this:
Place your JAR at:
'C:\Users[Username]\Desktop\Eclipse Java'
This way, when you are accessing Assets/Rooms/1/0.png, it points to the correct location.
Make a folder where you will place your JAR everytime. Create the path 'Assets/Rooms/1' in the folder and place your file 0.png there, hence you wouldn't be needing to place your JAR each time you make a new one as said in step 1.

Related

Is the relative path for a java project different for Intellij and cmd?

I have a java assignment, and at a specific point, we have to create a new folder and write some text files there. The issue is, when testing my code on Intellij, it works fine, but when testing it on cmd, I need to change it a tad bit?
My project structure:
.../project/src/greedycomparisons // greedycomparisons is the file where I'm creating the dir from
.../projct/data // the directory I want to create, to have my text files in
More specifically:
I'm trying to create the new subdirectory from a file I have inside my src folder. Therefore, the thing I tried first was:
File directory = new File("./data/");
if (!directory.mkdir()) dosth; // nothing happens on first call
/* making the String I want as my file's name, say string */
File file = new File(directory, string);
Which works fine (on Intellij), creating the subdirectory (and the files later on) exactly where I want them to. And then, likewise, I try accessing the files I made there from another file in my src folder, by again using "./data" before the name of the file I was trying to access, which again works as expected on Intellij.
But when I tested this on cmd, I need to change the directory name to "../data" in order for the code to work, which in turn does not work on Intellij (specifically giving me a "The system could not find the path specified" error) when I change it to that. Given that I have to submit it as an assignment and I don't want any ambiguity in regards to my files, is there something more "universal" that I can try, so my code works regardless?
If you check your IntelliJ configuration, by clicking at the top where you have the name of the file you are executing, you can click on Edit Configurations, and you will see one of the fields you can configure, called "Working directory".
IntelliJ is smart enough to set it to your project folder, outside the /src folder, because it is not good practice to write data inside your /src folder which should only have source files, unless they are resources you want to commit with your code.
On the other hand, when executing it from cmd, your working directory is just where you are trying to run the compiled program from. You haven't specified in which folder you are in when doing so, but most probably you are inside some subfolder that has the classes, which is why you needed to do the ...
If you package your classes in a .jar file, the way IntelliJ made it should work. If you run your .jar file with java -jar myjarfile.jar and the ./data folder is at the same level, then it would work.

How to give relative path in a executable jar?

I have a Spring app that I am deploying as a .jar.
The app has to write to a folder located in /src (precisely /src/main/resources/patches). I have this path directly in the code.
In application.properties: PATCH_DIR = src/main/resources/patches
The app has to also read a json file from src/main/resources/myJson.json, the path also being directly written in the code.
Prior to deploying, while running from the IDE everything goes well, the app sees the file and the folder and reads and writes correctly.
After building the .jar the paths change, the file is located in myJar.jar/BOOT-if/classes/myJson.json and the folder is respectively in myJar.jar/BOOT-if/classes/patches.
How can I specify these paths in the code in a way that even after building the jar they stay relevant to my application?
Edit: I can specify the path of the file as: PatchApplication.class.getClassLoader().getResource("myJson.json").getPath();
This should solve the problem, as the path is relative to the class and not to the root of the project, but it does not improve anything.
You should specify a path in your file system,instead of the path inside a .jar.When you run your app ,it would access the given path.
generally all the classes goes to classes folder in jar.
all the classes ending after src/main/java goes to /classes/ folder
and similarly all the resources file
Eg. your source folder have src/main/java/com/mypack/ABC.java than you will find this in jar as /classes/com/mypack/ABC.class .
Try using /classes/patches and /classes/myJson.json.
This should work

Java get path of executing jar without .jar file

I am trying to export my app into jar using intelij Idea artifacts. I export everything except for resources (14,5GB is in my opinion too much for .jar file) so I have put /res folder inside same folder as jar.
Right now my structure looks like this:
/SAR.jar
/res/colors/
/res/icons/
/res/map/
However I cant access this resources. I am using the following code to get path:
dir = new File(getClass().getProtectionDomain().getCodeSource().getLocation().toURI().getPath() + "/res/icons/");
It works when running from IDE and it prints correct location. But when I build an artifact and run it through cmd I get the null pointer and it prints this path: D:/JavaProject/SAR/out/artifacts/SAR_jar/SAR.jar/res/icons. But my resources are not inside jar file they are only in same directory.
Any ideas? I have done only android projects in path and I simply cant get this resources system with jars to work.
Thanks in forward
You are trying to access the ressources with a path dependent of your source code location, which is obviously not the case since you separated the code (or bytecode in the case of the jar) and the ressources. You must access them with a path relative to the jar or an absolute path.
I think you just need the following path (if the jar was ran from the directory containing the jar) :
new File("res/icons/icon.png")

Location of image in exported project folder

In my current code I write the specific location of the images I want to use in my project, now, these locations are only correct until I move the image to a different directory or open the application in a different computer.
Where do I place the images (where to place them in the exported folder) I want to use in my project?
The exported project is a zip file, once extracted, I have 2 folders within the extracted folder, one named nbproject other is src, one text file named build another .mf file called manifest inside nbproject I have two text files and two .properties files inside src I have my four classes.
Where do I put the images I want to use in the project? And once I place them, what directory do I write in my project?
Here's an example of how I use an image:
// Main menu background image
bgg[0] = new ImageIcon("D:/NetBeans/NetBeans projects/Java/Project Images/bg option for Vanguard.jpg").getImage();
And then I draw the image all over the screen
My exported folder contents:
http://i.imgur.com/qd4PeJo.png
http://i.imgur.com/W5YQ7OC.png
EDIT: Thought it worked but it keeps giving an exception on other people's computers, perhaps this isn't the reason beause I moved the images around in my PC and it worked but still.
Since you are writing the directory in your code.
bgg[0] = new ImageIcon("D:/NetBeans/NetBeans projects/Java/Project Images/bg option for Vanguard.jpg").getImage();
When you run the project in another computer or move the image to another location, the program can't find the path to the picture, so there is an error. Instead of using the full path. Copy the images to your project folder and use relative paths.For instance : "images/Vanguard.jpg".
The path where your program looks for resources can depend on how you run the program. If you ran it via console/terminal the initial path starts at the path of the *.class file you ran. If you run it from an IDE this path may change, in Eclipse the path starts at the Project dir and not the src folder. You can find out the exact path by calling System.getProperty("user.dir") that will return the current working path as a String.
Don't use a strict path, use a relative path like so:
Main.java
String path = "Project Images/bg option for Vanguard.jpg";
bgg[0] = new ImageIcon(getClass().getResource(path)).getImage();
In order for this to be loaded, you must place a folder called Project Images in the directory in which your Java files are. Then place the image bg option for Vanguard.jpg in this folder. Be sure to compile the program in you IDE so it can make a copy for the compiled version.

Launch .jar with config outside of jar, but be able to do it from ANY current directory

I've been wrestling with a particular problem. I have a Java program in a .jar file, and I have a lib directory and a config directory outside of the .jar, but in the same directory as the jar itself exists in.
I am trying to reference config/foo.config from within the code. Referencing it as a relative file works if I'm in the same directory as the jar. I've also tried using getResourceAsStream and making sure config is in the classpath.
So far, so good, but I also have to be able to launch the .jar from any directory.
So, if my structure is like so:
/prog/util/myprog/myprog.jar
/prog/util/myprog/config
/prog/util/myprog/config/foo.config
/prog/util/myprog/lib
(and a whole bunch of 3rd party jars within lib)
How do I correctly set up the classpath in my Manifest file so that config can be referenced?
The classpath in my manifest looks like so:
Class-Path: config/ lib/jar1.jar lib/jar2.jar (etc)
I am currently using getResourceAsStream("/foo.config").
This all works if I am in the /prog/util/myprog directory and run:
java -jar myproj.jar
However, I cannot, say, be in /prog and run:
java -jar util/myprog/myprog.jar
When I do this, the config file cannot be found.
How do I solve this issue?
EDIT: Some additional notes based on comments/suggestions, though I'm not sure this is feasible:
1) We can't use an absolute path for the file system, we don't know where the program will be stored, just that the config directory will be in the same directory as the jar.
2) I would like to be able to have something that works both when the code is jar'd, but also would work not-jar'd such as when I'm running in debug mode in Eclipse. At that point, the config directory is a sibling of the src, bin, and lib directories.
EDIT Part 2: Ok, between a colleague and myself, we came up with the following:
String configDirectory = new File(QueueMonitor.class.getProtectionDomain().getCodeSource().getLocation().getPath()).getParent() + "/config";
When we are in Eclipse and running in debug mode, the File object points to the bin directory, so getting the parent then appending "/config" works for our needs during development/testing.
Likewise, from a .jar file, the File object points to the jar itself, so getting the parent and appending "/config" gives us what we need as well.
I'm a little hesitant, though. I'm wondering if there's some potential problem or unintended consequence that I am not seeing in this solution. Any thoughts on that?
You should be able to use the Finding the path to a jar from a Class inside it? technique to find the location of your jar. From there it's just a matter of climbing in/out of folders.

Categories

Resources