Class#getClassLoader의 거동이 IDE에서 실행되는 경우와 jar를 실행한 경우에 바뀐다

개요



jar로 실행하면 아래와 같은 슬래시가 2개 겹치는 경우에 자원을 찾을 수 없다.
            InputStream resource1 = this.getClass().getClassLoader().getResourceAsStream("test//hello.txt");

프로젝트 구성





샘플 코드


package work.inabajun;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

public class Main {

    public static void main(String[] args) throws IOException {
        new Test().getHelloText();
    }

    private static class Test {

        public void getHelloText() throws IOException {
            // スラッシュが1つ
            InputStream resource1 = this.getClass().getClassLoader().getResourceAsStream("test/hello.txt");
            if( resource1 != null) {
                BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(resource1));
                System.out.println("Resource1:" + bufferedReader.readLine());
            } else {
                System.out.println("Resource1 is null.");
            }

            // スラッシュが2つ
            InputStream resource2 = this.getClass().getClassLoader().getResourceAsStream("test//hello.txt");
            if( resource2 != null) {
                BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(resource2));
                System.out.println("Resource2:" + bufferedReader.readLine());
            } else {
                System.out.println("Resource2 is null.");
            }
        }
    }
}

시작



Intellij IDEA로 시작


$ java "-javaagent:/Applications/IntelliJ IDEA CE.app/Contents/lib/idea_rt.jar=60858:/Applications/IntelliJ IDEA CE.app/Contents/bin" -Dfile.encoding=UTF-8  -classpath /Users/inabajunmr/test/untitled/out/production/untitled work.inabajun.Main
objc[7462]: Class JavaLaunchHelper is implemented in both /Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/bin/java (0x1023c94c0) and /Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/jre/lib/libinstrument.dylib (0x103bf04e0). One of the two will be used. Which one is undefined.
Resource1:abcde12345
Resource2:abcde12345

Resource1,2 함께 취득할 수 있다.

실행 가능 jar를 만들고 시작


$ java -jar untitled_jar/untitled.jar 
Resource1:abcde12345
Resource2 is null.

Resource2가 null가 된다.

Spring Boot + Thymeleaf에서 템플릿을 찾을 수 없다고 말했습니다.



Spring Boot + Thymeleaf에서 다음과 같은 코드를 작성하면 Gradle 또는 IDE에서 시작할 때 보통으로 움직였는데
    @GetMapping("/list.html")
    public String viewInput(final Model model) {
        return "/resource/list";
    }

환경에 배포하면 템플릿이 없다고 말하고 화가났다.
2018-03-21 11:58:56.840 ERROR 26381 --- [nio-8080-exec-8] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.thymeleaf.exceptions.TemplateInputException: Error resolving template "/resource/list", template might not exist or might not be accessible by any of the configured Template Resolvers] with root cause

org.thymeleaf.exceptions.TemplateInputException: Error resolving template "/resource/list", template might not exist or might not be accessible by any of the configured Template Resolvers
    at org.thymeleaf.engine.TemplateManager.resolveTemplate(TemplateManager.java:870)
    at org.thymeleaf.engine.TemplateManager.parseAndProcess(TemplateManager.java:607)
    at org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1098)
    at org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1072)
    at org.thymeleaf.spring5.view.ThymeleafView.renderFragment(ThymeleafView.java:354)

이 거동의 차이입니다.
htps : // 기주 b. 코 m / sp 린 gp 로지 cts / sp 린 g 보오 t / 이스에 s / 1744

제대로 움직인 코드



선두의 슬래시를 지우면 어느 기동 방법에서도 움직였다.
    @GetMapping("/list.html")
    public String viewInput(final Model model) {
        return "resource/list";
    }

좋은 웹페이지 즐겨찾기