Gradle, SpringBoot, Mybatis 사용시, gradle build 후 실행하면 mapper xml 을 못찾는 현상

개발환경

intellJ 에서 기본 build 를 gradle 로 위임해서 사용한다.

├── build
├── src
│ ├── main
│ │ ├── java
│ │ │ └── app
│ │ │  ├── controller .. controllers
│ │ │  ├── mapper .. mapper interface
│ │ │  └── MainApp .. spring boot application
│ │ └ resources
│ │   ├── app
│ │   │ └── mapper .. mapper xml
│ │   ├ application.yaml
│ │   └ logback-spring.xml
│ └── test
│   └── gradle-wrapper.properties
├── gradlew
└── gradlew.bat
...

사용 플러그인

plugins {
    id 'org.springframework.boot' version '2.2.6.RELEASE'
    id 'io.spring.dependency-management' version '1.0.8.RELEASE'
    id 'java'
}

mybatis mapper xml 을 찾지 못함.

spring boot plugin 의 bootJar 로 jar 를 실행하면 괜찮은데, 그냥 빌드하고 실행하면, mapper 를 찾지 못한다는 오류가 난다.

org.apache.ibatis.binding.BindingException: Invalid bound statement

그래서 build 된 항목을 살펴 보았더니

├── build
│ ├── classes
│ ├── libs
│ ├── resources
│ └── tmp
...

첫시도 - sourceSets 수정

요렇게 구성이 되어있었고, mapper xml 은 resources 에 들어가 있었다. classpath 에 xml 이 들어가 있는 jar 는 문제가 없고, classpath 에 xml 이 없기 때문에 resources 를 불러오지 못한다고 생각하여 아래와 같이 build.gradle 을 수정해서 해결이 되긴했는데..

sourceSets {
    main {
      output.resourcesDir = output.classesDir
    }
}

해결한 다음 글을 쓰려고 sourceSets 을 원복시키고 실행했더니, 이젠 application.yaml 도 못찾는 것 같았다.. 안그래도 어떻게 가져가고있는지 궁금했는데.. 이상하다………..

저러면 bootJar task 로 나온 jar 파일 속에 리소스 파일이 두개씩생기네 하하

두번째 시도 - Copy Task 사용

task localBuild {
    println 'localBuild'
    doLast {
        println "localBuild.doLast -> project.projectDir -> " + project.projectDir
        copy {
            println 'localBuild.doLast.copy ' + '$buildDir/resources -> $buildDir/classes/java'
            from "$buildDir/resources"
            into "$buildDir/classes/java"
        }
    }
}
//bootJar 는 assemble 을 하지 않는다. local build 일 경우에만 resources 를 복사하도록 한다.
assemble.dependsOn "localBuild"

$buildDir/resources 의 모든 파일을 $buildDir/classes/java 로 복사해주는 localBuild Task 를 정의했다.

그리고 bootJar task 에서는 동작하지 않도록 assemble task 에 의존성을 주었다.

이렇게하면.. build 를 수행하는 로컬환경에서만 리소스들이 복사되어 들어가게 된다. CI 환경에서는 bootJar 를 수행하니 상관없다.

그런데 아무리 생각해도 그냥 빌드했을때, 프로퍼티 파일도 못읽는건 영 이해가 안된다..