Use File Input and Output in .jar FIle - java

So I've created just a simple application which I'm using to apply for a highschool internship. It was built using Eclipse.
I initially exported into a runnable .jar file, but the location I initially saved files, ("src/fileDirectories") didn't work on export.I then set the location to "./fileDirectories") which works and the app can actually run, however the .jar file creates the folder directory in the same folder as the .jar file.
This isn't too bad, as I can create a folder with the .jar and the saved files in it, which is fine, but similar to images, I'm wondering if there is a way to save .txt files in a directory to the .jar file so everything works with just the .jar application.

Assuming the files you want to access are static, and are not changed by the application, you can do this using the classpath.
When you access a file using new File("path"), Java will look for it in the file system, relative to the working directory (i.e. where the application was launched from.
An alternative way to access files is to look them up from the classpath - this is the list of locations Java searches for resources. It includes, among other things, the top level of your JAR archive. You can access this as follows:
this.getClass().getResourceAsStream("/my_file.txt")
Build tools will generally have preconfigured directories (e.g. src/main/resources) which get copied from your source tree into the JAR so they can be accessed in this way.
This is great if you have some static resources or config which you want to access at runtime, but don't want to have to pass around with your application.
However, if what you want is a working folder for files which your application will make changes to or create new instances of, like user documents, you don't want this to be editing the JAR - you'll need to make a separate folder for these.

Related

Using Maven & getResources Dynamically With Path Objects?

I have a Netbeans maven project, and am using the src/main/resources folder to deploy my pictures and a help file alongside the program that I'm writing.
From my understanding of the subject, any files in this folder (and the packages that contain them) are archived in the generated .jar file generated by the Netbeans IDE. I've verified this by opening the jar in a compressed file extraction program.
This is convenient for deployment, and previously, I ran into issues with versioning, with some pictures being out of date, as I was using folders on the disk to house the pictures folder previously.
I have a subroutine that selects a random picture from the pictures folder, but implementing this inside the jar file clashes with my understanding of the subject.
If the pictures folder is now in the jar archive, how can I get Path objects to these files? I'm well aware that I can use Clazz.class.getResource("/pictures") to get a URL object to the folder. I can also transform this URL into a URI and feed it to the File constructor and use getPath to get a path to this folder on the disk.
Then I can call Files.list(picturesPath); to get the list of Paths and select a random one.
This process would work just fine if the files/folders were just regular files/folders on the disk, but they're not, they're inside a compressed jar archive. This confuses me.
Can I just treat these folders I get back as Paths as typical folders and manipulate them in the typical way I do regular folders? Is there techno-sorcery at work to make this seamless or is there some subtle fallacy in my assumptions that would prevent me from using something like Files.list(picturesPath)?

The jar file is not reflecting any changes after making changes in code

I'm working on a java app. I created a jar file and after that I made some changes in my code about look and feel of app using Net-beans but the changes I made are not reflecting in the jar file. So do I have to delete the old jar file and then create a new one?
You need to re-make you jar file again, the jar file is essentially a compressed file containing all the resources (classes, images, etc) required to run your program. So if any of your classes changed you need to recreate the jar file to ensure the updated classes are incorporated.

Exported jar finds some files (not all) even though the paths are the same [duplicate]

This question already has answers here:
I'm trying to export a runnable jar in Eclipse, but I need it to include some other files necessary for running my program
(3 answers)
Closed 8 years ago.
When I run my program from eclipse, it shows up fine, the images from Resources\ show up, as do the sounds from the same place, and the text files are found properly. However, when I export my jar, and copy the resources into it with 7Zip, the images will work, but the sounds and the text files can't be found, even though they're in the same folder, with the same path used to find them in my code. I can fix this by putting a folder next to the jar file named Resources, and put everything in there, but I'd like to know why just putting it in the jar file only worked for the images, and how I can get it to work with the text and audio files as well.
An example to show you what I mean:
File inventory = new File("Resources/inv.txt");
threadpath = "Resources/threads.wav";
enemy1 = new Sprite(new Texture("Resources/miniForestGolem.png"));
When I run it in eclipse, all three work fine, but when I export it, and put the resources folder in the jar file, only the image works.
Edit:
I know how to include my resources, and have done so, I'm asking about how/why some of the resources aren't able to be accessed, even after adding them in.
Ok, from your comments we can infer the difference between executing it from eclipse and executing it from a .jar.
From eclipse: it works, because all that new File(...) find an actual file in Resources/
From the .jar: it won't work, since there is no file in a relative ./Resources/ path from the execution path of the application.
The way to make it work is the next:
Make sure Eclipse recognizes Resources/ as a source folder (right-click on project properties, Java Build Path, and add it as a source path)
Look for a replacement for your API methods that, instead of File objects, use InputStreams. Once you have it, retrieve all your resources as InputStreams taken from the classpath. If you are inside MyClass.java, do this: MyClass.class.getClassLoader().getResourceAsStream("Resources/inv.txt"), etc.
What you have achieved by doing this: instead of File objects built on actual operating system files, you will be retrieving InputStreams read straight from your java application classpath. This way, you can package them into a jar, or into a WEB-INF/classes directory inside a web application, or a library folder in some application servers... wherever you like as long as it is into the application classpath. I would do this if I had to package your application in a portable and usable way.

Can an external jar access a file within a folder in a project

I am using an external jar (stored in my lib file within an eclipse project) and that jar needs access to a file to which I am supposed to pass the path. So far I have only been able to make it work properly if I store the file in a completely separate area on the server.
I'd like to be able to store this file neatly within the project. For examples sake lets say that testfile.txt is in the projects src/testfolder. From within java I try to reference the file like so:
File file = new File("src/testfolder/testfile.txt").getAbsolutePath();
But that returns a path on my pc. In this case its:
"/home/me/testfolder/testfile.txt"
I'd like to application to be portable so I can move the jar file around if necessary without having to worry about bringing external folders. How can I reference this file within the application and pass that url to an external jar?
Does the jar includes this file as well. If yes, then it should not be an issue as the absolute path will be taken care of automatically.

Java in Eclipse: Where do I put files on the filesystem that I want to load using getResource? (e.g. images for an ImageIcon)

I know the file needs to be where the getClass().getResource(filename) can find it, but I don't know where that is.
I'm interested both in where to put the files on the filesystem itself, and how to go about using Eclipse's functionality to set up the resources.
For Eclipse, typically all you need to do is set up a folder somewhere within your source code directory. For instance, if the directory containing your source is /src then you can create a /src/resources folder to place your images/files in. Then, within your class you do a getResource("/resources/image.png") to retrieve it.
You can also place the image/file within the same folder/package as the class trying to access it if you wish (example: place the image.png in the com.mycompany package with the com.mycompany.Foo class that needs to access it and call getResource("image.png")), but I've found it's easier to keep resources like images and other files in their own special directory outside of the class folders -- they're just easier to manage that way.
In Eclipse, whenever you do a build, the files within this resource directory will be copied over into your build directory along with your compiled classes.
It's important to note that if you have "Build Automatically" turned on in Eclipse (as most people do) any resources in this directory that get changed outside of Eclipse (i.e. you edit an image using an image editing tool) that the IDE may not always detect this change. Usually doing a refresh on the project folder will ensure that the file gets updated in the build in these situations.
You can either put them in the src folder alongside your classes, or you can create a new source folder for the purpose (usually called resources), although you'll locate them identically from code.
Then you get at them using getResource("/com/x/y/foo.png").

Categories

Resources