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.
Related
I'm trying to load an image that I have stored in my /src/main/resources folder. When I do, however, I keep running into a NullPointerException that stems from the resource not being found.
Here is the code snippet:
try {
String path = this.getClass().getClassLoader().getResource("bern.png").toString();
} catch (IOException ex) {
System.out.println(path);
}
Here is an image of my project file tree:
And here is an image of my target build file tree:
Here is the NullPointerException stacktrace:
https://pastebin.com/KqJVxWEL
I have tried using pretty well every possible path for the image file that I can think of. (/src/main/resources/bern.png, src/main/resources/bern.png, /bern.png, etc.).
I have also tried using getClass().getClassLoader().getResource() instead of getClass().getResource(). From what I understand, the only difference between the Class and ClassLoader version of getResource() is that the Class version is not inherently absolute relative to the root, whereas the ClassLoader version is.
When I run getClass().getResource("").toPath(), I get the path that leads to the classes directory. This aligns with what I've read about the getResource() method working with the target build file tree. However, I don't see the resources folder showing up anywhere in the target build; I think that's the core of my problem. I'm just not sure how to fix it.
I know this question has been asked numerous times before, but the answers to the other version of this question haven't helped me out much.
I'm using NetBeans 11, and this project is running on the Maven build system. I haven't done much work with Maven in the past, so forgive me if this problem is extremely easy to fix.
Anyone know how I'm approaching this wrong?
EDIT: The problem is not anything with my project structure or code as shown by the code compiling correctly when run using mvn via the command line. As a result, it's an issue with NetBeans specifically and the way that it is viewing the resources folder.
Read the resource contents as a Stream (instead of the URL or file path)
public static void main(String[] args) throws IOException {
InputStream in = Application.class.getClassLoader().getResourceAsStream("bern.png");
BufferedImage testImage = ImageIO.read(in);
ImageIcon icon = new ImageIcon(testImage);
}
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.
I am developing a Java application which displays a big amount of images. The problem is I can't figure out how to make Java find these images.
I have followed several tutorials and answers here at Stackoverflow, but I still haven't managed to find a solution that works regardless of OS (Linux or Windows) and running method (embedded on eclipse or exported jar file). This might be due to the fact that I am still a newbie, though.
I have created a class, which I call myIcon and through this class I mean to access all of these images. In the following code, I want to pass the string "resources/icon/image.gif" to the function getIconPath. The output should be a ImageIcon of this image, since this file exists. Despite that, if I pass to this function the path to an image that doesn't exist, null should be returned. In this case, my application will display a default image (a red x).
public class MyIcon {
// some other functions and properties
private static final ImageIcon getIconPath(String path) {
File f = new File(path);
if (f.exists()) {
return new ImageIcon(path, "");
} else {
return null;
}
}
}
The resources folder is a sibling to the src folder in my directory structure. That is, both resources and src are subfolders of the root directory.
When I run the code above, no image is ever found. The default image is thus always displayed and getIconPath returns null.
I am also aware of the getResource method of ClassLoader, but I still don't really understand how these things should be used.
While running in eclipse, you should print out f.getAbsolutePath(). It probably doesn't point to your file. More generally, you want to access the file as a resource. See:
https://docs.oracle.com/javase/tutorial/deployment/webstart/retrievingResources.html
There are two parts to this - making sure that when you build a jar, the images are part of it, and accessing a resource within the jar.
For the first part, I am guessing that whatever you're using to build a jar, it will put your images into the META-INF folder, which should work without too much issue (if its not there, or in with the Java class/source in the generated jar, that might cause the lookup to fail)
There is another Stack Overflow Post for the second part. The key is to make sure the images you want to load are on the classpath.
Hope this helps!
If resources is in classpath, you can find for the image at classpath, using getResource(String name) or getResourceAsStream(String name).
However, in a simple Java Project, even adding resources to build path, like this:
it will just put the folder content, in other words, just icon/..., to bin folder, something like this:
So, since resources isn't in classpath, just icon, to retrieve the images, you'll need to inform as path only /icon/image.gif, like this:
URL url = YourClass.class.getResource("/icon/image.gif");
ImageIcon icon = new ImageIcon(url);
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.
Ok, I'm stumped here. I'm using Matlab version 2013b with a Java RTE of 1.7.0_11 and I'm trying to run a simple piece of code to see if Matlab is able to read the .jar file and nothing seems to be working.
Here is the Java code, which is compiled to a .jar named JavaOCT.jar, which is placed in the Matlab working directory:
package VTK;
public class vtkVolumeView{
public int Test(){
return 10;
}
}
That is it, no other dependencies, nothing fancy. In Matlab, I try:
javaaddpath('\JavaOCT.jar'); %<-Directory and name are 100% correct
import VTK.*; %<-Package name from above
methodsview VTK.vtkVolumeView; %<-Can't find the class, argh!
Matlab kicks back that it can't find the class.
Things I've done to try and solve the problem:
Reverted to the exact same JDK as the Matlab RTE
Tried an older 1.6 JDK
Done lots of stack overflow research to try and solve it 1 2 3 4
Tried used javaclasspath and pointing to the compiled class instead
Read the Matlab documentation 5
Using clear -java after the javaaddpath
Any help would be appreciated, it is driving me nuts!
Update: Daniel R suggested just javaaddpath('JavaOCT.jar') which doesn't work either.
Final update: It finally works! I wasn't building the .jar properly. In IntelliJ, click on the project and hit F4. This brings up the Project Structure, then go to Artifacts and click the green + button and add DirectoryContent and then point to the out\production. Once this is done, as mentioned by others, it should show up in Matlab as an expandable .jar.
I don't know which operating system you are using, but the ./ seems invalid.
Try javaaddpath('JavaOCT.jar'); or javaaddpath(fullfile(pwd,'JavaOCT.jar'));.
What does exist(fullfile(pwd,'JavaOCT.jar')) return?
Some things to try:
Add the class file. When using a package, you need to add the class file in at the host of the package. For example, if your code is here:
\\full\path\to\code\VTK\vtkVolumeView.class
Then use:
javaaddpath('\\full\path\to\code')
I'm still suspicious of your *.jar path. You should usually use absolute paths when adding jar files. Try adding the results of which('JavaOCT.jar')
How did you make your jar file? Does it contain the appropriate directory structure implied by your package declaration?