3

I have a maven project with typical project structure. At the base of the project, I have a directory names res that has some resources (> 500 MB). I am trying to use

this.class().getClassLoader().getResourceAsStream("res/xxx")

this code fragment to read from that folder, but it returns a null resource stream. I have a few workarounds below, but none of these are acceptable due to reasons explained below.

  1. I can move the folder to {base}/target/classes, and it will be read, but it will also get cleaned when I do a mvn clean. Hence, this approach doesn't work. For some reason, specifying the path as ../../res/xxx also doesn't work.
  2. I can move the folder to {base}/src/resources, but then it will get copied to target/classes and the jar. Hence this is also not acceptable.
  3. Though I am open to trying some other java APIs, I may have to use the class loader mechanism only as there is some external library component that is also trying to access the res folder using the similar approach.

Is there some way I can read the res folder from projects base directory? Is there some setting in pom.xml file that can help me with that?

patentfox
  • 1,436
  • 2
  • 13
  • 28
  • 1
    Looks to me like option 2) is exactly what you want - because you want to read the ressources from the jar, don't you? – Ingo Nov 21 '13 at 10:38
  • 1
    2) is the maven way to go; if you want to avoid the overhead of copying the resources every time, make them into an own maven artifact! – Gyro Gearless Nov 21 '13 at 10:41
  • Gyro, I am relatively new to java and especially maven. Can you let me know where I can find instructions for making the resources into an artifact? Thanks! – patentfox Nov 21 '13 at 10:42
  • @kaustubh That is outlined in the first section of my answer below. – jwa Nov 21 '13 at 11:11

2 Answers2

5

Use this.class().getClassLoader().getResourceAsStream("/res/xxx") and then you will be reading from the root of the classpath irrespective of the actual file/folder location in windows or Linux. This is actually one of the safest ways to read files especially when you do not know how your application will eventually be deployed.

It means though that your classpath must include the parent of res and that res/ must be copied over when you deploy your app

Otherwise, if you want to use relative paths, try this snippet (taken from this SO answer):

String filePath = new File("").getAbsolutePath();
filePath.concat("path to the property file");
Community
  • 1
  • 1
David Brossard
  • 13,584
  • 6
  • 55
  • 88
1

If you use this.class().getClassLoader().getResourceAsStream("/res/xxx"), it is going to try to load resources from the classpath. If that's not want you want to do, you're going to need to specify an absolute path.


Resource on Classpath

If you don't want the resource built into your JAR, I'd suggest having a different maven project with the file in it, under the src/main/resources directory. This will create a jar file with the file in it, which will be ~500MB.

After this, you can include a dependency on this project in your project containing your application code. This will then be able to reference it from the jar file using getResourceAsStream(...).

If you don't want this large jar file to ship with your application, make sure you mark the dependency with <scope>provided</scope>.


File from Absolute Path

You will need to take the file location as a parameter in your main method, and then use new File("C:\\path\\to\\your\\file.txt") and then use a FileReader to read it in.

jwa
  • 3,239
  • 2
  • 23
  • 54
  • Thanks! I will use the src/main/resources/ folder for now. Good to know that there is another way using dependent maven project(s). I will revisit this later as soon as I can. – patentfox Nov 21 '13 at 11:39