0

I am building a springboot project with thymeleaf. The project runs as expected when running from within eclipse. i.e I am able to access model attributes in thymeleaf.

However, when I package the above project as a jar, thymeleaf is unable to access model attributes added on the backend.

1) Java code on the backend:

@RequestMapping("/")
public String index(Model model) throws Exception {

    String headshotsfileNameStrings = "";
    InputStream resource = new ClassPathResource("static/images/xyz-headshots/").getInputStream();
    try (BufferedReader reader = new BufferedReader(new InputStreamReader(resource))) {
         headshotsfileNameStrings = reader.lines().collect(Collectors.joining(","));
    }

    model.addAttribute("headshotsfileNameStrings", headshotsfileNameStrings);
    System.out.println(model);
    return "index";
}

EDIT 1: I updated above code to:

    try (BufferedReader reader = new BufferedReader(new InputStreamReader(resource))) {

System.out.println(reader.readLine()); //This prints 'null' when running application as a Jar 

         headshotsfileNameStrings = reader.lines().collect(Collectors.joining(","));
    }

2) Thymeleaf frontend code

<script>
        var headshotsfileNameStrings = "[[${headshotsfileNameStrings}]]";
    </script>

The variable 'headshotsfileNameStrings' has value "" when the application is run as a springboot jar and has value "some_string_here_xyz" when the application is run from Eclipse.

What could be going on here? I don't see any errors and I don't know where to start debugging this from. Any ideas?

Nikhil
  • 1,279
  • 2
  • 23
  • 43

2 Answers2

0

My first check would be if the file is indeed found, you can put a debug point and see if your resource value indeed holds the file that you expect.

Also, add a catch clause and print the stacktrace instead of using throws Exception, right now if something goes wrong in this method it does so silently.

What I believe happens at the moment, is that you have an IOException file not found, but you cannot see it because you do not print the stacktrace.

UPDATE:

I expect that 'xyz-headshots' is a filename. If that is the case, add the file extension and remove the trailing "/". So if it is a text file for example it should look like this static/images/xyz-headshots.txt

Dimitris
  • 560
  • 3
  • 17
  • Please see 'EDIT 1' above. I tried what you asked me to try on my machine and no exception was thrown. However, if you see 'EDIT 1' above, it seems that the resource "InputStream resource = new ClassPathResource("static/images/xyz-headshots/").getInputStream();" is not getting found. Any idea, how to proceed? – Nikhil Mar 13 '19 at 14:31
  • I was correct then, for some reason the file is not getting found. Try to put the file directly under your resource folder, so you don't have to specify the path, sometimes I have run into weird problems regarding the slashes. Then once you have a working case you can work on it to move it in the directory that you want. Also, what is your resource? Right now it seems like you pass a whole folder. – Dimitris Mar 13 '19 at 14:34
  • 'xyz-headshots' is a folder. I want to get the filenames present in that folder. The folder is actually getting found by java code. When I change 'xyz-headshots' to '#@$-headshots', I get a ---> java.io.FileNotFoundException: class path resource [static/images/#@$-headshots/] cannot be opened because it does not exist So, the problem seems to be something different. Something related to how a folder is accessed inside JAR. – Nikhil Mar 13 '19 at 15:28
0

This code worked for me in the IDE as well as when the application was run as a JAR:

@RequestMapping("/")
    public String index(Model model) {
        String headshotsfileNameStrings = "";
        ResourceLoader resourceLoader = new DefaultResourceLoader();
        Resource[] resources;
        try {
            resources = ResourcePatternUtils.getResourcePatternResolver(resourceLoader)
                    .getResources("classpath:" + "/static/images/xyz-headshots/*.jpg"); //get all files in the directory
            for (int i = 0; i < resources.length; i++) {
                String fileName = resources[i].getFilename(); //fileName gets populated now.
                headshotsfileNameStrings += fileName + ",";
            }


        } catch (Exception e) {
            e.printStackTrace();
        }

        model.addAttribute("headshotsfileNameStrings", headshotsfileNameStrings);
        return "index";
    }

I took help from the answers listed here: Classpath resource not found when running as jar

Nikhil
  • 1,279
  • 2
  • 23
  • 43