Grails
  1. Grails
  2. GRAILS-6542

Improve access and documentation of static resources

    Details

    • Type: Improvement Improvement
    • Status: Open
    • Priority: Major Major
    • Resolution: Unresolved
    • Affects Version/s: None
    • Fix Version/s: 3.0
    • Component/s: None
    • Labels:
      None

      Description

      There seems to be a lot of confusion on how to go about access static resources within various classes in a grails application. Searching the net for topics such as 'grails classpath resource' or 'grails getResource' reveals some of the issues (see the many references below). It is a frequent topic on the grails-user mailing list.

      There does not seem to be good documentation on the classpath within the grails user guide.

      There are various ways of accessing files, all seem to have various pros and cons and it would be nice to have the grails authors/designers make some decisions on the right 'grails-way' of doing this.

      This requirement does NOT refer to web-accessible static resources, this is referring to data files uses for other purposes such as watermark files when dynamically serving images, templates used to create emails, etc.

      After reading lots of posts the main requirement seems to be that static resources must be available using the same code using any of the following grails goals: test-app, run-app, run-war and that is must be documented in the grails user guide.

      Additionally people need to be able to have 'test-app'-only resources that are not packaged into a war file.

      People, myself included, like to have separate 'resource' folders for resources, see the maven standard directory layout - http://maven.apache.org/guides/introduction/introduction-to-the-standard-directory-layout.html

      Ideally, something like the snippet below should work from within at least bootstrap.groovy and any controller class, service class, unit test and integration test. An IDE JUnit test-runner should also be able to be configured so that it works too.

      import java.net.URL
      URL url = ???.getResource("emailTemplates/someTemplate.txt")
      

      ??? should be documented for each of the cases above, if 'this.class.getResource()' is not sufficient

      There should be some documented scheme for placing resource files within the grails app file structure, suggestions as follows:

      /
       test/
            resources/
                      myTestOnlyResource.txt
       grails-app/
                 resources/
                           myAccessableFromEverywhereResource.txt
      

      Given the example snippet above, the relative path to the root of the grails project for the resource file would be:

      /grails-app/resources/emailTemplates/someTemplate.txt
      

      A class specific resource for the class com.example.SomeService could be stored at:

      /grails-app/resources/com/example/someservice/someResource.txt
      

      Accessible in code via something like:

      package com.example
      
      class SomeService {
          void doStuff() {
              URL url = getResource("com/example/someservice/someResource.txt")
              String content = new File(url).text
          }
      }
      

      References:

      http://grails.1312388.n4.nabble.com/How-should-I-load-a-file-from-the-classpath-td2271990.html
      http://grails.1312388.n4.nabble.com/How-get-file-resource-during-running-unit-tests-td1388466.html
      http://grails.1312388.n4.nabble.com/Load-static-classpath-resources-td1381606.html
      http://grails.1312388.n4.nabble.com/Accessing-getResource-from-a-Service-td1375969.html#a1375969
      http://grails.1312388.n4.nabble.com/getResource-different-at-test-time-td1333947.html#a1333947
      http://grails.1312388.n4.nabble.com/How-to-check-if-a-resource-file-like-an-image-exists-at-run-time-td1367846.html
      http://grails.1312388.n4.nabble.com/Where-should-resource-files-live-td1387762.html#a1387762
      http://grails.1312388.n4.nabble.com/grails-app-conf-content-not-copied-to-WEB-INF-classes-td1349963.html
      http://grails.1312388.n4.nabble.com/The-grails-way-to-get-to-external-files-td2262058.html
      http://grails.1312388.n4.nabble.com/reading-a-file-in-WEB-INF-td1332214.html
      http://grails.1312388.n4.nabble.com/accessing-resources-JasperReport-jasper-file-td1346326.html
      http://grails.1312388.n4.nabble.com/Including-Accessing-Internally-Used-Resources-td1351537.html
      http://jira.codehaus.org/browse/GRAILS-4048
      http://jira.codehaus.org/browse/GRAILS-4646
      http://www.grails.org/Sending+SMTP+Authenticated+Email,+Html+content+with+GroovyTemplates+and+Spring+integration (see variable tplFile)

        Activity

        Hide
        Ronny Løvtangen added a comment -

        Moving a project from a maven based layout to Grails, I also found myself wondering where to put resources.
        My first take was to put them in src/groovy, but that didn't work.
        However, files under src/java are copied to classpath (WEB-INF/classes) as expected.
        Seems strange to me that there is a difference here between src/groovy and src/java.

        I also was made aware by the user mailing list that files under grails-app/conf are copied to classpath. This came as a surprise to me, as I had already found out that grails-app/spring/resources.xml was copied to WEB-INF/spring/resources.xml, and not to WEB-INF/classes/spring/resources.xml. But I guess I was tricked by this special case, as this seems to be the only file from grails-app/conf that is not copied to WEB-INF/classes.

        For tests, resources under test/unit is available in classpath.
        Having a test/resources folder similar to maven would be nice I think.

        Also, a src/resources or grails-app/resources would be nice, even though grails-app/conf does the same thing. Being able to separate configuration from other resources is a good thing.
        Maybe the location of resource folders could be configured with a property in Config.groovy

        I didn't find anything in the official documentation about where to put resources, so the documentation needs an update to.

        Show
        Ronny Løvtangen added a comment - Moving a project from a maven based layout to Grails, I also found myself wondering where to put resources. My first take was to put them in src/groovy, but that didn't work. However, files under src/java are copied to classpath (WEB-INF/classes) as expected. Seems strange to me that there is a difference here between src/groovy and src/java. I also was made aware by the user mailing list that files under grails-app/conf are copied to classpath. This came as a surprise to me, as I had already found out that grails-app/spring/resources.xml was copied to WEB-INF/spring/resources.xml, and not to WEB-INF/classes/spring/resources.xml. But I guess I was tricked by this special case, as this seems to be the only file from grails-app/conf that is not copied to WEB-INF/classes. For tests, resources under test/unit is available in classpath. Having a test/resources folder similar to maven would be nice I think. Also, a src/resources or grails-app/resources would be nice, even though grails-app/conf does the same thing. Being able to separate configuration from other resources is a good thing. Maybe the location of resource folders could be configured with a property in Config.groovy I didn't find anything in the official documentation about where to put resources, so the documentation needs an update to.

          People

          • Assignee:
            Unassigned
            Reporter:
            Dominic Clifton
          • Votes:
            8 Vote for this issue
            Watchers:
            6 Start watching this issue

            Dates

            • Created:
              Updated:
              Last Reviewed:

              Development