본문 바로가기
Back/Spring Boot

[Spring Boot] .jar 배포 후 resources 파일 경로 찾기

by 은z 2022. 6. 10.

문제 상황

진행하고 있는 프로젝트 개발 서버에 jar 파일로 말아 배포시켰다.

그런데 한 메소드에서 해당 파일 경로를 읽어오지 못하는 문제가 발생했다.

분명 local에서는 문제없이 잘 읽어 오는데, 배포한 jar파일에서는 파일을 찾지 못하는 에러가 계속 났다.

 

아래는 로컬에서 잘 돌아가는 기존 소스 

URL resource = getClass().getClassLoader().getResource("templates/fo/ko/utility/terms");
File dir = new File(resource != null ? resource.getPath() : null);

String[] filenames = dir.list(); // 하위 파일들의 이름을 배열에 담는다.

 

 

원인

보통 IDE등에서 개발하고 빌드하게 되면 파일 경로로 잘 접근하는데, jar로 배포하면 기존 파일 접근 코드로는 문제가 생긴다.

왜냐하면 유효하지 않은 경로가 되어버리게 때문이다.

jar 파일은 루트 경로를 참고해보면 jar:file:/ 로 시작하는 경로값을 가진다.

로컬에서는 실제 resource 파일인 file:/ 로 해당 경로를 찾는다.

//IDE에서 접근할 때
file:/~/파일명

//jar파일에서 접근할 때
file:/......./배포된jar.jar!/....../파일명
//또는 요렇게 보일 수도 있음
jar:file:/....../파일명

위와 같이 jar파일에서 경로를 찾으면 파일 경로에 !가 포함되게 된다.

그래서 로컬에서 되던 기존 파일을 사용하면 NPE나 FileNotFoundException이 발생하게 된다.

 

 

 

해결 방법을 찾던 중 이슈

내 경우에는 어떤 디렉토리 안에 있는 여러개의 파일을 찾아야하는 상황이었다.

파일을 읽어올 필요 없이 그 경로 안에 어떤 파일들이 있는지! 그 파일들의 각각의 이름은 무엇인지!

이걸 알아내야 하는데,

내가 구글링 해본 결과는 파일을 읽고 스트림으로 파일 내용을 가져오는 방법이 대부분....

특히 ClassPathResource 메소드를 사용하는 방법이 대부분이었다.

 

**참고로 ClassPathResource 이용해서 파일 경로를 찾고 그 파일을 스트림으로 읽어오는 코드는 아래에!

static String htmlFileReader(String pathStr){

    ClassPathResource resource = new ClassPathResource(pathStr);
    String resultcontent = "";
    try {
        InputStream inputStream = resource.getInputStream();
        BufferedReader br = new BufferedReader(new InputStreamReader(inputStream, "utf-8"));

        StringBuilder builder = new StringBuilder();
        while (true) {
            String line = br.readLine();
            if(line == null ) break;
            builder.append(line);
        }

        resultcontent = builder.toString();

    } catch (IOException e) {

    }
    return resultcontent;
}

 

해결 

아래 방법으로 하면 local과 개발환경(jar) 둘 다 모두 잘 돌아간다.

스프링에서는 여러가지 형태로 저장된 리소스를 패턴으로만 찾아서 가져올 수 있도록 도구를 제공한다.

Resource[] resources = ResourcePatternUtils
    .getResourcePatternResolver(new DefaultResourceLoader())
    .getResources("classpath*:msg/**");

 

댓글