Java on Mac: Cannot read resources in executable JAR - java

This code works fine when I run it from Eclipse, but not from an executable jar:
String str = "";
ImageIcon icon = null;
InputStream is = getClass().getResourceAsStream("/images/splash.jpg");
if (is != null) {
icon= new ImageIcon(ImageIO.read(is));
} else {
str = "stream is null";
}
JOptionPane.showMessageDialog(null,str,"A title",JOptionPane.PLAIN_MESSAGE,icon);
The dialog is displayed but no stream is returned from getResourceAsStream, irrespective of how I write the path. Inspection of the jar shows that splash.jpg is located in the images-folder, as it should be. The jar is created using Eclipse's export of "Runnable jar" with "Package required libraries into JAR" selected.
I know this question has been asked before, and I have read many (most?) of the answers and tried many different alternative solutions. But nothing seems to work. Any help would be much appreciated. (I'm using java 8 and Eclipse Mars on OSX Maverick.)
EDIT: Sorry for not listing the alternatives I have tried. It's just that I haven't kept notes and I cannot remember all. As far as path goes I have tried all combinations of "/" and "images" (and "resources"). I have also tried getting a URL via getResource(), both from class and class loader. No matter what I do I get null (no exception thrown in example above).
Here's what the structure looks like in Eclipse: http://i.stack.imgur.com/bIiEi.png
And here's what it looks like in the jar: http://i.stack.imgur.com/JAnmr.png

In your screenshots, the file is named "splash.JPG", and you're asking for "splash.jpg", which is a difference in case. The Mac filesystem is case-insensitive. The JAR entry reading code may not be. Try changing your string in the getResource call to have the same case as the file name or vice versa.

Related

JAVA getResourceAsStream() real path string interpretation of a file

I am using NetBeans 8.0.2 (I know there already is v8.2 but it has a lot of bugs for me so I got back to v8.0.2) and I need a string path to my .obj file for a parameter attribute like this:
api.parameter("filename", "obj/someFile.obj");
Above example worked in a previous version of my app where I had that .obj file placed in a folder called "obj" in the same directory as my .jar file, but now as I am trying to rather include it in the JAR itself with code:
api.parameter("filename", MyClass.class.getResourceAsStream("/someFile.obj").toString());
...it is not working anymore as the path string interpretation is not a path to a file, it looks more like this:
java.io.BufferedInputStream#215d7ea7
...where, of course, my code is expecting something like normal path string, I would said something in this pseudo-code manner:
api.parameter("filename", "<this.jar>/someFile.obj");
So after a fiddling a bit around StackOverflow I've found pieces of code that I thought could actually enable me to directly place that path as a string:
URL jar = MyClass.class.getProtectionDomain().getCodeSource().getLocation();
api.parameter("filename", jar + "/someFile.obj");
But surprisingly although I checked several times if the file actually really exist in my built jar file (and yes, it is there in the root) it still gives me this error:
java.io.FileNotFoundException: file:\Z:\_JAVA_\MyProject_0_018\dist\bin\myjar.jar\someFile.obj <The filename, directory name, or volume label syntax is incorrect>
And I am 100% sure the name of the file is correct, also its placement in the root of my jar file.
Or does it actually thinks that myjar.jar is a directory?
I am desperately trying to find a solution to this "path string" mess.
Your protection domain's code source location likely returns not what you'd expect it to.
You should use getResource(name) directly, like this:
URL locator = MyClass.class.getResource("someFile.obj");
api.parameter("filename", locator.toString());

Runnable jar exported with eclipse isn't working, in eclipse it still works

I'm trying to export a java project in eclipse as a runnable jar, but for some reason the runnable jar doesn't work. If I double click the executable jar, it doesn't do anything. I tried both extract and package required libraries into generated jar.
So I also tried to export some simpler projects, those worked fine. The biggest difference is my real project has files: images and xml files.
In code reference them like this:
File file = new File("Recources/test.xml");
ImageIcon imageIcon = new ImageIcon("Recources/" + num + ".gif");
The structure of the project looks like this:
But in the executable jar they look like this:
Thank you for your help.
Edit:
I have tried the 'java -jar filename.jar', but now it says it can't find my resources folder, while in eclipse it can still find it.
Files in a JAR-File aren't just like files stored in your hard-disc. If you include files in a JAR, they'll be seen as a Stream of Bytes. So you have to use different methods to access these resources.
//To read/access your XML-File
BufferedReader read = new BufferedReader(new InputStreamReader(getClass().getResourceAsStream("/test.xml")));
//To read/access your gif-Files
ImageIcon icon = new ImageIcon(this.getClass().getResource("/"+num+".gif"));
"/" is not the root-Folder of your file-system, but the root folder of the resources inside your JAR.
The issue may be that Java is not the default program to run the jar.
Try right click -> Open with, and select the Java Runtime, and it should run successfully.
Make it the default program to enable double-click running.
Right click -> Properties -> Change -> C:\Program Files\Java\jre7\bin\javaw.exe
Inspired by stratwine's answer at https://stackoverflow.com/a/8511277
So thank you all, but it seems like the problem wasn't the export only. There was an error I saw when I opened my program with cmd, I was using file name to open xml and images while I should have used inputStreams: https://docs.oracle.com/javase/tutorial/networking/urls/readingURL.html.

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.

Behavior between Runnable .jar and Eclipse run is very different

I am using an XML document as a template for multiple, similar documents (monthly reports which are organized identically). I was struggling to find the most generic path to the file. I came up with:
File f1 = new File("src/Statements/TemplateStatement.xml");
where /Statements/ is a folder under the src tab in Eclipse as if it were just another package.
Then:
File TemplateStatement = new File(f1.getAbsolutePath());
if (TemplateStatement.exists()) {
// ...do some stuff
} else {
JOptionPane.showMessageDialog(null, null,
"ERROR: Transaction template not found.", JOptionPane.OK_CANCEL_OPTION);
System.exit(0);
}
When running from Eclipse, it works great and my stuff gets done. When running as a .jar on my desktop (same machine and file system), I hit the else clause every time. I suspect I am missing a very basic yet important property of how jars package up the workspace and run it (as in there is no src directory associated with it anymore?).
I have had no luck finding examples or explanations on how to find the path, access, read, write, copy, etc. files from jarred applications. I really want to avoid hard-coding a full path as it may be the case the code will run on various machines. Any suggestions or pointers would be appreciated.
I've just encounted a similar problem, and it was caused by the java.io.FileReader function which uses platform default encoding.
As for my situation, in Runnable .jar running, java.io.FileReader uses ISO-8859-1 encoding, while in Eclipse it uses UTF-8 encoding. Replacing
new FileReader(filepath)
with
new InputStreamReader(new FileInputStream(filepath), "UTF-8")
solves my problem.

Java - .jar unexpected issue with Netbeans

First of all, I am aware of Stack Overflow (and any competent forum-like website) policy of "search first, ask last", and, doing my homework, I searched various sources to find a solution to my issue. That said, I, failing to find any suitable answers, was left no choice but to ask this problem personally.
I have somewhat moderate programming skills, especially regarding the Java language. I am working on this 2D game with the default Java SE JDK. More specifically JDK 7u4. In this project, we have a class that manages most I/O operations. One of its methods returns the path to a file:
public static URL load(String resource) {
return ZM.class.getResource(resource);
}
Now, this method works fine when running the project on Netbeans (version 7.1). However, when building and cleaning the project, the resulting .jar file does not seem to agree with its creator. When running the .jar on command line, the JVM caught a NullPointerException. It seemed that the file was not being able to be read inside the .jar. Following my programmers instinct, I started debugging the project. My first attempt was to check whether the load method was the faulty member. I ran some tests and obtained a couple of interesting results:
When running the application on Netbeans and with "ZM.class" as the methods argument, it returned:
/D:/Projects/GeometryZombiesMayhem/build/classes/geometryzombiesmayhem/ZM.class
But when running it from the .jar file, it returned:
file:/D:/Projects/GeometryZombiesMayhem/dist/GeometryZombiesMayhem.jar!/geometryzombiesmayhem/ZM.class
Naturally, I tried removing the initial file: string from it. No effect. Then I tried taking the exclamation mark from [...].jar![...]. Again, nothing. I tried removing all the possible permutations from the path. No luck.
Testing the method against the very own .jar file worked okay. Now, when I try to access the inside of the file, it doesn't let me. On earlier versions of this project it worked just fine. I am not really sure of what is going on. Any help is welcome.
Thank you in advance,
Renato
When loading resources from a jar file, I've always used a classLoader. Everything seems to work the same whether you run from within the IDE, launch the executable jar file or run the program from a web site using JNLP.
Try loading the resource this way instead:
try {
ClassLoader cl = ZM.getClass().getClassLoader();
ImageIcon img = new ImageIcon(cl.getResource("images/programIcon.jpg"));
// do stuff with img.
}
catch(Exception failed) {
System.out.println(failed);
}
One more suggestion - you should create a separate folder for resources. In my example above, images is a folder inside of my src folder. This way it will automatically become part of the jar when I build it, but I am keeping resources separate from source code.
I suppose your problem is in loading an image from your jar file.
Here is how i do it
URL imageurl = Myclassanme.class.getResource("/test/Ergophobia.jpg");
Image myPicture = Toolkit.getDefaultToolkit().getImage(imageurl);
JLabel piclabel = new JLabel(new ImageIcon( myPicture ));
piclabel.setBounds(0,0,myPicture.getWidth(null),myPicture.getHeight(null));
This way I can get the Ergophobia.jpg file inside 'test' package.

Categories

Resources