-1

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

  1. Is there a setting option for default resource folder that I need to set?
  2. Is src/main/resources the conventional place to store files like this?
  3. 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?

jumps4fun
  • 3,994
  • 10
  • 50
  • 96

1 Answers1

0

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

Community
  • 1
  • 1
Breandán Dalton
  • 1,619
  • 15
  • 24
  • AS far as I know, everything that goes into the target folder is compiled code, right? So I should not manually add something to the target-folder, or? I get that the file might be somewhere else, when I compile and run the code, compared to where it is in my developing environment, but as I stated in my question, I am not looking for more possible options, I am looking for the conventional standard solution to my problem. So I might want to adjust the manifest file, If that is the standard way of doing it. Is it? – jumps4fun Nov 07 '14 at 12:51
  • The target folder, in my view, is where you put stuff that you want to end up on the target system (in this case, your jar file), so I would not hesitate to create a target/resources directory for this purpose. However, 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 – Breandán Dalton Nov 07 '14 at 13:02
  • ...as a side note, I can see now that my configuration.xml-file actually IS transferred automatically to target/classes. Only it doesn't show in eclipse. Apparently the system really finds the file, but somehow it doesn't read it... I'll investigate further... So far I have not manually put anything in my target. The jar is generated, and placed into that folder, when maven executes it's compile action. – jumps4fun Nov 07 '14 at 13:07
  • I updated my answer to include the meat of my previous comment – Breandán Dalton Nov 07 '14 at 13:07
  • My original solution in the question actually works, apart from a single thing: The file path includes a single folder with a whitespace character, which is replaced by `%20`. I manually formatted them back to whitespaces, and voilla! But it can't be that this is the intended way to do it??? – jumps4fun Nov 07 '14 at 13:16
  • Maven sorts out everything in the src/main/resources folder, and therefor by inharitance, the META-INF folder. Adding META-INF might be correct, but I also had to change my "configuration.xml" to "META-INF/configuration.xml", and it still would not work... – jumps4fun Nov 07 '14 at 13:25
  • If your test.xml file contains properties, you could try `Properties testProperties=new Properties();testProperties.loadFromXML(this.getClass().getResourceAsStream("/test.xml"));` That loads it using`this`'s classloader – Breandán Dalton Nov 07 '14 at 13:30
  • Thanks for trying, but `this` will never work in a static method in an abstract class... I really appreciate you trying, but it seems like you, like me, mostly experiment with solutions, and actually do not know the answer to this problem. I really do appreciate the effort, but the continuous guessing is starting to clutter up the thread, making it harder for both me and possible other users to find relevant correct information. – jumps4fun Nov 07 '14 at 13:40