Java getResourceAsStream Returns NullPointerException? - java

This will no doubt be marked as a duplicate but I figured I'd try anyway. I've looked at all the related questions that have been asked, and I've searched online, and I can't seem to find the solution to this issue.
I am trying to use the Java FX diffuseMap to texture a Box. However, when using
PhongMaterial material = new PhongMaterial();
material.setDiffuseMap(new Image(getClass().getResourceAsStream("/Eternity/Images/ice.png")));
b.setMaterial(material);
I get a NullPointerException;
java.lang.NullPointerException: Input stream must not be null
I have tried messing with the filename, paths, different ways of accomplishing the same task (all of which still involved InputStreams) and even copying and pasting the actual file path (using Intellij's Copy File Path button) but I can't seem to solve this issue. It just doesn't seem to have any effect on the error.
Here's a look at the project hierarchy, barring the main project folder.
Any and all help would be greatly appreciated!

Class.getResourceAsStream() uses the class loader, to load a resource from the classpath. So, for your code to work, the directory containing the Eternity directory should be in the classpath. Since it's not, the resource can't be found by the class loader, and null is returned, as documented.
So, either change the classpath of your running program, or move the images to the source folder, so that your IDE (and, hopefully, your build/packaging tool), copies the images to the directory where the class files are compiled. And then use the right path of course (i.e. the full package name, but with slashes instead of dots, and with a starting slash). If the image is in src/foo/bar/ice.png, the package is foo.bar, and the path to use is thus /foo/bar/ice.png.

Seems like you're using Intellij, just drag the images directory and drop it in the src directory and rename the path to
... .getResourceAsStream("/Images/ice.png")));
#JB Nizet did a good job of explaining why it doesn't work.
My solution is a temp-fix the right way would be to correctly configure a resource directory and then put your resources there. I suggest you go through Intellij Modules

Related

Using $PROJECT_DIR$ in the path String in IntelliJ Idea

I have a simple question, but I can't find the answer anywhere. I would like to use $PROJECT_DIR$default path variable in IntelliJ.
I wanted to add an icon to the Stage:
stage.getIcons().add(new Image("$PROJECT_DIR$/src/main/resources/com/example/demo/money.png"));
But this doesn't work, unfortunately :(
I tried also using PROJECT_DIR or MODULE_DIR or $MODULE_DIR$, but nothing works. Maybe it's impossible to use those path variables in such way (?). Please, explain it to me.
Using Absolute Path to the image works, but I would like to share my project and that's why I decided to replace it with a path variable.
You don't have to use directory like this one. Intellij already know where is the project.
You have to check according to where will be located the file when it will be exported.
In you case, you have to use :
stage.getIcons().add(new Image("com/example/demo/money.png"));
Because resources are already consider as resources and so will be in main folder in exported jar.
If it failed, you can try with less package, for example put money.png directly in the resource folder

class.getClassLoader.getResource() returns null

Previously I built single jars with ant, for each application i wanted from my project and calling the application with java -jar application-name.
I have now moved to using gradle and having a single jar and call the applications with
java -cp fullpath-to-class.
Everything works as expected for all but one application where i now get a
null pointer exception trying to load the resources required.
If I move the files into the directory of the class which is looking for the files everything is good once again , but having them in a different directory seems to be problematical.
Have you any suggestions on the best approach to
A. debugging this effectivey
B. Having the file in a separate directory
Have you any suggestions on the best approach to A. debugging this effectively
Use jar -tvf ... to check that the missing resource is actually in the JAR file, and that it has the correct pathname in the JAR.file
Use a debugger, and set a breakpoint on the code that is trying to load the resource. Single step until you get to the point where you have the absolute resource path. Check it.
B. Having the file in a separate directory
Umm. I'm not sure what your actual problem is, but my guess is that it is to do with resolving relative resource pathnames. I suggest using absolute resource pathnames instead.
I guess the problem could be in the way you are building the JAR file, but you've not provided any concrete details of how you are doing that.

How to correctly import files in a maven project structure?

I have a configuration file in xml format, that I need to load into my java code. While testing, I have imported it through it's absolute URL, but now I am about to compile and deploy the project as a jar, and that won't work anymore.
From previous experience, I think the right way to do this, is to use the ClassLoader, but I'm having some difficulties. Maybe because of my project setup, I do not know. I think I would be able to make this work, as I ahve done in the past, but I really want to make sure I do it the standard, conventional and/or correct way, so that I do not need to experiment every single time this comes up.
Here is the code I've tried to implement: http://www.mkyong.com/java/java-read-a-file-from-resources-folder/
However, this code:
ClassLoader classLoader = getClass().getClassLoader();
File file = new File(classLoader.getResource("file/test.xml").getFile());
I could not use, due to needing the file in a static method of an abstract class. Therefor I switched it out with the following code:
ClassLoader classLoader = XmlConfigLoader.class.getClassLoader();
File file = new File(classLoader.getResource("configuration.xml").getFile());
The XmlConfigLoader is the containing Class. "configuration.xml" is located in the src/main/resources-folder, just as "file/test.xml" is in the example
I've run the code in debug-mode, and found that the file has the wrong path. Instead of looking in src/main/resources, it points to target/classes
Is there a setting option for default resource folder that I need to set?
Is src/main/resources the conventional place to store files like this?
Is my way of loading the ClassLoader correct in this setting?
As an additional info, this is a Maven project.
UPDATE:
My Current code actually works perfectly, apart from a single bug. The file is automatically transferred to the target/classes folder at compile time. However, whitespaces in the url are replaced by %20, and I have to manually change them back in order to make the system find the file. I am sure there is a better solution to this. Anyone?
It makes sense that the file has the path "target/classes", as this is the Class-Path in your jar's manifest file. If you want to get it to look somewhere else, edit the manifest file and append the resource classpath to it.
There are more details on how to alter your jar's classpath over at Setting classpath for a JAR
As you are using maven, the easiest thing to do is to put you resource file into the src/main/resources/META-INF directory, and maven will sort it out for you. See http://maven.apache.org/guides/getting-started/index.html#How_do_I_add_resources_to_my_JAR

getResourceAsStream works in Eclipse IDE but not in JAR format

This is a really common error, because there are tons of threads about it, but I'm not sure if since my situation is slightly different from all of them the solutions don't work?
Basically, I'm in eclipse. I have a source folder called src, then I have a package that goes down three folders, then the class in question. The class uses the code:
BufferedImage im = ImageIO.read(Thread.currentThread().getContextClassLoader().getResourceAsStream(filenames[x].concat(extension)));
surrounded by a try/catch. filenames is an array of all the file names I am loading (this code is run multiple times in a for loop) and extension is ".PNG". The pictures are located in another source folder called EngineTextures.
Running this program works fine in Eclipse! All textures are loaded and all my other code runs! However, I export it as a runnable jar and run it in command prompt to recieve input == null errors on all of them, pointing to the line that has ImageIO.read(Thread.currentThread() in it.
The kicker is this whole thing worked in a separate project before, and when I even tried re-exporting that project, I recieve the same errors on completely unchanged code. This leads me to believe I have some obscure Eclipse setting changed wrongly.
Opening the jar, my MANIFEST.MF has a version of 1.0 and a classpath of just plain ., which I thought was correct for this kind of thing? The Main-Class points to the right place, and all my pictures are right there next to the META-INF folder.
Solutions I've looked at unsuccessfully:
getResourceAsStream working in eclipse, but not when run as applet in browser
Why does getResourceAsStream() work in the IDE but not the JAR?
Java IDE - Eclipse, Importing resources
Audio file in jar made by Eclipse IDE
getResourceAsStream() returning null in jar but fine in eclipse
Additionally, I completely deleted the workspace and recopied my pictures and code into the same state, thinking maybe some .metadata thing was wrong, to no avail.
Thank you, in advance, for any and all help. I hate to make a repeat like this but no solutions have worked thus far. Please let me know if I have not given any crucial information.
Opening the jar, my MANIFEST.MF has a version of 1.0 and a classpath of just plain ., which I thought was correct for this kind of thing?
No. The Class-Path entry in a JAR file names other JAR files, relative to the location of this jar file. It doesn't name directories:
"The value of this attribute specifies the relative URLs of the extensions or libraries that this application or extension needs."
That in turn implies that resources to be loaded via getResourceAsStream() must be in JAR files.

Duplication within Java classpath issue

I have a program that imports its required classes from a .jar source.
However I have also unzipped said .jar source in order to search its file directory to gather up class names for a list within the same program.
The problem is that the class ** appears more than once in the classpath, this is due to it being simultaneously in the bin and as a library. I need both elements for separate, yet equally code features.
I've found removing the file directory of the .jar source solves the problem however my list is now blank.
Anyone know of a way to do both?
Based on what you said above in the comments, if your package names start with com.somethingfromsourceforge.* then I would change com.somethingfromsourceforge to com.hopeless and the pathing issue should be resolved. Try this and let us know.

Categories