22
Play.classloader.getResourceAsStream(filepath); 

filepath - relative to what? project root? playframework root? absolute path?

Or maybe the usage Play.classloader.getResourceAsStream is wrong?

bArmageddon
  • 8,088
  • 6
  • 22
  • 40

5 Answers5

22

In the Play Framework the "conf" directory is on the classpath, so you can put your file there and open it with getResourceAsStream.

For example if you create a file "conf/foo.txt" you can open it using

Play.classloader.getResourceAsStream("foo.txt");
Eamonn O'Brien-Strain
  • 3,352
  • 1
  • 23
  • 33
  • 4
    What if the file isn't a configuration file? – cdmckay Jan 17 '14 at 23:52
  • It does not matter if the file is not a configuration file, you can still put it in the conf directory and access it this way. – Eamonn O'Brien-Strain Jan 23 '14 at 01:11
  • 1
    Sorry, my point was that you should not be putting non-configuration-related files in the conf directory. It's messy and confusing for other developers looking at your code. – cdmckay Jan 23 '14 at 01:24
  • Yes I agree it is not ideal from a readability point of view. To make it a bit more obvious you could create a subdirectory under conf with a name that makes clear what these files are for. And I suppose you could argue that any read-only, non-code files like these, no matter what they are used for, are a kind of "configuration" in the broad sense of that word. – Eamonn O'Brien-Strain Jan 24 '14 at 01:44
  • 2
    I suppose you could, but it still seems a bit dirty to me. I added an alternative in another answer below (using the public folder) but it's not perfect either. I think Play 2 needs to add a folder for private assets/resources that can be accessible in production mode. – cdmckay Jan 24 '14 at 02:13
  • I like the "public" version too. It does seem like a better solution for non config files. I gave your answer a vote! – Eamonn O'Brien-Strain Jan 24 '14 at 04:12
  • Does this work in development mode? I always get file not found. – Roger Oct 30 '14 at 17:16
  • 1
    Not available for Play 2.3 – Pwnstar Jun 13 '18 at 09:01
13

The accepted answer is deprecated in Play 2.5.x as global access to things like a classloader is slowly being phased out. The recommended way to handling this moving forward is to inject a play.api.Environment then using its classLoader to get the InputStream, e.g.

class Controller @Inject()(env: Environment, ...){

  def readFile = Action {  req =>
    ...

    //if the path is bad, this will return null, so best to wrap in an Option
    val inputStream = Option(env.classLoader.getResourceAsStream(path))

    ...
  }
}
josephpconley
  • 1,703
  • 12
  • 12
10

As an alternative to using the conf dir (which should only be used for configuration-related files), you can use the public dir and access it with:

 Play.classloader.getResourceAsStream("public/foo.txt")

Or in Scala with:

 Play.resourceAsStream("public/foo.txt")
cdmckay
  • 31,832
  • 25
  • 83
  • 114
5

Inject Environment and then call environment.resourceAsStream("filename");

Example:

import javax.inject.Inject;

public class ExampleResource extends Controller{

     private final Environment environment;
     
     @Inject
     public ExampleResource(Environment environment){
          this.environment = environment;
     }

     public void readResourceAsStream() {
          InputStream resource = environment.resourceAsStream("filename");
          // Do what you want with the stream here
     }
}

Documentation: https://www.playframework.com/documentation/2.8.0/api/java/play/Environment.html#resourceAsStream-java.lang.String-

danio
  • 8,548
  • 6
  • 47
  • 55
Georgi Georgiev
  • 362
  • 6
  • 9
-2

Relative to the classpath root. That is, your WEB-INF/classes + all the jars in WEB-INF/lib

Bozho
  • 588,226
  • 146
  • 1,060
  • 1,140