Search code examples
javaspring-bootclasspathfilenotfoundexception

FileNotFoundException exception when reading from a HTML resource


I try to open and read an HTML file from within class path.

Please find the directory structure in screenshot below

enter image description here

Inside class SendEmail class I want to read that verification.html file.

Code

When using the code below, it is throwing me a java.io.FileNotFoundException exception here:

emailContent = readHTMLFile("../emailTemplate/EmailVerificationTemplate/verification.html");

The readHTMLFile method looks like this:

public String readHTMLFile(String path) throws IOException {
    String emailContent = "";
    StringBuilder stringBuilder = new StringBuilder();
    BufferedReader bufferedReader = new BufferedReader(new FileReader(path));
    while ((emailContent = bufferedReader.readLine()) != null) {
        stringBuilder.append(emailContent);
    }
    return stringBuilder.toString();
}

However, when I use an absolute path everything is working fine.

I am very new to Java world. Please help me to fix this 🙏🏻.


Solution

    1. verification.html looks rather like a "class path resource" than a file... (A file is very environment dependent (e.g. thinking of its path/location), whereas a "CPR" we package & supply with our application & can refer to it with a known&fixed (absolute or relative) (class path) address.

    2. Nor nor (by default) "includes" anything else from src/main/java than *.java files. So please move the according files (including structure/packages) to src/main/resources (or src/test/... accordingly).

    3. When the resource is finally in classpath, since spring:3.2.2, we can do that:

      String emailBody = org.springframework.util.StreamUtils.
        copyToString(
           new org.springframework.core.io.ClassPathResource(
      "/full/package/of/emailTemplate/EmailVerificationTemplate/verification.html")
           .getInputStream(), 
           /* you must know(!), better: */
           Charset.forName("UTF-8")
      );
      

      (..also outside/before spring-boot-application.)

      In spring context, the Resource (Classpath-, ServletContext-, File(!)-, URL-, ...) can also be "injected", like:

      @Value("classpath:/full/package/...")Resource verificationEmailBody
      

      ..instead of calling the constructor.

    See also:


    When you need to refer to verification.html as a File, then please ensure: It has a distinct (absolute (ok!) or relative (good luck!)) address (in all target environments)!