JAR won't work after adding images - java

I've written a game that uses PNGs, and when I exported it, the images wouldn't work. I added getClass().getClassLoader().getResource() to everywhere I import an image, but the JAR won't even launch anymore. It used to open, but none of the images worked. Now it won't even open the JAR.
This is how I get the image for the muffin:
muffin=new ImageIcon(getClass().getClassLoader().getResource("muffin.png")).getImage();
Actual path for it is: C:\Users\My User Name\Dropbox\FinalProjectWithoutApplet\muffin.png
What should I do to solve this issue?
Thanks!

getClass().getClassLoader().getResource("muffin.png") is looking for the image muffin.png in the same directory where your class is.
I means that if your class's name is com.mycompany.game.MyClass the image is expected to be in com/mycompany/game/muffin.png. If this is not the location write absolute path that starts with /, for example /img/muffin.png.
And in future if program does not work start from examining the stack trace.

I found the issue. Turns out my cases mismatched. The IDE didn't care that one was called "muffin.png" in code vs. "Muffin.png". Another case I found was "DoubleJumpIcon.png" vs. "DoubleJumpIcon.PNG". Every single case matters it turns out.

Related

new File() works but getResource()/getResourceAsStream() throws null exception

In the context of a school project i'm currently working on a little game in eclipse which I want to convert into an executable JAR when I'm done. Since I'm working with the .drawImage() method on my label I need to use BufferedImage or Image. To import my pictures into my project I've created a folder called "rsc" and set it as a resource folder, them put the images in there.
Now, when I use
BufferedImage bg1 = ImageIO.read(new File("rsc/BlackWhiteSpace.jpg"));
Everything works fine. But I obviously can't use that when exporting the project because that will change the paths and the method will no longer be able to find the images even though they are clearly included in the JAR (I've checked)
The resolution I found on the Internet is to use .getResource() or .getResourceAsStream()
I've tried tons of different variations. Here a few examples:
ImageIO.read(getClass().getResource("rsc/BlackWhiteSpace.jpg"))
ImageIO.read(Var.class.getResourceAsStream("rsc/BlackWhiteSpace.jpg"))
ImageIO.read(Var.class.getResource("rsc/BlackWhiteSpace.jpg"))
And also different path variations such as:
"/rsc/BlackWhiteSpace.jpg"
"rsc/BlackWhiteSpace.jpg"
"/BlackWhiteSpace.jpg"
"BlackWhiteSpace.jpg"
Etc.
I've also thought of case sensitivity and those examples aren't the only variations I've tried.
Now why is java still giving me:
Exception in thread "main" java.lang.IllegalArgumentException: input == null!
at javax.imageio.ImageIO.read(Unknown Source)
???
What am I doing wrong? This project is being graded so I really wanna be able to run it without eclipse, please help!
Edit:
[enter image description here][1]
[1]: https://i.stack.imgur.com/tIlz4.png
https://pastebin.com/s7Yxtw6Y

IllegalArgumentException at Java Jar resource access

I have spent all last night (until 3am) and this morning researching, testing, refactoring, and attempting to debug this issue. I have a simple Java game in Netbeans and while it runs perfectly perfect within the IDE in either run or debug mode, once exported into a jar file it refuses to load any resources corrrectly. There are many similar questions to this such as this one regarding loading an ImageIcon and despite great effort none of these solutions work for my project. I am not using ImageIcons, only simple BufferedImages and wav sound files. I recently refactored to combine my BufferedImageLoader and Sound classes into one Resource class, which I then moved into the same package as all my resources even though it worked perfectly well in a separate code package before in the IDE, although it works in its new location as well, strictly within the IDE.
I'm rather irritated and flustered from this issue. The truly infuriating thing is that this project used to work with resources after being exported into a jar, and now it seems to have stopped working with no changes. The only real programmatic difference between back when it worked and now is that I didn't have or use sound files back then, but this error isn't related to the sound files, as it catches an exception (and generates an error dialog) just from first trying to load the art assets.
I've tried every possible solution I've found in my research to no avail. Hopefully a fresh set of eyes can reveal the error of my ways.
The offending line of code is
return ImageIO.read(Resource.class.getResource("/res/" + imageFileName));
whereas imageFileName is the parameter with values passed from method calls such as
blockSheet = Resource.loadImage("art_assets/platform.png");
The location of the Resource class seemed to have no bearing on this working within Netbeans. My res folder is inside src, next to the com class package beginning.
It throws an IllegalArgumentException: input == null! exception. After some testing it seems that Resource.class.getResource("/res/" + imageFileName) returns a null value, which makes no sense at all. Again, this works perfectly perfect within the IDE. I can change the jar file into a zip and look inside to see that all the resources are exactly where they should be with the correct names and the correct extensions.
Here is a zip file of my entire project. Any help is immensely appreciated. Thank you.
EDIT:
Some of the things I've already tried:
getResourceAsStream() instead of getResource()
classLoader() between Resource.class and getResource()
this.getClass() instead of Resource.class from a non-static context
I think this should help:
How to get the path of a running JAR file?
CodeSource codeSource = YourMainClass.class.getProtectionDomain().getCodeSource();
File jarFile = new File(codeSource.getLocation().toURI().getPath());
String jarDir = jarFile.getParentFile().getPath();
provided by Benny Neugebauer in the post.

Relative/Absolute Path in Java

I need to write a program that asks for the file name of a text document of number and then calculates average, median, etc., from this data set. I have written the program so that runs correctly when I input the full path such as "C:\Users\COSC\Documents\inputValues2.txt", however it will not run when I simply input inputValues2.txt. I have been researching the different between the two but am not fully understanding how to fix this. Since it is running correctly, otherwise, I don't believe it is a problem with the code, but I am new to this so I may be wrong.
Your program needs to know the full path in order to find the file. It isn't just searching your computer for the file "inputValues2.txt". It needs to know exactly how to get there. If you wanted to, you could move the file into your project folder, and then you would just be able to write "inputValues2.txt" to access it. I normally create a folder called "res" in my project folder, and then let's say I am trying to create an image:
Image i = new Image("res/img.png");
Your file should be in the class-path. That's in the same directory that your main class is in.
The suggested practice is to place it in a Resources directory inside your class-path, then you can access it via, "Resources/inputValues2.txt".

Load files dynamically in multiple environments

so I am in the process of making a small application.
Right now, the project works fine. I am running it through an IDE. The problem comes about when trying to run the project as a jar - which is the end result. Right now, it fails to properly load the required files (classes and simple ASCII files).
The method I am using is one based off of:
final Enumeration<URL> paths = CLASS_LOADER.getResources("");
Where CLASS_LOADER is an instance of class.getClassLoader().
This works great when not inside a jar. Inside a jar though, it seems to fail horribly. For example, in the code above, paths would be empty.
I am assuming that the fault is that the files are all within a jar - the same jar to be precise.
The class path for the manifest file is blank at the moment.
If it helps, I have two tasks that require loading files.
I need to create a list of all files that are a subclass of
another class.
I need to load a list of language files (all of
which are in the same directory).
If you need anything else to help debug this problem or provide a solution - let me know. Thanks for reading this!
For ClassLoader.getResources() to work you need to feed a path relative to the jar root. If you want to search the jar then ClassLoader public API won't help you. You have to use custom code based on java.util.jar.JarFile, like the one here.

Add images to jar

I want to set icon to my JFrame. I do the following:
Image icon = Toolkit.getDefaultToolkit().getImage("src/images/icon.jpg");
this.setIconImage(icon);
It works fine when I run this code from netbeans, but when I try to run this code from jar file, images are not shown in my JFrame. I have tried to load images as resources:
this.setIconImage(Toolkit.getDefaultToolkit().getImage(getClass().getResource("/src/images/icon.jpg")));
but when I run this code it fails with NullPointerException
Uncaught error fetching image:
java.lang.NullPointerException
at sun.awt.image.URLImageSource.getConnection(URLImageSource.java:99)
at sun.awt.image.URLImageSource.getDecoder(URLImageSource.java:113)
at sun.awt.image.InputStreamImageSource.doFetch(InputStreamImageSource.java:240)
at sun.awt.image.ImageFetcher.fetchloop(ImageFetcher.java:172)
at sun.awt.image.ImageFetcher.run(ImageFetcher.java:136)
How can I do this work?
edit:
Thanks to all,
the problem was solved by specifying image as
Toolkit.getDefaultToolkit().getImage(getClass().getClassLoader().getResource("images/icon.JPG"))
As for it seems rather weird, and would be better if it was like
this.setIconImage(new ImageIcon(pathToIcon).getImage());
Assuming your JAR file has a top level directory called images, you can use either:
getClass().getResource("/images/icon.jpg") or
getClass().getClassLoader().getResource("images/icon.jpg")
Looking at the source code of URLImageSource, it appears that the reason that getConnection throws an NPE is that it has a null for the url. And that leads me to suspect that
getClass().getResource("/src/images/icon.jpg")
is returning null. It would do that if it could not locate a resource with that pathname.
I bet that the problem is that you've got the path wrong.
To prove / disprove this, you should run jar tvf on the JAR file, and look for the line that matches "icon.jpg". Is the corresponding pathname the same as what you are using? If not, use the pathname from the matching line in the getResource call and it should work. Alternatively, if the file doesn't show up at all, look at the NetBeans build configs that tell it what to put in the JAR file. (I'm not a NetBeans user, so I can't say where you would need to look ...)
If that leads you absolutely nowhere, another possibility is that getClass().getResource(...) is using a classloader that doesn't know about the JAR file containing the image. (This seems pretty improbable to me ...)
getResource() loads a resource from classpath, not an OS path, and the after compilation your classpath will not include the /src folder, but rather just its contents. So you'd better try /images/icon.jpg.
Also you may find this discussion somewhat useful.
This should do it assuming you can import javax.imageio.ImageIO:
Image icon = ImageIO.read(this.getClass().getResource("/src/images/icon.jpg"));
this.setIconImage(icon);
.."/src/images/icon.jpg"..
The '/src' prefix of the address seems suspicious. Many apps. will provide separate 'src' and 'build' directories, but it normally ends up that the 'src' prefix is not used in the resulting Jar. I recommend trying..
.."/images/icon.jpg"..
& also triple checking that the image is in the location of the Jar that the code is expecting to find it.
For this to work, you should access the images from a directory relative to some fixed class.
For example, if the image files are saved in a directory "images" on the same level as the Toolkit.class, then
this.setIconImage(Toolkit.getDefaultToolkit().getImage(Toolkit.class.getResource("images/icon.jpg")));
should work.
You can simply create a package inside the main source, and incluse your images in this package. Then, just call the images in your main class like:
ImageIcon a = new ImageIcon(MainClass.class.getResource("/Package/Image.jpg"));
JFrame f = new JFrame("Edit Configure File");
//Image image = ImageIO.read(getClass().getResource("images/ctx.Icon"));
f.setIconImage(new ImageIcon("images/ctx.PNG").getImage());//this works for me finally
//f.setIconImage(image);
//f.setIconImage(Toolkit.getDefaultToolkit().getImage(getClass().getResource("images/ctx.PNG")));

Categories

Resources