Spring Boot 를 이용해 간단한 데모 서버를 만들어야 하는 일이 생겼다.
DB 는 Liquibase 를 이용해 migration 하려고 하였으나, 쌩뚱맞은 에러가 발생하였다.
해당 과정은 다음과 같다.
참고로, liquibase 를 적용시키기 위해 다음의 사이트를 참고하였다.
https://www.baeldung.com/liquibase-refactor-schema-of-java-app
(공식 문서가 당연히 좋겠지만, 언제나 보기 편하고 좋은 걸 봤던 나에게는 상당히 힘들다… 안되면 공식문서를 뒤적거려야겠지…)
가장 먼저 build.gradle.kts 에 dependency 를 주입하였다.
implementation("org.liquibase:liquibase-core")
그 후,
resources 폴더에 다음과 같이 changelog-master.xml 파일을 설정하였다.
<?xml version="1.0" encoding="UTF-8"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-latest.xsd">
<include file="db/changelog/db.changelog-1.0.xml"/>
</databaseChangeLog>
“db/changelog/db.changelog-1.0.xml” 파일은 liquibase 의 xml 문법에 맞춰 이상없이 작성하였으나,
여기서 다음과 같은 에러가 발생한다.
ERROR: liquibase.secureParsing is set to 'true' which does not allow remote lookups. Set it to 'false' to allow remote lookups of xsd files.
secureParsing 이 true 라서 xsd 파일의 remote lookup 이 불가능하다고 나온다.
해결법은 단순하게 application.yaml 에 liquibase.secureParsing = false 를 추가하면 된다고 나온다.
하지만 application.yaml 에 liquibase.secureParsing = false 를 추가하여도, 오류는 여전히 발생한다.
그렇다면 조금 더 직관적으로, remote lookup 이 안되는거니 직접 xsd 파일을 로컬에 추가해버리면 어떨까.
changelog-master.xml 파일의 “xsi:schemaLocation” 설정 부분을 다음과 같이 바꿨다.
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog classpath:src/main/db/changelog/dbchangelog-latest.xsd">
이 “http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-latest.xsd” 링크에 접속하여 xsd 파일을 직접 다운로드 후, src/main/db/changelog/dbchangelog-latest.xsd 의 경로에 복사해두었다.
그러나 슬프게도, 에러의 종류만 바뀌었을 뿐 결과는 NO 였다.
새롭게 나온 에러는 다음과 같았다.
schema_reference: accessExternalSchema 속성으로 설정된 제한으로 인해 'classpath' 액세스가 허용되지 않으므로 스키마 문서 'dbchangelog-latest.xsd' 읽기를 실패했습니다.
여전히 외부 파일은 읽을 수 없다고 나온다.
결국, liquibase 의 깃헙에서 선례가 없나 찾기로 하였다.
그리고 정말 고맙게도, 명확한 원인은 적혀있지 않지만 답을 찾을 수 있었다.
liquibase 의 github 에도 똑같은 증상을 호소하는 이슈(https://github.com/liquibase/liquibase/issues/3120)가 존재하여 확인하였더니, 결국엔 버전문제인 듯 하다.
schemaLocation 링크에는 latest 를 배척하고, 직접 버전을 기입하도록 하자..
<?xml version="1.0" encoding="UTF-8"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.9.xsd">
<include file="db/changelog/db.changelog-1.0.xml"/>
</databaseChangeLog>
슬프지만 어쩔 수 없다…
INFO 23764 --- [ main] liquibase.changelog :
ChangeSet db/changelog/db.changelog-1.0.xml::1::test ran successfully in 473ms
참고로 실행 로그는 맛있기 그지없었다.