Cannot read resource from Jar File - java

I am having trouble figuring out this problem and I have tried almost everything.
I would like my program to read two resources from Jar File, and it will run fine through eclipse. However it gives nullpointer exception when I run the jar from command prompt.
Structure:
src/main/java/App.java
src/main/resources/properties/application.properties
src/main/resources/spring/applicationContext.xml
Code:
To read application.properties
properties.load(App.class.getResourceAsStream("/properties/application.properties"));
To read applicationContext.xml
context = new ClassPathXmlApplicationContext("/spring/applicationContext.xml");
Error:
Error while loading
application.properties java.lang.NullPointerException
What could I be doing wrong?

Assuming that these are in a jar file that is available on the classpath at runtime, the first, getResourceAsStream() example is probably failing because you haven't specified the full path within the jar file. (Also, a common failure it to leave off the leading /, but you seem okay there.) E.g.:
properties.load(App.class.getResourceAsStream("/src/main/resources/properties/application.properties"));
However, if you are unsure where (what path) the files have been given in the jar file that was built, try
jar -tvf <your-jar>.jar
to see what is actually in it.
Can't comment on ClassPathXmlApplicationContext; not a Spring developer.

in your structure you show where the .java is, but you´re missing the .class. The path where it resides is the one the classloader will use. There should be your resources
EDIT: to clarify a bit. In your post you mention the path to App.java. but the classloader only cares about App.class, so let´s say you have
\src
|...(App.java and whatever, these will be ignored)
\bin
|
|--App.class
|
\bin\resources\...(properties and whatever, these will be read)
you should make sure you have properties and spring directories under bin.
If you only have the .java in src it will be ignored by the classloader.

Related

How to properly get resource Java project

In my project i currently have a setup using eclipse
But when i try to load the file "bg.png" by calling
getClass().getResource("/res/bg.png") or getClass().getResourceAsStream("/res/bg.png") I get a NPE
Can anyone tell me whats happening here? I never really thought there was much difference between how both methods locate their files
TIA
getClass().getResource[AsStream]() uses the class loader to load resources: the same mechanism as the one used to load class files based on the classpath.
So, to be able to load the resource, it must be in a jar file or under a directory that is part of the classpath. That is not the case here.
Move the res directory to the src directory: the file will then be in an Eclipse source directory, and Eclipse will "compile" it by simply copying the file to its bin/classes/whatever destination directory, which is in the classpath when running the application.

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

Jar cannot find the path to the file inside

In my Maven project I have a properties file that has a property for a location of keystore file file=filename.p12 (I think the file type doesn't really matter now).
The problem I have that when i built it with maven, I see that the file is inside the root of jar and when i run java -jar the-jar-file.jar I get the IO exception that the filename.p12 is not found.
Everything runs fine in Eclipse, it finds the file and the application runs. Not to confuse somebody, I keep a copy of that filename.p12 as well in src/main/resources folder so that the paths are resolved running in Eclipse and standalone. But this is going to be my other question.
What I can't do is to get the filename.p12 as a resource, because I have external jar that gets as argument my properties file and then handles that properties file itself where the row file=filename.p12 is. Why is the file not found inside the jar, even though I see it's there? My other property files that I have open with Spring's ClassPathResource run just fine.
In order to access internal/embedded resources you need to use Class#getResource or Class#getResourceAsStream depending on your needs

Java NoClassDefFoundError even when Jars in same folder

I have created a simple Java program (1 java file that contains the main() ), and I've included all Jar files in the same directory as the .class file. It is giving the NoClassDefFoundError message.
I've tried updating the Classpath to point to the directory, and I've also set "-cp ." to suggest that it look in the same directory as the .class file. However, the program still says it can't find the class def.
Any thoughts on what I should do?
Adding a folder tells java to look in that folder for .class files.
You can't reference .jar files via a folder name... Each .jar file's path must be listed on the CLASS_PATH explicitly.
this question's answer may be useful
When you try running a class from command line then a NoClassDefFound exception usualy means there is something wrong with your classpath.
You have explicitly define the classpath. You can do this in a few ways but the following way is the least prone to error:
Open a command shell and do the following:
1.) set classpath = {path to class files};{path to jars}
2.) java com.example.mainclass
Note: Even if your classes path and jar path is the same you need to specify them explicitly.
Note: If you have more then one jars place them in a folder say lib and add it to the classpath like: {path}/lib/* This will include all of the jar otherwise you have to specify them individually.
References: https://javarevisited.blogspot.com/2011/01/how-classpath-work-in-java.html
Import the following package:
Import java.lang.NoClassDefFoundError;

Problem with resources location difference in eclipse and JARs

I wrote a program that is based completely on a single text file: I read the file, store the information, then search the information, etc. So, for the program to work, the file just has to be present and detectable by the program.
I use eclipse, so I put the file is in the default resources map (src/main/resources). At the start of my program I create the file:
private static File textFile = new File("src/main/resources/TEXT.TXT")
However, when I try to package my program using Maven, I get a JAR in which all class and resources files are present in the same folder; my program stops working since it cannot find the file anymore.
Any help on how to deal with this problem? I`d prefer a situation in which my program works in eclipse and as a JAR, but as a JAR only would be alright as well.
You can use ClassLoader.getResourceAsStream to load it from the classpath (or getResource to get the URL of the file).
Thread.currentThread().getContextClassLoader().getResource("TEXT.TXT")
This works as long as src/main/resources is on the classpath in eclipse. (The maven eclipse plugin includes it by default.) The file has to be in the jar file to work outside of eclipse.
Nice suggestions, this works perfect in eclipse itself: the correct location of the file is returned and I can use the file to do whatever I like.
When opening the program as a jar, there is still a problem. The getResource method returns a location that looks like the right one:
/something/something/something/something/workspace/program/target/program-0.0.1.jar!/TEXT.TXT.
However, when I convert this url to a string, use that string to create a file object and use this file object in my program, I get the following error:
java.io.FileNotFoundException: file:/something/something/something/something/workspace/program/target/program-0.0.1.jar!/TEXT.TXT (No such file or directory)
So, the getResource method does find the file, but the program somehow can't use it..

Categories